Browse Source

When changing axis from free to limited, reset warm starting (#815)

This avoids sudden impulses being applied when switching mode.
Jorrit Rouwe 1 year ago
parent
commit
093bd2f807

+ 17 - 0
Jolt/Physics/Constraints/SixDOFConstraint.cpp

@@ -120,6 +120,9 @@ void SixDOFConstraint::UpdateRotationLimits()
 
 void SixDOFConstraint::UpdateFixedFreeAxis()
 {
+	uint8 old_free_axis = mFreeAxis;
+	uint8 old_fixed_axis = mFixedAxis;
+
 	// Cache which axis are fixed and which ones are free
 	mFreeAxis = 0;
 	mFixedAxis = 0;
@@ -132,6 +135,20 @@ void SixDOFConstraint::UpdateFixedFreeAxis()
 		else if (mLimitMin[a] <= -limit && mLimitMax[a] >= limit)
 			mFreeAxis |= 1 << a;
 	}
+
+	// On change we deactivate all constraints to reset warm starting
+	if (old_free_axis != mFreeAxis || old_fixed_axis != mFixedAxis)
+	{
+		for (AxisConstraintPart &c : mTranslationConstraintPart)
+			c.Deactivate();
+		mPointConstraintPart.Deactivate();
+		mSwingTwistConstraintPart.Deactivate();
+		mRotationConstraintPart.Deactivate();
+		for (AxisConstraintPart &c : mMotorTranslationConstraintPart)
+			c.Deactivate();
+		for (AngleConstraintPart &c : mMotorRotationConstraintPart)
+			c.Deactivate();
+	}	
 }
 
 SixDOFConstraint::SixDOFConstraint(Body &inBody1, Body &inBody2, const SixDOFConstraintSettings &inSettings) :

+ 2 - 2
Jolt/Physics/Constraints/SixDOFConstraint.h

@@ -240,8 +240,8 @@ private:
 	Quat						mConstraintToBody2;
 
 	// Limits
-	uint8						mFreeAxis;													// Bitmask of free axis (bit 0 = TranslationX)
-	uint8						mFixedAxis;													// Bitmask of fixed axis (bit 0 = TranslationX)
+	uint8						mFreeAxis = 0;												// Bitmask of free axis (bit 0 = TranslationX)
+	uint8						mFixedAxis = 0;												// Bitmask of fixed axis (bit 0 = TranslationX)
 	bool						mTranslationMotorActive = false;							// If any of the translational frictions / motors are active
 	bool						mRotationMotorActive = false;								// If any of the rotational frictions / motors are active
 	uint8						mRotationPositionMotorActive = 0;							// Bitmask of axis that have position motor active (bit 0 = RotationX)