Add EnableAutoAnchor to Joint for automatic target anchor setup

This commit is contained in:
Wojtek Figat
2021-11-04 12:17:08 +01:00
parent a45ecf7ec3
commit f303b1c061
2 changed files with 39 additions and 11 deletions

View File

@@ -19,7 +19,6 @@ Joint::Joint(const SpawnParams& params)
, _breakTorque(MAX_float)
, _targetAnchor(Vector3::Zero)
, _targetAnchorRotation(Quaternion::Identity)
, _enableCollision(true)
{
Target.Changed.Bind<Joint, &Joint::OnTargetChanged>(this);
}
@@ -30,7 +29,6 @@ void Joint::SetBreakForce(float value)
return;
_breakForce = value;
if (_joint)
{
_joint->setBreakForce(_breakForce, _breakTorque);
@@ -43,7 +41,6 @@ void Joint::SetBreakTorque(float value)
return;
_breakTorque = value;
if (_joint)
{
_joint->setBreakForce(_breakForce, _breakTorque);
@@ -56,21 +53,29 @@ void Joint::SetEnableCollision(bool value)
return;
_enableCollision = value;
if (_joint)
{
_joint->setConstraintFlag(PxConstraintFlag::eCOLLISION_ENABLED, value);
}
}
bool Joint::GetEnableAutoAnchor() const
{
return _enableAutoAnchor;
}
void Joint::SetEnableAutoAnchor(bool value)
{
_enableAutoAnchor = value;
}
void Joint::SetTargetAnchor(const Vector3& value)
{
if (Vector3::NearEqual(value, _targetAnchor))
return;
_targetAnchor = value;
if (_joint)
if (_joint && !_enableAutoAnchor)
{
_joint->setLocalPose(PxJointActorIndex::eACTOR1, PxTransform(C2P(_targetAnchor), C2P(_targetAnchorRotation)));
}
@@ -82,8 +87,7 @@ void Joint::SetTargetAnchorRotation(const Quaternion& value)
return;
_targetAnchorRotation = value;
if (_joint)
if (_joint && !_enableAutoAnchor)
{
_joint->setLocalPose(PxJointActorIndex::eACTOR1, PxTransform(C2P(_targetAnchor), C2P(_targetAnchorRotation)));
}
@@ -155,6 +159,12 @@ void Joint::Create()
data.Rot0 = _localTransform.Orientation;
data.Pos1 = _targetAnchor;
data.Rot1 = _targetAnchorRotation;
if (_enableAutoAnchor && target)
{
// Place target anchor at the joint location
data.Pos1 = Target->GetTransform().WorldToLocal(GetPosition());
data.Rot1 = WorldToLocal(Target->GetOrientation(), GetOrientation());
}
_joint = CreateJoint(data);
_joint->userData = this;
@@ -206,6 +216,8 @@ Vector3 Joint::GetTargetPosition() const
Vector3 position = _targetAnchor;
if (Target)
{
if (_enableAutoAnchor)
position = Target->GetTransform().WorldToLocal(GetPosition());
position = Target->GetOrientation() * position + Target->GetPosition();
}
return position;
@@ -216,6 +228,8 @@ Quaternion Joint::GetTargetOrientation() const
Quaternion rotation = _targetAnchorRotation;
if (Target)
{
if (_enableAutoAnchor)
rotation = WorldToLocal(Target->GetOrientation(), GetOrientation());
rotation = Target->GetOrientation() * rotation;
}
return rotation;
@@ -259,6 +273,7 @@ void Joint::Serialize(SerializeStream& stream, const void* otherObj)
SERIALIZE_MEMBER(TargetAnchor, _targetAnchor);
SERIALIZE_MEMBER(TargetAnchorRotation, _targetAnchorRotation);
SERIALIZE_MEMBER(EnableCollision, _enableCollision);
SERIALIZE_MEMBER(EnableAutoAnchor, _enableAutoAnchor);
}
void Joint::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier)
@@ -272,6 +287,7 @@ void Joint::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier)
DESERIALIZE_MEMBER(TargetAnchor, _targetAnchor);
DESERIALIZE_MEMBER(TargetAnchorRotation, _targetAnchorRotation);
DESERIALIZE_MEMBER(EnableCollision, _enableCollision);
DESERIALIZE_MEMBER(EnableAutoAnchor, _enableAutoAnchor);
}
void Joint::BeginPlay(SceneBeginData* data)

View File

@@ -26,7 +26,8 @@ protected:
float _breakTorque;
Vector3 _targetAnchor;
Quaternion _targetAnchorRotation;
bool _enableCollision;
bool _enableCollision = true;
bool _enableAutoAnchor = false;
public:
@@ -78,13 +79,24 @@ public:
/// </summary>
API_PROPERTY() void SetEnableCollision(bool value);
/// <summary>
/// Determines whether use automatic target anchor position and rotation based on the joint world-space frame (computed when creating joint).
/// </summary>
API_PROPERTY(Attributes="EditorOrder(39), DefaultValue(false), EditorDisplay(\"Joint\")")
bool GetEnableAutoAnchor() const;
/// <summary>
/// Determines whether use automatic target anchor position and rotation based on the joint world-space frame (computed when creating joint).
/// </summary>
API_PROPERTY() void SetEnableAutoAnchor(bool value);
/// <summary>
/// Gets the target anchor.
/// </summary>
/// <remarks>
/// This is the relative pose which locates the joint frame relative to the target actor.
/// </remarks>
API_PROPERTY(Attributes="EditorOrder(40), DefaultValue(typeof(Vector3), \"0,0,0\"), EditorDisplay(\"Joint\")")
API_PROPERTY(Attributes="EditorOrder(40), DefaultValue(typeof(Vector3), \"0,0,0\"), EditorDisplay(\"Joint\"), VisibleIf(nameof(EnableAutoAnchor), true)")
FORCE_INLINE Vector3 GetTargetAnchor() const
{
return _targetAnchor;
@@ -104,7 +116,7 @@ public:
/// <remarks>
/// This is the relative pose rotation which locates the joint frame relative to the target actor.
/// </remarks>
API_PROPERTY(Attributes="EditorOrder(50), DefaultValue(typeof(Quaternion), \"0,0,0,1\"), EditorDisplay(\"Joint\")")
API_PROPERTY(Attributes="EditorOrder(50), DefaultValue(typeof(Quaternion), \"0,0,0,1\"), EditorDisplay(\"Joint\"), VisibleIf(nameof(EnableAutoAnchor), true)")
FORCE_INLINE Quaternion GetTargetAnchorRotation() const
{
return _targetAnchorRotation;