|
@@ -32,7 +32,8 @@ TEST_SUITE("SliderConstraintTests")
|
|
|
|
|
|
// Create slider constraint
|
|
// Create slider constraint
|
|
SliderConstraintSettings s;
|
|
SliderConstraintSettings s;
|
|
- s.mSliderAxis = Vec3::sAxisX();
|
|
|
|
|
|
+ s.SetPoint(body1, body2);
|
|
|
|
+ s.SetSliderAxis(Vec3::sAxisX());
|
|
s.mLimitsMin = cLimitMin;
|
|
s.mLimitsMin = cLimitMin;
|
|
s.mLimitsMax = 0.0f;
|
|
s.mLimitsMax = 0.0f;
|
|
c.CreateConstraint<SliderConstraint>(body1, body2, s);
|
|
c.CreateConstraint<SliderConstraint>(body1, body2, s);
|
|
@@ -44,7 +45,7 @@ TEST_SUITE("SliderConstraintTests")
|
|
CHECK_APPROX_EQUAL(Vec3::sZero(), body2.GetLinearVelocity(), 1.0e-4f);
|
|
CHECK_APPROX_EQUAL(Vec3::sZero(), body2.GetLinearVelocity(), 1.0e-4f);
|
|
|
|
|
|
// Test resulting position
|
|
// Test resulting position
|
|
- CHECK_APPROX_EQUAL(cInitialPos + cLimitMin * s.mSliderAxis, body2.GetPosition(), 1.0e-4f);
|
|
|
|
|
|
+ CHECK_APPROX_EQUAL(cInitialPos + cLimitMin * s.mSliderAxis1, body2.GetPosition(), 1.0e-4f);
|
|
}
|
|
}
|
|
|
|
|
|
// Test a box attached to a slider constraint, test that the body doesn't move beyond the max limit
|
|
// Test a box attached to a slider constraint, test that the body doesn't move beyond the max limit
|
|
@@ -63,7 +64,8 @@ TEST_SUITE("SliderConstraintTests")
|
|
|
|
|
|
// Create slider constraint
|
|
// Create slider constraint
|
|
SliderConstraintSettings s;
|
|
SliderConstraintSettings s;
|
|
- s.mSliderAxis = Vec3::sAxisX();
|
|
|
|
|
|
+ s.SetPoint(body1, body2);
|
|
|
|
+ s.SetSliderAxis(Vec3::sAxisX());
|
|
s.mLimitsMin = 0.0f;
|
|
s.mLimitsMin = 0.0f;
|
|
s.mLimitsMax = cLimitMax;
|
|
s.mLimitsMax = cLimitMax;
|
|
c.CreateConstraint<SliderConstraint>(body1, body2, s);
|
|
c.CreateConstraint<SliderConstraint>(body1, body2, s);
|
|
@@ -75,7 +77,7 @@ TEST_SUITE("SliderConstraintTests")
|
|
CHECK_APPROX_EQUAL(Vec3::sZero(), body2.GetLinearVelocity(), 1.0e-4f);
|
|
CHECK_APPROX_EQUAL(Vec3::sZero(), body2.GetLinearVelocity(), 1.0e-4f);
|
|
|
|
|
|
// Test resulting position
|
|
// Test resulting position
|
|
- CHECK_APPROX_EQUAL(cInitialPos + cLimitMax * s.mSliderAxis, body2.GetPosition(), 1.0e-4f);
|
|
|
|
|
|
+ CHECK_APPROX_EQUAL(cInitialPos + cLimitMax * s.mSliderAxis1, body2.GetPosition(), 1.0e-4f);
|
|
}
|
|
}
|
|
|
|
|
|
// Test a box attached to a slider constraint, test that a motor can drive it to a specific velocity
|
|
// Test a box attached to a slider constraint, test that a motor can drive it to a specific velocity
|
|
@@ -91,7 +93,8 @@ TEST_SUITE("SliderConstraintTests")
|
|
|
|
|
|
// Create slider constraint
|
|
// Create slider constraint
|
|
SliderConstraintSettings s;
|
|
SliderConstraintSettings s;
|
|
- s.mSliderAxis = Vec3::sAxisX();
|
|
|
|
|
|
+ s.SetPoint(body1, body2);
|
|
|
|
+ s.SetSliderAxis(Vec3::sAxisX());
|
|
constexpr float mass = Cubed(2.0f) * 1000.0f; // Density * Volume
|
|
constexpr float mass = Cubed(2.0f) * 1000.0f; // Density * Volume
|
|
s.mMotorSettings = MotorSettings(0.0f, 0.0f, mass * cMotorAcceleration, 0.0f);
|
|
s.mMotorSettings = MotorSettings(0.0f, 0.0f, mass * cMotorAcceleration, 0.0f);
|
|
SliderConstraint &constraint = c.CreateConstraint<SliderConstraint>(body1, body2, s);
|
|
SliderConstraint &constraint = c.CreateConstraint<SliderConstraint>(body1, body2, s);
|
|
@@ -102,18 +105,18 @@ TEST_SUITE("SliderConstraintTests")
|
|
c.Simulate(1.0f);
|
|
c.Simulate(1.0f);
|
|
|
|
|
|
// Test resulting velocity
|
|
// Test resulting velocity
|
|
- Vec3 expected_vel = cMotorAcceleration * s.mSliderAxis;
|
|
|
|
|
|
+ Vec3 expected_vel = cMotorAcceleration * s.mSliderAxis1;
|
|
CHECK_APPROX_EQUAL(expected_vel, body2.GetLinearVelocity(), 1.0e-4f);
|
|
CHECK_APPROX_EQUAL(expected_vel, body2.GetLinearVelocity(), 1.0e-4f);
|
|
|
|
|
|
// Simulate (after 0.5 seconds it should reach the target velocity)
|
|
// Simulate (after 0.5 seconds it should reach the target velocity)
|
|
c.Simulate(1.0f);
|
|
c.Simulate(1.0f);
|
|
|
|
|
|
// Test resulting velocity
|
|
// Test resulting velocity
|
|
- expected_vel = 1.5f * cMotorAcceleration * s.mSliderAxis;
|
|
|
|
|
|
+ expected_vel = 1.5f * cMotorAcceleration * s.mSliderAxis1;
|
|
CHECK_APPROX_EQUAL(expected_vel, body2.GetLinearVelocity(), 1.0e-4f);
|
|
CHECK_APPROX_EQUAL(expected_vel, body2.GetLinearVelocity(), 1.0e-4f);
|
|
|
|
|
|
// Test resulting position (1.5s of acceleration + 0.5s of constant speed)
|
|
// Test resulting position (1.5s of acceleration + 0.5s of constant speed)
|
|
- Vec3 expected_pos = c.PredictPosition(cInitialPos, Vec3::sZero(), cMotorAcceleration * s.mSliderAxis, 1.5f) + 0.5f * expected_vel;
|
|
|
|
|
|
+ Vec3 expected_pos = c.PredictPosition(cInitialPos, Vec3::sZero(), cMotorAcceleration * s.mSliderAxis1, 1.5f) + 0.5f * expected_vel;
|
|
CHECK_APPROX_EQUAL(expected_pos, body2.GetPosition(), 1.0e-4f);
|
|
CHECK_APPROX_EQUAL(expected_pos, body2.GetPosition(), 1.0e-4f);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -131,7 +134,8 @@ TEST_SUITE("SliderConstraintTests")
|
|
|
|
|
|
// Create slider constraint
|
|
// Create slider constraint
|
|
SliderConstraintSettings s;
|
|
SliderConstraintSettings s;
|
|
- s.mSliderAxis = Vec3::sAxisX();
|
|
|
|
|
|
+ s.SetPoint(body1, body2);
|
|
|
|
+ s.SetSliderAxis(Vec3::sAxisX());
|
|
constexpr float mass = Cubed(2.0f) * 1000.0f; // Density * Volume
|
|
constexpr float mass = Cubed(2.0f) * 1000.0f; // Density * Volume
|
|
s.mMotorSettings = MotorSettings(0.0f, 0.0f, mass * cMotorAcceleration, 0.0f);
|
|
s.mMotorSettings = MotorSettings(0.0f, 0.0f, mass * cMotorAcceleration, 0.0f);
|
|
SliderConstraint &constraint = c.CreateConstraint<SliderConstraint>(body1, body2, s);
|
|
SliderConstraint &constraint = c.CreateConstraint<SliderConstraint>(body1, body2, s);
|
|
@@ -142,7 +146,7 @@ TEST_SUITE("SliderConstraintTests")
|
|
c.Simulate(1.0f);
|
|
c.Simulate(1.0f);
|
|
|
|
|
|
// Test resulting velocity (both boxes move in opposite directions with the same force, so the resulting velocity difference is 2x as big as the previous test)
|
|
// Test resulting velocity (both boxes move in opposite directions with the same force, so the resulting velocity difference is 2x as big as the previous test)
|
|
- Vec3 expected_vel = cMotorAcceleration * s.mSliderAxis;
|
|
|
|
|
|
+ Vec3 expected_vel = cMotorAcceleration * s.mSliderAxis1;
|
|
CHECK_APPROX_EQUAL(-expected_vel, body1.GetLinearVelocity(), 1.0e-4f);
|
|
CHECK_APPROX_EQUAL(-expected_vel, body1.GetLinearVelocity(), 1.0e-4f);
|
|
CHECK_APPROX_EQUAL(expected_vel, body2.GetLinearVelocity(), 1.0e-4f);
|
|
CHECK_APPROX_EQUAL(expected_vel, body2.GetLinearVelocity(), 1.0e-4f);
|
|
|
|
|
|
@@ -150,13 +154,13 @@ TEST_SUITE("SliderConstraintTests")
|
|
c.Simulate(1.0f);
|
|
c.Simulate(1.0f);
|
|
|
|
|
|
// Test resulting velocity
|
|
// Test resulting velocity
|
|
- expected_vel = 1.5f * cMotorAcceleration * s.mSliderAxis;
|
|
|
|
|
|
+ expected_vel = 1.5f * cMotorAcceleration * s.mSliderAxis1;
|
|
CHECK_APPROX_EQUAL(-expected_vel, body1.GetLinearVelocity(), 1.0e-4f);
|
|
CHECK_APPROX_EQUAL(-expected_vel, body1.GetLinearVelocity(), 1.0e-4f);
|
|
CHECK_APPROX_EQUAL(expected_vel, body2.GetLinearVelocity(), 1.0e-4f);
|
|
CHECK_APPROX_EQUAL(expected_vel, body2.GetLinearVelocity(), 1.0e-4f);
|
|
|
|
|
|
// Test resulting position (1.5s of acceleration + 0.5s of constant speed)
|
|
// Test resulting position (1.5s of acceleration + 0.5s of constant speed)
|
|
- Vec3 expected_pos1 = c.PredictPosition(Vec3::sZero(), Vec3::sZero(), -cMotorAcceleration * s.mSliderAxis, 1.5f) - 0.5f * expected_vel;
|
|
|
|
- Vec3 expected_pos2 = c.PredictPosition(cInitialPos, Vec3::sZero(), cMotorAcceleration * s.mSliderAxis, 1.5f) + 0.5f * expected_vel;
|
|
|
|
|
|
+ Vec3 expected_pos1 = c.PredictPosition(Vec3::sZero(), Vec3::sZero(), -cMotorAcceleration * s.mSliderAxis1, 1.5f) - 0.5f * expected_vel;
|
|
|
|
+ Vec3 expected_pos2 = c.PredictPosition(cInitialPos, Vec3::sZero(), cMotorAcceleration * s.mSliderAxis1, 1.5f) + 0.5f * expected_vel;
|
|
CHECK_APPROX_EQUAL(expected_pos1, body1.GetPosition(), 1.0e-4f);
|
|
CHECK_APPROX_EQUAL(expected_pos1, body1.GetPosition(), 1.0e-4f);
|
|
CHECK_APPROX_EQUAL(expected_pos2, body2.GetPosition(), 1.0e-4f);
|
|
CHECK_APPROX_EQUAL(expected_pos2, body2.GetPosition(), 1.0e-4f);
|
|
}
|
|
}
|
|
@@ -174,10 +178,11 @@ TEST_SUITE("SliderConstraintTests")
|
|
|
|
|
|
// Create slider constraint
|
|
// Create slider constraint
|
|
SliderConstraintSettings s;
|
|
SliderConstraintSettings s;
|
|
- s.mSliderAxis = Vec3::sAxisX();
|
|
|
|
|
|
+ s.SetPoint(body1, body2);
|
|
|
|
+ s.SetSliderAxis(Vec3::sAxisX());
|
|
SliderConstraint &constraint = c.CreateConstraint<SliderConstraint>(body1, body2, s);
|
|
SliderConstraint &constraint = c.CreateConstraint<SliderConstraint>(body1, body2, s);
|
|
constraint.SetMotorState(EMotorState::Position);
|
|
constraint.SetMotorState(EMotorState::Position);
|
|
- constraint.SetTargetPosition((cMotorPos - cInitialPos).Dot(s.mSliderAxis));
|
|
|
|
|
|
+ constraint.SetTargetPosition((cMotorPos - cInitialPos).Dot(s.mSliderAxis1));
|
|
|
|
|
|
// Simulate
|
|
// Simulate
|
|
c.Simulate(2.0f);
|
|
c.Simulate(2.0f);
|
|
@@ -205,7 +210,8 @@ TEST_SUITE("SliderConstraintTests")
|
|
|
|
|
|
// Create slider constraint
|
|
// Create slider constraint
|
|
SliderConstraintSettings s;
|
|
SliderConstraintSettings s;
|
|
- s.mSliderAxis = Vec3::sAxisX();
|
|
|
|
|
|
+ s.SetPoint(body1, body2);
|
|
|
|
+ s.SetSliderAxis(Vec3::sAxisX());
|
|
constexpr float mass = Cubed(2.0f) * 1000.0f; // Density * Volume
|
|
constexpr float mass = Cubed(2.0f) * 1000.0f; // Density * Volume
|
|
s.mMaxFrictionForce = mass * cFrictionAcceleration;
|
|
s.mMaxFrictionForce = mass * cFrictionAcceleration;
|
|
c.CreateConstraint<SliderConstraint>(body1, body2, s);
|
|
c.CreateConstraint<SliderConstraint>(body1, body2, s);
|
|
@@ -214,11 +220,11 @@ TEST_SUITE("SliderConstraintTests")
|
|
c.Simulate(cSimulationTime);
|
|
c.Simulate(cSimulationTime);
|
|
|
|
|
|
// Test resulting velocity
|
|
// Test resulting velocity
|
|
- Vec3 expected_vel = cInitialVelocity - cFrictionAcceleration * cSimulationTime * s.mSliderAxis;
|
|
|
|
|
|
+ Vec3 expected_vel = cInitialVelocity - cFrictionAcceleration * cSimulationTime * s.mSliderAxis1;
|
|
CHECK_APPROX_EQUAL(expected_vel, body2.GetLinearVelocity(), 1.0e-4f);
|
|
CHECK_APPROX_EQUAL(expected_vel, body2.GetLinearVelocity(), 1.0e-4f);
|
|
|
|
|
|
// Test resulting position
|
|
// Test resulting position
|
|
- Vec3 expected_pos = c.PredictPosition(cInitialPos, cInitialVelocity, -cFrictionAcceleration * s.mSliderAxis, cSimulationTime);
|
|
|
|
|
|
+ Vec3 expected_pos = c.PredictPosition(cInitialPos, cInitialVelocity, -cFrictionAcceleration * s.mSliderAxis1, cSimulationTime);
|
|
CHECK_APPROX_EQUAL(expected_pos, body2.GetPosition(), 1.0e-4f);
|
|
CHECK_APPROX_EQUAL(expected_pos, body2.GetPosition(), 1.0e-4f);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -232,7 +238,8 @@ TEST_SUITE("SliderConstraintTests")
|
|
|
|
|
|
// Create slider constraint
|
|
// Create slider constraint
|
|
SliderConstraintSettings s;
|
|
SliderConstraintSettings s;
|
|
- s.mSliderAxis = Vec3::sAxisX();
|
|
|
|
|
|
+ s.SetPoint(body1, body2);
|
|
|
|
+ s.SetSliderAxis(Vec3::sAxisX());
|
|
c.CreateConstraint<SliderConstraint>(body1, body2, s);
|
|
c.CreateConstraint<SliderConstraint>(body1, body2, s);
|
|
|
|
|
|
// Verify they're not active
|
|
// Verify they're not active
|
|
@@ -265,7 +272,8 @@ TEST_SUITE("SliderConstraintTests")
|
|
|
|
|
|
// Create slider constraint
|
|
// Create slider constraint
|
|
SliderConstraintSettings s;
|
|
SliderConstraintSettings s;
|
|
- s.mSliderAxis = Vec3::sAxisX();
|
|
|
|
|
|
+ s.SetPoint(body1, body2);
|
|
|
|
+ s.SetSliderAxis(Vec3::sAxisX());
|
|
c.CreateConstraint<SliderConstraint>(body1, body2, s);
|
|
c.CreateConstraint<SliderConstraint>(body1, body2, s);
|
|
|
|
|
|
// Verify they're not active
|
|
// Verify they're not active
|
|
@@ -298,7 +306,8 @@ TEST_SUITE("SliderConstraintTests")
|
|
|
|
|
|
// Create slider constraint
|
|
// Create slider constraint
|
|
SliderConstraintSettings s;
|
|
SliderConstraintSettings s;
|
|
- s.mSliderAxis = Vec3::sAxisX();
|
|
|
|
|
|
+ s.SetPoint(body1, body2);
|
|
|
|
+ s.SetSliderAxis(Vec3::sAxisX());
|
|
c.CreateConstraint<SliderConstraint>(body1, body2, s);
|
|
c.CreateConstraint<SliderConstraint>(body1, body2, s);
|
|
|
|
|
|
// Verify they're not active
|
|
// Verify they're not active
|
|
@@ -331,7 +340,8 @@ TEST_SUITE("SliderConstraintTests")
|
|
|
|
|
|
// Create slider constraint
|
|
// Create slider constraint
|
|
SliderConstraintSettings s;
|
|
SliderConstraintSettings s;
|
|
- s.mSliderAxis = Vec3::sAxisX();
|
|
|
|
|
|
+ s.SetPoint(body1, body2);
|
|
|
|
+ s.SetSliderAxis(Vec3::sAxisX());
|
|
c.CreateConstraint<SliderConstraint>(body1, body2, s);
|
|
c.CreateConstraint<SliderConstraint>(body1, body2, s);
|
|
|
|
|
|
// Verify they're not active
|
|
// Verify they're not active
|
|
@@ -364,7 +374,8 @@ TEST_SUITE("SliderConstraintTests")
|
|
|
|
|
|
// Create slider constraint
|
|
// Create slider constraint
|
|
SliderConstraintSettings s;
|
|
SliderConstraintSettings s;
|
|
- s.mSliderAxis = Vec3::sAxisX();
|
|
|
|
|
|
+ s.SetPoint(body1, body2);
|
|
|
|
+ s.SetSliderAxis(Vec3::sAxisX());
|
|
c.CreateConstraint<SliderConstraint>(body1, body2, s);
|
|
c.CreateConstraint<SliderConstraint>(body1, body2, s);
|
|
|
|
|
|
// Verify they're not active
|
|
// Verify they're not active
|
|
@@ -386,4 +397,48 @@ TEST_SUITE("SliderConstraintTests")
|
|
CHECK(body1.IsActive());
|
|
CHECK(body1.IsActive());
|
|
CHECK(body2.IsActive());
|
|
CHECK(body2.IsActive());
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ // Test that when a reference frame is provided, the slider constraint is correctly constructed
|
|
|
|
+ TEST_CASE("TestSliderReferenceFrame")
|
|
|
|
+ {
|
|
|
|
+ // Create two boxes in semi random position/orientation
|
|
|
|
+ PhysicsTestContext c;
|
|
|
|
+ Body &body1 = c.CreateBox(Vec3(1, 2, 3), Quat::sRotation(Vec3(1, 1, 1).Normalized(), 0.1f * JPH_PI), EMotionType::Dynamic, EMotionQuality::Discrete, Layers::MOVING, Vec3(1, 1, 1), EActivation::Activate);
|
|
|
|
+ Body &body2 = c.CreateBox(Vec3(-3, -2, -1), Quat::sRotation(Vec3(1, 0, 1).Normalized(), 0.2f * JPH_PI), EMotionType::Dynamic, EMotionQuality::Discrete, Layers::MOVING, Vec3(1, 1, 1), EActivation::Activate);
|
|
|
|
+
|
|
|
|
+ // Disable collision between the boxes
|
|
|
|
+ GroupFilterTable *group_filter = new GroupFilterTable(2);
|
|
|
|
+ group_filter->DisableCollision(0, 1);
|
|
|
|
+ body1.SetCollisionGroup(CollisionGroup(group_filter, 0, 0));
|
|
|
|
+ body2.SetCollisionGroup(CollisionGroup(group_filter, 0, 1));
|
|
|
|
+
|
|
|
|
+ // Get their transforms
|
|
|
|
+ Mat44 t1 = body1.GetCenterOfMassTransform();
|
|
|
|
+ Mat44 t2 = body2.GetCenterOfMassTransform();
|
|
|
|
+
|
|
|
|
+ // Create slider constraint so that slider connects the bodies at their center of mass and rotated XY -> YZ
|
|
|
|
+ SliderConstraintSettings s;
|
|
|
|
+ s.mPoint1 = t1.GetTranslation();
|
|
|
|
+ s.mSliderAxis1 = t1.GetColumn3(0);
|
|
|
|
+ s.mNormalAxis1 = t1.GetColumn3(1);
|
|
|
|
+ s.mPoint2 = t2.GetTranslation();
|
|
|
|
+ s.mSliderAxis2 = t2.GetColumn3(1);
|
|
|
|
+ s.mNormalAxis2 = t2.GetColumn3(2);
|
|
|
|
+ SliderConstraint &constraint = c.CreateConstraint<SliderConstraint>(body1, body2, s);
|
|
|
|
+
|
|
|
|
+ // Activate the motor to drive to 0
|
|
|
|
+ constraint.SetMotorState(EMotorState::Position);
|
|
|
|
+ constraint.SetTargetPosition(0);
|
|
|
|
+
|
|
|
|
+ // Simulate for a second
|
|
|
|
+ c.Simulate(1.0f);
|
|
|
|
+
|
|
|
|
+ // Now the bodies should have aligned so their COM is at the same position and they're rotated XY -> YZ
|
|
|
|
+ t1 = body1.GetCenterOfMassTransform();
|
|
|
|
+ t2 = body2.GetCenterOfMassTransform();
|
|
|
|
+ CHECK_APPROX_EQUAL(t1.GetColumn3(0), t2.GetColumn3(1), 1.0e-4f);
|
|
|
|
+ CHECK_APPROX_EQUAL(t1.GetColumn3(1), t2.GetColumn3(2), 1.0e-4f);
|
|
|
|
+ CHECK_APPROX_EQUAL(t1.GetColumn3(2), t2.GetColumn3(0), 1.0e-4f);
|
|
|
|
+ CHECK_APPROX_EQUAL(t1.GetTranslation(), t2.GetTranslation(), 1.0e-2f);
|
|
|
|
+ }
|
|
}
|
|
}
|