Refactor Physics to separate PhysicsBackend

#673
This commit is contained in:
Wojtek Figat
2022-01-20 23:28:43 +01:00
parent cf1af53ab8
commit 427846f73b
66 changed files with 4803 additions and 4327 deletions

View File

@@ -3,9 +3,7 @@
#include "D6Joint.h"
#include "Engine/Serialization/JsonTools.h"
#include "Engine/Serialization/Serialization.h"
#include "Engine/Physics/Utilities.h"
#include "Engine/Physics/Physics.h"
#include <ThirdParty/PhysX/extensions/PxD6Joint.h>
#include "Engine/Physics/PhysicsBackend.h"
D6Joint::D6Joint(const SpawnParams& params)
: Joint(params)
@@ -19,185 +17,118 @@ void D6Joint::SetMotion(const D6JointAxis axis, const D6JointMotion value)
{
if (value == GetMotion(axis))
return;
_motion[static_cast<int32>(axis)] = value;
if (_joint)
{
auto joint = static_cast<PxD6Joint*>(_joint);
joint->setMotion(static_cast<PxD6Axis::Enum>(axis), static_cast<PxD6Motion::Enum>(value));
}
PhysicsBackend::SetD6JointMotion(_joint, axis, value);
}
void D6Joint::SetDrive(const D6JointDriveType index, const D6JointDrive& value)
{
if (value == GetDrive(index))
return;
_drive[static_cast<int32>(index)] = value;
if (_joint)
{
auto joint = static_cast<PxD6Joint*>(_joint);
PxD6JointDrive drive;
if (value.Acceleration)
drive.flags = PxD6JointDriveFlag::eACCELERATION;
drive.stiffness = value.Stiffness;
drive.damping = value.Damping;
drive.forceLimit = value.ForceLimit;
ASSERT_LOW_LAYER(drive.isValid());
joint->setDrive(static_cast<PxD6Drive::Enum>(index), drive);
}
PhysicsBackend::SetD6JointDrive(_joint, index, value);
}
void D6Joint::SetLimitLinear(const LimitLinear& value)
{
if (value == _limitLinear)
return;
_limitLinear = value;
if (_joint)
{
auto joint = static_cast<PxD6Joint*>(_joint);
PxJointLinearLimit limit(*Physics::GetTolerancesScale(), Math::Max(value.Extent, ZeroTolerance), value.ContactDist);
limit.stiffness = value.Spring.Stiffness;
limit.damping = value.Spring.Damping;
limit.restitution = value.Restitution;
ASSERT_LOW_LAYER(limit.isValid());
joint->setLinearLimit(limit);
}
PhysicsBackend::SetD6JointLimitLinear(_joint, value);
}
void D6Joint::SetLimitTwist(const LimitAngularRange& value)
{
if (value == _limitTwist)
return;
_limitTwist = value;
if (_joint)
{
auto joint = static_cast<PxD6Joint*>(_joint);
PxJointAngularLimitPair limit(value.Lower * DegreesToRadians, Math::Max(value.Upper, value.Lower) * DegreesToRadians, value.ContactDist);
limit.stiffness = value.Spring.Stiffness;
limit.damping = value.Spring.Damping;
limit.restitution = value.Restitution;
ASSERT_LOW_LAYER(limit.isValid());
joint->setTwistLimit(limit);
}
PhysicsBackend::SetD6JointLimitTwist(_joint, value);
}
void D6Joint::SetLimitSwing(const LimitConeRange& value)
{
if (value == _limitSwing)
return;
_limitSwing = value;
if (_joint)
{
auto joint = static_cast<PxD6Joint*>(_joint);
PxJointLimitCone limit(Math::Clamp(value.YLimitAngle * DegreesToRadians, ZeroTolerance, PI - ZeroTolerance), Math::Clamp(value.ZLimitAngle * DegreesToRadians, ZeroTolerance, PI - ZeroTolerance), value.ContactDist);
limit.stiffness = value.Spring.Stiffness;
limit.damping = value.Spring.Damping;
limit.restitution = value.Restitution;
ASSERT_LOW_LAYER(limit.isValid());
joint->setSwingLimit(limit);
}
PhysicsBackend::SetD6JointLimitSwing(_joint, value);
}
Vector3 D6Joint::GetDrivePosition() const
{
return _joint ? P2C(static_cast<PxD6Joint*>(_joint)->getDrivePosition().p) : Vector3::Zero;
return _joint ? PhysicsBackend::GetD6JointDrivePosition(_joint) : Vector3::Zero;
}
void D6Joint::SetDrivePosition(const Vector3& value)
{
if (_joint)
{
auto joint = static_cast<PxD6Joint*>(_joint);
PxTransform t = joint->getDrivePosition();
t.p = C2P(value);
joint->setDrivePosition(t);
}
PhysicsBackend::SetD6JointDrivePosition(_joint, value);
}
Quaternion D6Joint::GetDriveRotation() const
{
return _joint ? P2C(static_cast<PxD6Joint*>(_joint)->getDrivePosition().q) : Quaternion::Identity;
return _joint ? PhysicsBackend::GetD6JointDriveRotation(_joint) : Quaternion::Identity;
}
void D6Joint::SetDriveRotation(const Quaternion& value)
{
if (_joint)
{
auto joint = static_cast<PxD6Joint*>(_joint);
PxTransform t = joint->getDrivePosition();
t.q = C2P(value);
joint->setDrivePosition(t);
}
PhysicsBackend::SetD6JointDriveRotation(_joint, value);
}
Vector3 D6Joint::GetDriveLinearVelocity() const
{
Vector3 linear = Vector3::Zero, angular;
if (_joint)
{
PxVec3 linear, angular;
static_cast<PxD6Joint*>(_joint)->getDriveVelocity(linear, angular);
return P2C(linear);
}
return Vector3::Zero;
PhysicsBackend::GetD6JointDriveVelocity(_joint, linear, angular);
return linear;
}
void D6Joint::SetDriveLinearVelocity(const Vector3& value)
{
if (_joint)
{
PxVec3 linear, angular;
auto joint = static_cast<PxD6Joint*>(_joint);
joint->getDriveVelocity(linear, angular);
linear = C2P(value);
joint->setDriveVelocity(linear, angular);
Vector3 linear, angular;
PhysicsBackend::GetD6JointDriveVelocity(_joint, linear, angular);
PhysicsBackend::SetD6JointDriveVelocity(_joint, value, angular);
}
}
Vector3 D6Joint::GetDriveAngularVelocity() const
{
Vector3 linear, angular = Vector3::Zero;
if (_joint)
{
PxVec3 linear, angular;
static_cast<PxD6Joint*>(_joint)->getDriveVelocity(linear, angular);
return P2C(angular);
}
return Vector3::Zero;
PhysicsBackend::GetD6JointDriveVelocity(_joint, linear, angular);
return angular;
}
void D6Joint::SetDriveAngularVelocity(const Vector3& value)
{
if (_joint)
{
PxVec3 linear, angular;
auto joint = static_cast<PxD6Joint*>(_joint);
joint->getDriveVelocity(linear, angular);
angular = C2P(value);
joint->setDriveVelocity(linear, angular);
Vector3 linear, angular;
PhysicsBackend::GetD6JointDriveVelocity(_joint, linear, angular);
PhysicsBackend::SetD6JointDriveVelocity(_joint, linear, value);
}
}
float D6Joint::GetCurrentTwist() const
{
return _joint ? static_cast<PxD6Joint*>(_joint)->getTwistAngle() : 0.0f;
return _joint ? PhysicsBackend::GetD6JointTwist(_joint) : 0.0f;
}
float D6Joint::GetCurrentSwingYAngle() const
float D6Joint::GetCurrentSwingY() const
{
return _joint ? static_cast<PxD6Joint*>(_joint)->getSwingYAngle() : 0.0f;
return _joint ? PhysicsBackend::GetD6JointSwingY(_joint) : 0.0f;
}
float D6Joint::GetCurrentSwingZAngle() const
float D6Joint::GetCurrentSwingZ() const
{
return _joint ? static_cast<PxD6Joint*>(_joint)->getSwingZAngle() : 0.0f;
return _joint ? PhysicsBackend::GetD6JointSwingZ(_joint) : 0.0f;
}
#if USE_EDITOR
@@ -412,59 +343,15 @@ void D6Joint::Deserialize(DeserializeStream& stream, ISerializeModifier* modifie
JsonTools::GetFloat(_limitSwing.Spring.Damping, stream, "LimitSwing.Damping");
}
PxJoint* D6Joint::CreateJoint(JointData& data)
void* D6Joint::CreateJoint(const PhysicsJointDesc& desc)
{
const PxTransform trans0(C2P(data.Pos0), C2P(data.Rot0));
const PxTransform trans1(C2P(data.Pos1), C2P(data.Rot1));
auto joint = PxD6JointCreate(*data.Physics, data.Actor0, trans0, data.Actor1, trans1);
void* joint = PhysicsBackend::CreateD6Joint(desc);
for (int32 i = 0; i < static_cast<int32>(D6JointAxis::MAX); i++)
{
joint->setMotion(static_cast<PxD6Axis::Enum>(i), static_cast<PxD6Motion::Enum>(_motion[i]));
}
PhysicsBackend::SetD6JointMotion(joint, (D6JointAxis)i, _motion[i]);
for (int32 i = 0; i < static_cast<int32>(D6JointAxis::MAX); i++)
{
const auto& value = _drive[i];
PxD6JointDrive drive;
if (value.Acceleration)
drive.flags = PxD6JointDriveFlag::eACCELERATION;
drive.stiffness = value.Stiffness;
drive.damping = value.Damping;
drive.forceLimit = value.ForceLimit;
ASSERT_LOW_LAYER(drive.isValid());
joint->setDrive(static_cast<PxD6Drive::Enum>(i), drive);
}
{
const auto& value = _limitLinear;
PxJointLinearLimit limit(*Physics::GetTolerancesScale(), Math::Max(value.Extent, ZeroTolerance), value.ContactDist);
limit.stiffness = value.Spring.Stiffness;
limit.damping = value.Spring.Damping;
limit.restitution = value.Restitution;
ASSERT_LOW_LAYER(limit.isValid());
joint->setDistanceLimit(limit);
}
{
const auto& value = _limitTwist;
PxJointAngularLimitPair limit(value.Lower * DegreesToRadians, Math::Max(value.Upper, value.Lower) * DegreesToRadians, value.ContactDist);
limit.stiffness = value.Spring.Stiffness;
limit.damping = value.Spring.Damping;
limit.restitution = value.Restitution;
ASSERT_LOW_LAYER(limit.isValid());
joint->setTwistLimit(limit);
}
{
const auto& value = _limitSwing;
PxJointLimitCone limit(Math::Clamp(value.YLimitAngle * DegreesToRadians, ZeroTolerance, PI - ZeroTolerance), Math::Clamp(value.ZLimitAngle * DegreesToRadians, ZeroTolerance, PI - ZeroTolerance), value.ContactDist);
limit.stiffness = value.Spring.Stiffness;
limit.damping = value.Spring.Damping;
limit.restitution = value.Restitution;
ASSERT_LOW_LAYER(limit.isValid());
joint->setSwingLimit(limit);
}
PhysicsBackend::SetD6JointDrive(joint, (D6JointDriveType)i, _drive[i]);
PhysicsBackend::SetD6JointLimitLinear(joint, _limitLinear);
PhysicsBackend::SetD6JointLimitTwist(joint, _limitTwist);
PhysicsBackend::SetD6JointLimitSwing(joint, _limitSwing);
return joint;
}

View File

@@ -303,19 +303,19 @@ public:
public:
/// <summary>
/// Gets the twist angle of the joint.
/// Gets the twist angle of the joint (in the range (-2*Pi, 2*Pi]).
/// </summary>
API_PROPERTY() float GetCurrentTwist() const;
/// <summary>
/// Gets the current swing angle of the joint from the Y axis.
/// </summary>
API_PROPERTY() float GetCurrentSwingYAngle() const;
API_PROPERTY() float GetCurrentSwingY() const;
/// <summary>
/// Gets the current swing angle of the joint from the Z axis.
/// </summary>
API_PROPERTY() float GetCurrentSwingZAngle() const;
API_PROPERTY() float GetCurrentSwingZ() const;
public:
@@ -329,5 +329,5 @@ public:
protected:
// [Joint]
PxJoint* CreateJoint(JointData& data) override;
void* CreateJoint(const PhysicsJointDesc& desc) override;
};

View File

@@ -1,9 +1,8 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
#include "DistanceJoint.h"
#include "Engine/Physics/PhysicsBackend.h"
#include "Engine/Serialization/Serialization.h"
#include "Engine/Physics/Utilities.h"
#include <ThirdParty/PhysX/extensions/PxDistanceJoint.h>
DistanceJoint::DistanceJoint(const SpawnParams& params)
: Joint(params)
@@ -18,13 +17,9 @@ void DistanceJoint::SetFlags(DistanceJointFlag value)
{
if (_flags == value)
return;
_flags = value;
if (_joint)
{
static_cast<PxDistanceJoint*>(_joint)->setDistanceJointFlags(static_cast<PxDistanceJointFlag::Enum>(value));
}
PhysicsBackend::SetDistanceJointFlags(_joint, value);
}
void DistanceJoint::SetMinDistance(float value)
@@ -32,13 +27,9 @@ void DistanceJoint::SetMinDistance(float value)
value = Math::Clamp(value, 0.0f, _maxDistance);
if (Math::NearEqual(value, _minDistance))
return;
_minDistance = value;
if (_joint)
{
static_cast<PxDistanceJoint*>(_joint)->setMinDistance(value);
}
PhysicsBackend::SetDistanceJointMinDistance(_joint, value);
}
void DistanceJoint::SetMaxDistance(float value)
@@ -46,13 +37,9 @@ void DistanceJoint::SetMaxDistance(float value)
value = Math::Max(_minDistance, value);
if (Math::NearEqual(value, _maxDistance))
return;
_maxDistance = value;
if (_joint)
{
static_cast<PxDistanceJoint*>(_joint)->setMaxDistance(value);
}
PhysicsBackend::SetDistanceJointMaxDistance(_joint, value);
}
void DistanceJoint::SetTolerance(float value)
@@ -60,32 +47,23 @@ void DistanceJoint::SetTolerance(float value)
value = Math::Max(0.1f, value);
if (Math::NearEqual(value, _tolerance))
return;
_tolerance = value;
if (_joint)
{
static_cast<PxDistanceJoint*>(_joint)->setTolerance(value);
}
PhysicsBackend::SetDistanceJointTolerance(_joint, value);
}
void DistanceJoint::SetSpringParameters(const SpringParameters& value)
{
if (value == _spring)
return;
_spring = value;
if (_joint)
{
static_cast<PxDistanceJoint*>(_joint)->setStiffness(value.Stiffness);
static_cast<PxDistanceJoint*>(_joint)->setDamping(value.Damping);
}
PhysicsBackend::SetDistanceJointSpring(_joint, value);
}
float DistanceJoint::GetCurrentDistance() const
{
return _joint ? static_cast<PxDistanceJoint*>(_joint)->getDistance() : 0.0f;
return _joint ? PhysicsBackend::GetDistanceJointDistance(_joint) : 0.0f;
}
#if USE_EDITOR
@@ -149,18 +127,13 @@ void DistanceJoint::Deserialize(DeserializeStream& stream, ISerializeModifier* m
DESERIALIZE_MEMBER(Damping, _spring.Damping);
}
PxJoint* DistanceJoint::CreateJoint(JointData& data)
void* DistanceJoint::CreateJoint(const PhysicsJointDesc& desc)
{
const PxTransform trans0(C2P(data.Pos0), C2P(data.Rot0));
const PxTransform trans1(C2P(data.Pos1), C2P(data.Rot1));
auto joint = PxDistanceJointCreate(*data.Physics, data.Actor0, trans0, data.Actor1, trans1);
joint->setMinDistance(_minDistance);
joint->setMaxDistance(_maxDistance);
joint->setTolerance(_tolerance);
joint->setDistanceJointFlags(static_cast<PxDistanceJointFlag::Enum>(_flags));
joint->setStiffness(_spring.Stiffness);
joint->setDamping(_spring.Damping);
void* joint = PhysicsBackend::CreateDistanceJoint(desc);
PhysicsBackend::SetDistanceJointFlags(joint, _flags);
PhysicsBackend::SetDistanceJointMinDistance(joint, _minDistance);
PhysicsBackend::SetDistanceJointMaxDistance(joint, _maxDistance);
PhysicsBackend::SetDistanceJointTolerance(joint, _tolerance);
PhysicsBackend::SetDistanceJointSpring(joint, _spring);
return joint;
}

View File

@@ -157,5 +157,5 @@ public:
protected:
// [Joint]
PxJoint* CreateJoint(JointData& data) override;
void* CreateJoint(const PhysicsJointDesc& desc) override;
};

View File

@@ -1,8 +1,7 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
#include "FixedJoint.h"
#include "Engine/Physics/Utilities.h"
#include <ThirdParty/PhysX/extensions/PxFixedJoint.h>
#include "Engine/Physics/PhysicsBackend.h"
FixedJoint::FixedJoint(const SpawnParams& params)
: Joint(params)
@@ -23,9 +22,7 @@ void FixedJoint::OnDebugDrawSelected()
#endif
PxJoint* FixedJoint::CreateJoint(JointData& data)
void* FixedJoint::CreateJoint(const PhysicsJointDesc& desc)
{
const PxTransform trans0(C2P(data.Pos0), C2P(data.Rot0));
const PxTransform trans1(C2P(data.Pos1), C2P(data.Rot1));
return PxFixedJointCreate(*data.Physics, data.Actor0, trans0, data.Actor1, trans1);
return PhysicsBackend::CreateFixedJoint(desc);
}

View File

@@ -21,5 +21,5 @@ public:
protected:
// [Joint]
PxJoint* CreateJoint(JointData& data) override;
void* CreateJoint(const PhysicsJointDesc& desc) override;
};

View File

@@ -2,8 +2,7 @@
#include "HingeJoint.h"
#include "Engine/Serialization/Serialization.h"
#include "Engine/Physics/Utilities.h"
#include <ThirdParty/PhysX/extensions/PxRevoluteJoint.h>
#include "Engine/Physics/PhysicsBackend.h"
HingeJoint::HingeJoint(const SpawnParams& params)
: Joint(params)
@@ -17,61 +16,37 @@ void HingeJoint::SetFlags(const HingeJointFlag value)
{
if (_flags == value)
return;
_flags = value;
if (_joint)
{
auto joint = static_cast<PxRevoluteJoint*>(_joint);
joint->setRevoluteJointFlag(PxRevoluteJointFlag::eLIMIT_ENABLED, (_flags & HingeJointFlag::Limit) != 0);
joint->setRevoluteJointFlag(PxRevoluteJointFlag::eDRIVE_ENABLED, (_flags & HingeJointFlag::Drive) != 0);
}
PhysicsBackend::SetHingeJointFlags(_joint, value, _drive.FreeSpin);
}
void HingeJoint::SetLimit(const LimitAngularRange& value)
{
if (_limit == value)
return;
_limit = value;
if (_joint)
{
auto joint = static_cast<PxRevoluteJoint*>(_joint);
PxJointAngularLimitPair limit(value.Lower * DegreesToRadians, Math::Max(value.Upper, value.Lower) * DegreesToRadians, value.ContactDist);
limit.stiffness = value.Spring.Stiffness;
limit.damping = value.Spring.Damping;
limit.restitution = value.Restitution;
ASSERT_LOW_LAYER(limit.isValid());
joint->setLimit(limit);
}
PhysicsBackend::SetHingeJointLimit(_joint, value);
}
void HingeJoint::SetDrive(const HingeJointDrive& value)
{
if (_drive == value)
return;
_drive = value;
if (_joint)
{
auto joint = static_cast<PxRevoluteJoint*>(_joint);
joint->setDriveVelocity(Math::Max(value.Velocity, 0.0f));
joint->setDriveForceLimit(Math::Max(value.ForceLimit, 0.0f));
joint->setDriveGearRatio(Math::Max(value.GearRatio, 0.0f));
joint->setRevoluteJointFlag(PxRevoluteJointFlag::eDRIVE_FREESPIN, value.FreeSpin);
}
PhysicsBackend::SetHingeJointDrive(_joint, value);
}
float HingeJoint::GetCurrentAngle() const
{
return _joint ? static_cast<PxRevoluteJoint*>(_joint)->getAngle() : 0.0f;
return _joint ? PhysicsBackend::GetHingeJointAngle(_joint) : 0.0f;
}
float HingeJoint::GetCurrentVelocity() const
{
return _joint ? static_cast<PxRevoluteJoint*>(_joint)->getVelocity() : 0.0f;
return _joint ? PhysicsBackend::GetHingeJointVelocity(_joint) : 0.0f;
}
#if USE_EDITOR
@@ -146,29 +121,11 @@ void HingeJoint::Deserialize(DeserializeStream& stream, ISerializeModifier* modi
DESERIALIZE_MEMBER(FreeSpin, _drive.FreeSpin);
}
PxJoint* HingeJoint::CreateJoint(JointData& data)
void* HingeJoint::CreateJoint(const PhysicsJointDesc& desc)
{
const PxTransform trans0(C2P(data.Pos0), C2P(data.Rot0));
const PxTransform trans1(C2P(data.Pos1), C2P(data.Rot1));
auto joint = PxRevoluteJointCreate(*data.Physics, data.Actor0, trans0, data.Actor1, trans1);
int32 flags = 0;
if (_flags & HingeJointFlag::Limit)
flags |= PxRevoluteJointFlag::eLIMIT_ENABLED;
if (_flags & HingeJointFlag::Drive)
flags |= PxRevoluteJointFlag::eDRIVE_ENABLED;
if (_drive.FreeSpin)
flags |= PxRevoluteJointFlag::eDRIVE_FREESPIN;
joint->setRevoluteJointFlags(static_cast<PxRevoluteJointFlag::Enum>(flags));
joint->setDriveVelocity(_drive.Velocity);
joint->setDriveForceLimit(_drive.ForceLimit);
joint->setDriveGearRatio(_drive.GearRatio);
PxJointAngularLimitPair limit(_limit.Lower * DegreesToRadians, Math::Max(_limit.Upper, _limit.Lower) * DegreesToRadians, _limit.ContactDist);
limit.stiffness = _limit.Spring.Stiffness;
limit.damping = _limit.Spring.Damping;
limit.restitution = _limit.Restitution;
ASSERT_LOW_LAYER(limit.isValid());
joint->setLimit(limit);
void* joint = PhysicsBackend::CreateHingeJoint(desc);
PhysicsBackend::SetHingeJointFlags(joint, _flags, _drive.FreeSpin);
PhysicsBackend::SetHingeJointLimit(joint, _limit);
PhysicsBackend::SetHingeJointDrive(joint, _drive);
return joint;
}

View File

@@ -165,5 +165,5 @@ public:
protected:
// [Joint]
PxJoint* CreateJoint(JointData& data) override;
void* CreateJoint(const PhysicsJointDesc& desc) override;
};

View File

@@ -3,14 +3,13 @@
#include "Joint.h"
#include "Engine/Serialization/Serialization.h"
#include "Engine/Core/Log.h"
#include "Engine/Physics/Utilities.h"
#include "Engine/Physics/Physics.h"
#include "Engine/Physics/PhysicsBackend.h"
#include "Engine/Physics/PhysicsScene.h"
#include "Engine/Physics/Actors/IPhysicsActor.h"
#if USE_EDITOR
#include "Engine/Level/Scene/SceneRendering.h"
#endif
#include "Engine/Scripting/Script.h"
#include <ThirdParty/PhysX/extensions/PxJoint.h>
Joint::Joint(const SpawnParams& params)
: Actor(params)
@@ -27,36 +26,27 @@ void Joint::SetBreakForce(float value)
{
if (Math::NearEqual(value, _breakForce))
return;
_breakForce = value;
if (_joint)
{
_joint->setBreakForce(_breakForce, _breakTorque);
}
PhysicsBackend::SetJointBreakForce(_joint, _breakForce, _breakTorque);
}
void Joint::SetBreakTorque(float value)
{
if (Math::NearEqual(value, _breakTorque))
return;
_breakTorque = value;
if (_joint)
{
_joint->setBreakForce(_breakForce, _breakTorque);
}
PhysicsBackend::SetJointBreakForce(_joint, _breakForce, _breakTorque);
}
void Joint::SetEnableCollision(bool value)
{
if (value == GetEnableCollision())
return;
_enableCollision = value;
if (_joint)
{
_joint->setConstraintFlag(PxConstraintFlag::eCOLLISION_ENABLED, value);
}
PhysicsBackend::SetJointFlags(_joint, _enableCollision ? PhysicsBackend::JointFlags::Collision : PhysicsBackend::JointFlags::None);
}
bool Joint::GetEnableAutoAnchor() const
@@ -73,24 +63,23 @@ void Joint::SetTargetAnchor(const Vector3& value)
{
if (Vector3::NearEqual(value, _targetAnchor))
return;
_targetAnchor = value;
if (_joint && !_enableAutoAnchor)
{
_joint->setLocalPose(PxJointActorIndex::eACTOR1, PxTransform(C2P(_targetAnchor), C2P(_targetAnchorRotation)));
}
PhysicsBackend::SetJointActorPose(_joint, _targetAnchor, _targetAnchorRotation, 1);
}
void Joint::SetTargetAnchorRotation(const Quaternion& value)
{
if (Quaternion::NearEqual(value, _targetAnchorRotation))
return;
_targetAnchorRotation = value;
if (_joint && !_enableAutoAnchor)
{
_joint->setLocalPose(PxJointActorIndex::eACTOR1, PxTransform(C2P(_targetAnchor), C2P(_targetAnchorRotation)));
}
PhysicsBackend::SetJointActorPose(_joint, _targetAnchor, _targetAnchorRotation, 1);
}
void* Joint::GetPhysicsImpl() const
{
return _joint;
}
void Joint::SetJointLocation(const Vector3& location)
@@ -128,14 +117,9 @@ void Joint::SetJointOrientation(const Quaternion& orientation)
void Joint::GetCurrentForce(Vector3& linear, Vector3& angular) const
{
if (_joint && _joint->getConstraint())
{
_joint->getConstraint()->getForce(*(PxVec3*)&linear, *(PxVec3*)&angular);
}
else
{
linear = angular = Vector3::Zero;
}
linear = angular = Vector3::Zero;
if (_joint)
PhysicsBackend::GetJointForce(_joint, linear, angular);
}
void Joint::Create()
@@ -151,26 +135,25 @@ void Joint::Create()
}
// Create joint object
JointData data;
data.Physics = Physics::GetPhysics();
data.Actor0 = parent->GetRigidActor();
data.Actor1 = target ? target->GetRigidActor() : nullptr;
data.Pos0 = _localTransform.Translation;
data.Rot0 = _localTransform.Orientation;
data.Pos1 = _targetAnchor;
data.Rot1 = _targetAnchorRotation;
PhysicsJointDesc desc;
desc.Joint = this;
desc.Actor0 = parent->GetPhysicsActor();
desc.Actor1 = target ? target->GetPhysicsActor() : nullptr;
desc.Pos0 = _localTransform.Translation;
desc.Rot0 = _localTransform.Orientation;
desc.Pos1 = _targetAnchor;
desc.Rot1 = _targetAnchorRotation;
if (_enableAutoAnchor && target)
{
// Place target anchor at the joint location
data.Pos1 = Target->GetTransform().WorldToLocal(GetPosition());
data.Rot1 = WorldToLocal(Target->GetOrientation(), GetOrientation());
desc.Pos1 = Target->GetTransform().WorldToLocal(GetPosition());
desc.Rot1 = WorldToLocal(Target->GetOrientation(), GetOrientation());
}
_joint = CreateJoint(data);
_joint->userData = this;
_joint = CreateJoint(desc);
// Setup joint properties
_joint->setBreakForce(_breakForce, _breakTorque);
_joint->setConstraintFlag(PxConstraintFlag::eCOLLISION_ENABLED, _enableCollision);
PhysicsBackend::SetJointBreakForce(_joint, _breakForce, _breakTorque);
PhysicsBackend::SetJointFlags(_joint, _enableCollision ? PhysicsBackend::JointFlags::Collision : PhysicsBackend::JointFlags::None);
}
void Joint::OnJointBreak()
@@ -180,10 +163,8 @@ void Joint::OnJointBreak()
void Joint::Delete()
{
// Remove the joint
Physics::RemoveJoint(this);
_joint->userData = nullptr;
_joint->release();
PhysicsBackend::RemoveJoint(this);
PhysicsBackend::DestroyJoint(_joint);
_joint = nullptr;
}
@@ -192,8 +173,7 @@ void Joint::SetActors()
auto parent = dynamic_cast<IPhysicsActor*>(GetParent());
auto target = dynamic_cast<IPhysicsActor*>(Target.Get());
ASSERT(parent != nullptr);
_joint->setActors(parent ? parent->GetRigidActor() : nullptr, target ? target->GetRigidActor() : nullptr);
PhysicsBackend::SetJointActors(_joint, parent->GetPhysicsActor(), target ? target->GetPhysicsActor() : nullptr);
}
void Joint::OnTargetChanged()
@@ -347,7 +327,7 @@ void Joint::OnActiveInTreeChanged()
else
Delete();
}
// Joint object may not be created if actor is disabled on play mode begin (late init feature)
// Joint object may not be created if actor is disabled on play mode begin (late init feature)
else if (IsDuringPlay())
{
Create();
@@ -393,9 +373,6 @@ void Joint::OnTransformChanged()
_box = BoundingBox(_transform.Translation);
_sphere = BoundingSphere(_transform.Translation, 0.0f);
if (_joint)
{
_joint->setLocalPose(PxJointActorIndex::eACTOR0, PxTransform(C2P(_localTransform.Translation), C2P(_localTransform.Orientation)));
}
PhysicsBackend::SetJointActorPose(_joint, _localTransform.Translation, _localTransform.Orientation, 0);
}

View File

@@ -21,7 +21,7 @@ API_CLASS(Abstract) class FLAXENGINE_API Joint : public Actor
DECLARE_SCENE_OBJECT_ABSTRACT(Joint);
protected:
PxJoint* _joint;
void* _joint;
float _breakForce;
float _breakTorque;
Vector3 _targetAnchor;
@@ -133,12 +133,9 @@ public:
public:
/// <summary>
/// Gets the native PhysX joint object.
/// Gets the native physics backend object.
/// </summary>
FORCE_INLINE PxJoint* GetPhysXJoint() const
{
return _joint;
}
void* GetPhysicsImpl() const;
/// <summary>
/// Sets the location of the joint by automatically computing local position and target anchor to place a joint at the given location (world-space).
@@ -178,20 +175,9 @@ public:
protected:
struct JointData
{
PxPhysics* Physics;
PxRigidActor* Actor0;
PxRigidActor* Actor1;
Quaternion Rot0;
Quaternion Rot1;
Vector3 Pos0;
Vector3 Pos1;
};
Vector3 GetTargetPosition() const;
Quaternion GetTargetOrientation() const;
virtual PxJoint* CreateJoint(JointData& data) = 0;
virtual void* CreateJoint(const struct PhysicsJointDesc& desc) = 0;
#if USE_EDITOR
virtual void DrawPhysicsDebug(RenderView& view);
#endif

View File

@@ -2,9 +2,7 @@
#include "SliderJoint.h"
#include "Engine/Serialization/Serialization.h"
#include "Engine/Physics/Utilities.h"
#include "Engine/Physics/Physics.h"
#include <ThirdParty/PhysX/extensions/PxPrismaticJoint.h>
#include "Engine/Physics/PhysicsBackend.h"
SliderJoint::SliderJoint(const SpawnParams& params)
: Joint(params)
@@ -18,43 +16,28 @@ void SliderJoint::SetFlags(const SliderJointFlag value)
{
if (_flags == value)
return;
_flags = value;
if (_joint)
{
auto joint = static_cast<PxPrismaticJoint*>(_joint);
joint->setPrismaticJointFlag(PxPrismaticJointFlag::eLIMIT_ENABLED, (_flags & SliderJointFlag::Limit) != 0);
}
PhysicsBackend::SetSliderJointFlags(_joint, value);
}
void SliderJoint::SetLimit(const LimitLinearRange& value)
{
if (_limit == value)
return;
_limit = value;
if (_joint)
{
auto joint = static_cast<PxPrismaticJoint*>(_joint);
PxJointLinearLimitPair limit(*Physics::GetTolerancesScale(), value.Lower, value.Upper, value.ContactDist);
limit.stiffness = value.Spring.Stiffness;
limit.damping = value.Spring.Damping;
limit.restitution = value.Restitution;
ASSERT_LOW_LAYER(limit.isValid());
joint->setLimit(limit);
}
PhysicsBackend::SetSliderJointLimit(_joint, value);
}
float SliderJoint::GetCurrentPosition() const
{
return _joint ? static_cast<PxPrismaticJoint*>(_joint)->getPosition() : 0.0f;
return _joint ? PhysicsBackend::GetSliderJointPosition(_joint) : 0.0f;
}
float SliderJoint::GetCurrentVelocity() const
{
return _joint ? static_cast<PxPrismaticJoint*>(_joint)->getVelocity() : 0.0f;
return _joint ? PhysicsBackend::GetSliderJointVelocity(_joint) : 0.0f;
}
#if USE_EDITOR
@@ -111,21 +94,10 @@ void SliderJoint::Deserialize(DeserializeStream& stream, ISerializeModifier* mod
DESERIALIZE_MEMBER(UpperLimit, _limit.Upper);
}
PxJoint* SliderJoint::CreateJoint(JointData& data)
void* SliderJoint::CreateJoint(const PhysicsJointDesc& desc)
{
const PxTransform trans0(C2P(data.Pos0), C2P(data.Rot0));
const PxTransform trans1(C2P(data.Pos1), C2P(data.Rot1));
auto joint = PxPrismaticJointCreate(*data.Physics, data.Actor0, trans0, data.Actor1, trans1);
int32 flags = 0;
if (_flags & SliderJointFlag::Limit)
flags |= PxPrismaticJointFlag::eLIMIT_ENABLED;
joint->setPrismaticJointFlags(static_cast<PxPrismaticJointFlag::Enum>(flags));
PxJointLinearLimitPair limit(*Physics::GetTolerancesScale(), _limit.Lower, _limit.Upper, _limit.ContactDist);
limit.stiffness = _limit.Spring.Stiffness;
limit.damping = _limit.Spring.Damping;
limit.restitution = _limit.Restitution;
joint->setLimit(limit);
void* joint = PhysicsBackend::CreateSliderJoint(desc);
PhysicsBackend::SetSliderJointFlags(joint, _flags);
PhysicsBackend::SetSliderJointLimit(joint, _limit);
return joint;
}

View File

@@ -95,5 +95,5 @@ public:
protected:
// [Joint]
PxJoint* CreateJoint(JointData& data) override;
void* CreateJoint(const PhysicsJointDesc& desc) override;
};

View File

@@ -2,8 +2,7 @@
#include "SphericalJoint.h"
#include "Engine/Serialization/Serialization.h"
#include "Engine/Physics/Utilities.h"
#include <ThirdParty/PhysX/extensions/PxSphericalJoint.h>
#include "Engine/Physics/PhysicsBackend.h"
SphericalJoint::SphericalJoint(const SpawnParams& params)
: Joint(params)
@@ -15,33 +14,18 @@ void SphericalJoint::SetFlags(const SphericalJointFlag value)
{
if (_flags == value)
return;
_flags = value;
if (_joint)
{
auto joint = static_cast<PxSphericalJoint*>(_joint);
joint->setSphericalJointFlag(PxSphericalJointFlag::eLIMIT_ENABLED, (_flags & SphericalJointFlag::Limit) != 0);
}
PhysicsBackend::SetSphericalJointFlags(_joint, value);
}
void SphericalJoint::SetLimit(const LimitConeRange& value)
{
if (_limit == value)
return;
_limit = value;
if (_joint)
{
auto joint = static_cast<PxSphericalJoint*>(_joint);
PxJointLimitCone limit(Math::Clamp(value.YLimitAngle * DegreesToRadians, ZeroTolerance, PI - ZeroTolerance), Math::Clamp(value.ZLimitAngle * DegreesToRadians, ZeroTolerance, PI - ZeroTolerance), value.ContactDist);
limit.stiffness = value.Spring.Stiffness;
limit.damping = value.Spring.Damping;
limit.restitution = value.Restitution;
ASSERT_LOW_LAYER(limit.isValid());
joint->setLimitCone(limit);
}
PhysicsBackend::SetSphericalJointLimit(_joint, value);
}
#if USE_EDITOR
@@ -101,21 +85,10 @@ void SphericalJoint::Deserialize(DeserializeStream& stream, ISerializeModifier*
DESERIALIZE_MEMBER(ZLimitAngle, _limit.ZLimitAngle);
}
PxJoint* SphericalJoint::CreateJoint(JointData& data)
void* SphericalJoint::CreateJoint(const PhysicsJointDesc& desc)
{
const PxTransform trans0(C2P(data.Pos0), C2P(data.Rot0));
const PxTransform trans1(C2P(data.Pos1), C2P(data.Rot1));
auto joint = PxSphericalJointCreate(*data.Physics, data.Actor0, trans0, data.Actor1, trans1);
int32 flags = 0;
if (_flags & SphericalJointFlag::Limit)
flags |= PxSphericalJointFlag::eLIMIT_ENABLED;
joint->setSphericalJointFlags(static_cast<PxSphericalJointFlag::Enum>(flags));
PxJointLimitCone limit(Math::Clamp(_limit.YLimitAngle * DegreesToRadians, ZeroTolerance, PI - ZeroTolerance), Math::Clamp(_limit.ZLimitAngle * DegreesToRadians, ZeroTolerance, PI - ZeroTolerance), _limit.ContactDist);
limit.stiffness = _limit.Spring.Stiffness;
limit.damping = _limit.Spring.Damping;
limit.restitution = _limit.Restitution;
joint->setLimitCone(limit);
void* joint = PhysicsBackend::CreateSphericalJoint(desc);
PhysicsBackend::SetSphericalJointFlags(joint, _flags);
PhysicsBackend::SetSphericalJointLimit(joint, _limit);
return joint;
}

View File

@@ -85,5 +85,5 @@ public:
protected:
// [Joint]
PxJoint* CreateJoint(JointData& data) override;
void* CreateJoint(const PhysicsJointDesc& desc) override;
};