|
@@ -929,6 +929,59 @@ TEST_SUITE("PhysicsTests")
|
|
|
CHECK(contact_listener.Contains(LoggingContactListener::EType::Remove, sphere.GetID(), floor.GetID()));
|
|
|
}
|
|
|
|
|
|
+ TEST_CASE("TestPhysicsInsideSpeculativeContactDistanceNoHit")
|
|
|
+ {
|
|
|
+ PhysicsTestContext c(1.0f / 60.0f, 1, 1);
|
|
|
+ Body &floor = c.CreateFloor();
|
|
|
+ floor.SetRestitution(1.0f);
|
|
|
+ c.ZeroGravity();
|
|
|
+
|
|
|
+ // Turn off the minimum velocity for restitution, our velocity is lower than the default
|
|
|
+ PhysicsSettings settings = c.GetSystem()->GetPhysicsSettings();
|
|
|
+ settings.mMinVelocityForRestitution = 0.0f;
|
|
|
+ c.GetSystem()->SetPhysicsSettings(settings);
|
|
|
+
|
|
|
+ LoggingContactListener contact_listener;
|
|
|
+ c.GetSystem()->SetContactListener(&contact_listener);
|
|
|
+
|
|
|
+ // Create a sphere inside speculative contact distance from the ground
|
|
|
+ const float cSpeculativeContactDistance = c.GetSystem()->GetPhysicsSettings().mSpeculativeContactDistance;
|
|
|
+ const float cDistanceAboveFloor = 0.9f * cSpeculativeContactDistance;
|
|
|
+ const RVec3 cInitialPosSphere(0, 1.0f + cDistanceAboveFloor, 0.0f);
|
|
|
+
|
|
|
+ // Make it move slow enough so that it will not touch the floor in 1 time step
|
|
|
+ const Vec3 cVelocity(0, -0.9f * cDistanceAboveFloor / c.GetDeltaTime(), 0);
|
|
|
+
|
|
|
+ Body &sphere = c.CreateSphere(cInitialPosSphere, 1.0f, EMotionType::Dynamic, EMotionQuality::Discrete, Layers::MOVING);
|
|
|
+ sphere.SetLinearVelocity(cVelocity);
|
|
|
+ sphere.SetRestitution(1.0f);
|
|
|
+ sphere.GetMotionProperties()->SetLinearDamping(0.0f);
|
|
|
+
|
|
|
+ // Simulate a step
|
|
|
+ c.SimulateSingleStep();
|
|
|
+
|
|
|
+ // Check that it has triggered contact points from the speculative contacts
|
|
|
+ CHECK(contact_listener.GetEntryCount() == 2);
|
|
|
+ CHECK(contact_listener.Contains(LoggingContactListener::EType::Validate, sphere.GetID(), floor.GetID()));
|
|
|
+ CHECK(contact_listener.Contains(LoggingContactListener::EType::Add, sphere.GetID(), floor.GetID()));
|
|
|
+ contact_listener.Clear();
|
|
|
+
|
|
|
+ // Check that sphere didn't actually change velocity (it hasn't actually interacted with the floor, the speculative contact was not an actual contact)
|
|
|
+ CHECK(sphere.GetLinearVelocity() == cVelocity);
|
|
|
+
|
|
|
+ // Simulate a step
|
|
|
+ c.SimulateSingleStep();
|
|
|
+
|
|
|
+ // Check again that it triggered contact points
|
|
|
+ CHECK(contact_listener.GetEntryCount() == 2);
|
|
|
+ CHECK(contact_listener.Contains(LoggingContactListener::EType::Validate, sphere.GetID(), floor.GetID()));
|
|
|
+ CHECK(contact_listener.Contains(LoggingContactListener::EType::Persist, sphere.GetID(), floor.GetID()));
|
|
|
+ contact_listener.Clear();
|
|
|
+
|
|
|
+ // It should have bounced back up and inverted velocity due to restitution being 1
|
|
|
+ CHECK_APPROX_EQUAL(-sphere.GetLinearVelocity(), cVelocity);
|
|
|
+ }
|
|
|
+
|
|
|
TEST_CASE("TestPhysicsInsideSpeculativeContactDistanceMovingAway")
|
|
|
{
|
|
|
PhysicsTestContext c(1.0f / 60.0f, 1, 1);
|