Skip to content

Commit

Permalink
Implemented NotifyShapeChange to notify constraint of COM changes (#506)
Browse files Browse the repository at this point in the history
Added example test to show how it is used.
  • Loading branch information
jrouwe committed Apr 14, 2023
1 parent 0d39abb commit a37d60e
Show file tree
Hide file tree
Showing 29 changed files with 267 additions and 0 deletions.
1 change: 1 addition & 0 deletions Jolt/Physics/Collision/Shape/MutableCompoundShape.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class MutableCompoundShape final : public CompoundShape

/// Recalculate the center of mass and shift all objects so they're centered around it
/// (this needs to be done of dynamic bodies and if the center of mass changes significantly due to adding / removing / repositioning sub shapes or else the simulation will look unnatural)
/// Note that after adjusting the center of mass of an object you need to call BodyInterface::NotifyShapeChanged and Constraint::NotifyShapeChanged on the relevant bodies / constraints.
void AdjustCenterOfMass();

///@}
Expand Down
8 changes: 8 additions & 0 deletions Jolt/Physics/Constraints/ConeConstraint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,14 @@ ConeConstraint::ConeConstraint(Body &inBody1, Body &inBody2, const ConeConstrain
}
}

void ConeConstraint::NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inDeltaCOM)
{
if (mBody1->GetID() == inBodyID)
mLocalSpacePosition1 -= inDeltaCOM;
else if (mBody2->GetID() == inBodyID)
mLocalSpacePosition2 -= inDeltaCOM;
}

void ConeConstraint::CalculateRotationConstraintProperties(float inDeltaTime, Mat44Arg inRotation1, Mat44Arg inRotation2)
{
// Rotation is along the cross product of both twist axis
Expand Down
1 change: 1 addition & 0 deletions Jolt/Physics/Constraints/ConeConstraint.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class ConeConstraint final : public TwoBodyConstraint

// Generic interface of a constraint
virtual EConstraintSubType GetSubType() const override { return EConstraintSubType::Cone; }
virtual void NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inDeltaCOM) override;
virtual void SetupVelocityConstraint(float inDeltaTime) override;
virtual void WarmStartVelocityConstraint(float inWarmStartImpulseRatio) override;
virtual bool SolveVelocityConstraint(float inDeltaTime) override;
Expand Down
7 changes: 7 additions & 0 deletions Jolt/Physics/Constraints/Constraint.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

JPH_NAMESPACE_BEGIN

class BodyID;
class IslandBuilder;
class LargeIslandSplitter;
class BodyManager;
Expand Down Expand Up @@ -141,6 +142,12 @@ class Constraint : public RefTarget<Constraint>, public NonCopyable
uint64 GetUserData() const { return mUserData; }
void SetUserData(uint64 inUserData) { mUserData = inUserData; }

/// Notify the constraint that the shape of a body has changed and that its center of mass has moved by inDeltaCOM.
/// Bodies don't know which constraints are connected to them so the user is responsible for notifying the relevant constraints when a body changes.
/// @param inBodyID ID of the body that has changed
/// @param inDeltaCOM The delta of the center of mass of the body (shape->GetCenterOfMass() - shape_before_change->GetCenterOfMass())
virtual void NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inDeltaCOM) = 0;

///@name Solver interface
///@{
virtual bool IsActive() const { return mEnabled; }
Expand Down
8 changes: 8 additions & 0 deletions Jolt/Physics/Constraints/DistanceConstraint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,14 @@ DistanceConstraint::DistanceConstraint(Body &inBody1, Body &inBody2, const Dista
SetDamping(inSettings.mDamping);
}

void DistanceConstraint::NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inDeltaCOM)
{
if (mBody1->GetID() == inBodyID)
mLocalSpacePosition1 -= inDeltaCOM;
else if (mBody2->GetID() == inBodyID)
mLocalSpacePosition2 -= inDeltaCOM;
}

void DistanceConstraint::CalculateConstraintProperties(float inDeltaTime)
{
// Update world space positions (the bodies may have moved)
Expand Down
1 change: 1 addition & 0 deletions Jolt/Physics/Constraints/DistanceConstraint.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class DistanceConstraint final : public TwoBodyConstraint

// Generic interface of a constraint
virtual EConstraintSubType GetSubType() const override { return EConstraintSubType::Distance; }
virtual void NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inDeltaCOM) override;
virtual void SetupVelocityConstraint(float inDeltaTime) override;
virtual void WarmStartVelocityConstraint(float inWarmStartImpulseRatio) override;
virtual bool SolveVelocityConstraint(float inDeltaTime) override;
Expand Down
8 changes: 8 additions & 0 deletions Jolt/Physics/Constraints/FixedConstraint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,14 @@ FixedConstraint::FixedConstraint(Body &inBody1, Body &inBody2, const FixedConstr
}
}

void FixedConstraint::NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inDeltaCOM)
{
if (mBody1->GetID() == inBodyID)
mLocalSpacePosition1 -= inDeltaCOM;
else if (mBody2->GetID() == inBodyID)
mLocalSpacePosition2 -= inDeltaCOM;
}

void FixedConstraint::SetupVelocityConstraint(float inDeltaTime)
{
// Calculate constraint values that don't change when the bodies don't change position
Expand Down
1 change: 1 addition & 0 deletions Jolt/Physics/Constraints/FixedConstraint.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class FixedConstraint final : public TwoBodyConstraint

// Generic interface of a constraint
virtual EConstraintSubType GetSubType() const override { return EConstraintSubType::Fixed; }
virtual void NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inDeltaCOM) override;
virtual void SetupVelocityConstraint(float inDeltaTime) override;
virtual void WarmStartVelocityConstraint(float inWarmStartImpulseRatio) override;
virtual bool SolveVelocityConstraint(float inDeltaTime) override;
Expand Down
1 change: 1 addition & 0 deletions Jolt/Physics/Constraints/GearConstraint.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class GearConstraint final : public TwoBodyConstraint

// Generic interface of a constraint
virtual EConstraintSubType GetSubType() const override { return EConstraintSubType::Gear; }
virtual void NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inDeltaCOM) override { /* Do nothing */ }
virtual void SetupVelocityConstraint(float inDeltaTime) override;
virtual void WarmStartVelocityConstraint(float inWarmStartImpulseRatio) override;
virtual bool SolveVelocityConstraint(float inDeltaTime) override;
Expand Down
8 changes: 8 additions & 0 deletions Jolt/Physics/Constraints/HingeConstraint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,14 @@ HingeConstraint::HingeConstraint(Body &inBody1, Body &inBody2, const HingeConstr
}
}

void HingeConstraint::NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inDeltaCOM)
{
if (mBody1->GetID() == inBodyID)
mLocalSpacePosition1 -= inDeltaCOM;
else if (mBody2->GetID() == inBodyID)
mLocalSpacePosition2 -= inDeltaCOM;
}

float HingeConstraint::GetCurrentAngle() const
{
// See: CalculateA1AndTheta
Expand Down
1 change: 1 addition & 0 deletions Jolt/Physics/Constraints/HingeConstraint.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class HingeConstraint final : public TwoBodyConstraint

// Generic interface of a constraint
virtual EConstraintSubType GetSubType() const override { return EConstraintSubType::Hinge; }
virtual void NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inDeltaCOM) override;
virtual void SetupVelocityConstraint(float inDeltaTime) override;
virtual void WarmStartVelocityConstraint(float inWarmStartImpulseRatio) override;
virtual bool SolveVelocityConstraint(float inDeltaTime) override;
Expand Down
8 changes: 8 additions & 0 deletions Jolt/Physics/Constraints/PathConstraint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@ PathConstraint::PathConstraint(Body &inBody1, Body &inBody2, const PathConstrain
SetPath(inSettings.mPath, inSettings.mPathFraction);
}

void PathConstraint::NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inDeltaCOM)
{
if (mBody1->GetID() == inBodyID)
mPathToBody1.SetTranslation(mPathToBody1.GetTranslation() - inDeltaCOM);
else if (mBody2->GetID() == inBodyID)
mPathToBody2.SetTranslation(mPathToBody2.GetTranslation() - inDeltaCOM);
}

void PathConstraint::SetPath(const PathConstraintPath *inPath, float inPathFraction)
{
mPath = inPath;
Expand Down
1 change: 1 addition & 0 deletions Jolt/Physics/Constraints/PathConstraint.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ class PathConstraint final : public TwoBodyConstraint

// Generic interface of a constraint
virtual EConstraintSubType GetSubType() const override { return EConstraintSubType::Path; }
virtual void NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inDeltaCOM) override;
virtual void SetupVelocityConstraint(float inDeltaTime) override;
virtual void WarmStartVelocityConstraint(float inWarmStartImpulseRatio) override;
virtual bool SolveVelocityConstraint(float inDeltaTime) override;
Expand Down
8 changes: 8 additions & 0 deletions Jolt/Physics/Constraints/PointConstraint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ PointConstraint::PointConstraint(Body &inBody1, Body &inBody2, const PointConstr
}
}

void PointConstraint::NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inDeltaCOM)
{
if (mBody1->GetID() == inBodyID)
mLocalSpacePosition1 -= inDeltaCOM;
else if (mBody2->GetID() == inBodyID)
mLocalSpacePosition2 -= inDeltaCOM;
}

void PointConstraint::SetPoint1(EConstraintSpace inSpace, RVec3Arg inPoint1)
{
if (inSpace == EConstraintSpace::WorldSpace)
Expand Down
1 change: 1 addition & 0 deletions Jolt/Physics/Constraints/PointConstraint.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class PointConstraint final : public TwoBodyConstraint

// Generic interface of a constraint
virtual EConstraintSubType GetSubType() const override { return EConstraintSubType::Point; }
virtual void NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inDeltaCOM) override;
virtual void SetupVelocityConstraint(float inDeltaTime) override;
virtual void WarmStartVelocityConstraint(float inWarmStartImpulseRatio) override;
virtual bool SolveVelocityConstraint(float inDeltaTime) override;
Expand Down
8 changes: 8 additions & 0 deletions Jolt/Physics/Constraints/PulleyConstraint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,14 @@ PulleyConstraint::PulleyConstraint(Body &inBody1, Body &inBody2, const PulleyCon
mWorldSpaceNormal1 = mWorldSpaceNormal2 = -Vec3::sAxisY();
}

void PulleyConstraint::NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inDeltaCOM)
{
if (mBody1->GetID() == inBodyID)
mLocalSpacePosition1 -= inDeltaCOM;
else if (mBody2->GetID() == inBodyID)
mLocalSpacePosition2 -= inDeltaCOM;
}

float PulleyConstraint::CalculatePositionsNormalsAndLength()
{
// Update world space positions (the bodies may have moved)
Expand Down
1 change: 1 addition & 0 deletions Jolt/Physics/Constraints/PulleyConstraint.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class PulleyConstraint final : public TwoBodyConstraint

// Generic interface of a constraint
virtual EConstraintSubType GetSubType() const override { return EConstraintSubType::Pulley; }
virtual void NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inDeltaCOM) override;
virtual void SetupVelocityConstraint(float inDeltaTime) override;
virtual void WarmStartVelocityConstraint(float inWarmStartImpulseRatio) override;
virtual bool SolveVelocityConstraint(float inDeltaTime) override;
Expand Down
1 change: 1 addition & 0 deletions Jolt/Physics/Constraints/RackAndPinionConstraint.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class RackAndPinionConstraint final : public TwoBodyConstraint

// Generic interface of a constraint
virtual EConstraintSubType GetSubType() const override { return EConstraintSubType::RackAndPinion; }
virtual void NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inDeltaCOM) override { /* Nothing */ }
virtual void SetupVelocityConstraint(float inDeltaTime) override;
virtual void WarmStartVelocityConstraint(float inWarmStartImpulseRatio) override;
virtual bool SolveVelocityConstraint(float inDeltaTime) override;
Expand Down
8 changes: 8 additions & 0 deletions Jolt/Physics/Constraints/SixDOFConstraint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,14 @@ SixDOFConstraint::SixDOFConstraint(Body &inBody1, Body &inBody2, const SixDOFCon
CacheRotationMotorActive();
}

void SixDOFConstraint::NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inDeltaCOM)
{
if (mBody1->GetID() == inBodyID)
mLocalSpacePosition1 -= inDeltaCOM;
else if (mBody2->GetID() == inBodyID)
mLocalSpacePosition2 -= inDeltaCOM;
}

void SixDOFConstraint::SetTranslationLimits(Vec3Arg inLimitMin, Vec3Arg inLimitMax)
{
mLimitMin[EAxis::TranslationX] = inLimitMin.GetX();
Expand Down
1 change: 1 addition & 0 deletions Jolt/Physics/Constraints/SixDOFConstraint.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ class SixDOFConstraint final : public TwoBodyConstraint

/// Generic interface of a constraint
virtual EConstraintSubType GetSubType() const override { return EConstraintSubType::SixDOF; }
virtual void NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inDeltaCOM) override;
virtual void SetupVelocityConstraint(float inDeltaTime) override;
virtual void WarmStartVelocityConstraint(float inWarmStartImpulseRatio) override;
virtual bool SolveVelocityConstraint(float inDeltaTime) override;
Expand Down
8 changes: 8 additions & 0 deletions Jolt/Physics/Constraints/SliderConstraint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,14 @@ SliderConstraint::SliderConstraint(Body &inBody1, Body &inBody2, const SliderCon
SetDamping(inSettings.mDamping);
}

void SliderConstraint::NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inDeltaCOM)
{
if (mBody1->GetID() == inBodyID)
mLocalSpacePosition1 -= inDeltaCOM;
else if (mBody2->GetID() == inBodyID)
mLocalSpacePosition2 -= inDeltaCOM;
}

float SliderConstraint::GetCurrentPosition() const
{
// See: CalculateR1R2U and CalculateSlidingAxisAndPosition
Expand Down
1 change: 1 addition & 0 deletions Jolt/Physics/Constraints/SliderConstraint.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class SliderConstraint final : public TwoBodyConstraint

// Generic interface of a constraint
virtual EConstraintSubType GetSubType() const override { return EConstraintSubType::Slider; }
virtual void NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inDeltaCOM) override;
virtual void SetupVelocityConstraint(float inDeltaTime) override;
virtual void WarmStartVelocityConstraint(float inWarmStartImpulseRatio) override;
virtual bool SolveVelocityConstraint(float inDeltaTime) override;
Expand Down
8 changes: 8 additions & 0 deletions Jolt/Physics/Constraints/SwingTwistConstraint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,14 @@ SwingTwistConstraint::SwingTwistConstraint(Body &inBody1, Body &inBody2, const S
UpdateLimits();
}

void SwingTwistConstraint::NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inDeltaCOM)
{
if (mBody1->GetID() == inBodyID)
mLocalSpacePosition1 -= inDeltaCOM;
else if (mBody2->GetID() == inBodyID)
mLocalSpacePosition2 -= inDeltaCOM;
}

Quat SwingTwistConstraint::GetRotationInConstraintSpace() const
{
// Let b1, b2 be the center of mass transform of body1 and body2 (For body1 this is mBody1->GetCenterOfMassTransform())
Expand Down
1 change: 1 addition & 0 deletions Jolt/Physics/Constraints/SwingTwistConstraint.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ class SwingTwistConstraint final : public TwoBodyConstraint

///@name Generic interface of a constraint
virtual EConstraintSubType GetSubType() const override { return EConstraintSubType::SwingTwist; }
virtual void NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inDeltaCOM) override;
virtual void SetupVelocityConstraint(float inDeltaTime) override;
virtual void WarmStartVelocityConstraint(float inWarmStartImpulseRatio) override;
virtual bool SolveVelocityConstraint(float inDeltaTime) override;
Expand Down
1 change: 1 addition & 0 deletions Jolt/Physics/Vehicle/VehicleConstraint.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ class VehicleConstraint : public Constraint, public PhysicsStepListener

// Generic interface of a constraint
virtual bool IsActive() const override { return mIsActive && Constraint::IsActive(); }
virtual void NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inDeltaCOM) override { /* Do nothing */ }
virtual void SetupVelocityConstraint(float inDeltaTime) override;
virtual void WarmStartVelocityConstraint(float inWarmStartImpulseRatio) override;
virtual bool SolveVelocityConstraint(float inDeltaTime) override;
Expand Down
2 changes: 2 additions & 0 deletions Samples/Samples.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ set(SAMPLES_SRC_FILES
${SAMPLES_ROOT}/Tests/Constraints/ConeConstraintTest.h
${SAMPLES_ROOT}/Tests/Constraints/ConstraintSingularityTest.cpp
${SAMPLES_ROOT}/Tests/Constraints/ConstraintSingularityTest.h
${SAMPLES_ROOT}/Tests/Constraints/ConstraintVsCOMChangeTest.cpp
${SAMPLES_ROOT}/Tests/Constraints/ConstraintVsCOMChangeTest.h
${SAMPLES_ROOT}/Tests/Constraints/DistanceConstraintTest.cpp
${SAMPLES_ROOT}/Tests/Constraints/DistanceConstraintTest.h
${SAMPLES_ROOT}/Tests/Constraints/FixedConstraintTest.cpp
Expand Down
2 changes: 2 additions & 0 deletions Samples/SamplesApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ JPH_DECLARE_RTTI_FOR_FACTORY(PathConstraintTest)
JPH_DECLARE_RTTI_FOR_FACTORY(RackAndPinionConstraintTest)
JPH_DECLARE_RTTI_FOR_FACTORY(GearConstraintTest)
JPH_DECLARE_RTTI_FOR_FACTORY(PulleyConstraintTest)
JPH_DECLARE_RTTI_FOR_FACTORY(ConstraintVsCOMChangeTest)

static TestNameAndRTTI sConstraintTests[] =
{
Expand All @@ -170,6 +171,7 @@ static TestNameAndRTTI sConstraintTests[] =
{ "Pulley Constraint", JPH_RTTI(PulleyConstraintTest) },
{ "Spring", JPH_RTTI(SpringTest) },
{ "Constraint Singularity", JPH_RTTI(ConstraintSingularityTest) },
{ "Constraint vs Center Of Mass Change",JPH_RTTI(ConstraintVsCOMChangeTest) },
};

JPH_DECLARE_RTTI_FOR_FACTORY(BoxShapeTest)
Expand Down
Loading

0 comments on commit a37d60e

Please sign in to comment.