|
@@ -9,7 +9,7 @@
|
|
|
|
|
|
TEST_SUITE("OffsetCenterOfMassShapeTests")
|
|
TEST_SUITE("OffsetCenterOfMassShapeTests")
|
|
{
|
|
{
|
|
- TEST_CASE("TestAngularImpulseCOMZero")
|
|
|
|
|
|
+ TEST_CASE("TestAddAngularImpulseCOMZero")
|
|
{
|
|
{
|
|
PhysicsTestContext c;
|
|
PhysicsTestContext c;
|
|
c.ZeroGravity();
|
|
c.ZeroGravity();
|
|
@@ -32,7 +32,9 @@ TEST_SUITE("OffsetCenterOfMassShapeTests")
|
|
|
|
|
|
// Add impulse
|
|
// Add impulse
|
|
Vec3 cImpulse(0, 10000, 0);
|
|
Vec3 cImpulse(0, 10000, 0);
|
|
- body.AddAngularImpulse(cImpulse);
|
|
|
|
|
|
+ CHECK(!body.IsActive());
|
|
|
|
+ c.GetBodyInterface().AddAngularImpulse(body.GetID(), cImpulse);
|
|
|
|
+ CHECK(body.IsActive());
|
|
|
|
|
|
// Check resulting velocity change
|
|
// Check resulting velocity change
|
|
// dv = I^-1 * L
|
|
// dv = I^-1 * L
|
|
@@ -41,7 +43,7 @@ TEST_SUITE("OffsetCenterOfMassShapeTests")
|
|
CHECK_APPROX_EQUAL(body.GetAngularVelocity(), Vec3(0, delta_v, 0));
|
|
CHECK_APPROX_EQUAL(body.GetAngularVelocity(), Vec3(0, delta_v, 0));
|
|
}
|
|
}
|
|
|
|
|
|
- TEST_CASE("TestAngularImpulseCOMOffset")
|
|
|
|
|
|
+ TEST_CASE("TestAddAngularImpulseCOMOffset")
|
|
{
|
|
{
|
|
PhysicsTestContext c;
|
|
PhysicsTestContext c;
|
|
c.ZeroGravity();
|
|
c.ZeroGravity();
|
|
@@ -65,7 +67,9 @@ TEST_SUITE("OffsetCenterOfMassShapeTests")
|
|
|
|
|
|
// Add impulse
|
|
// Add impulse
|
|
Vec3 cImpulse(0, 10000, 0);
|
|
Vec3 cImpulse(0, 10000, 0);
|
|
- body.AddAngularImpulse(cImpulse);
|
|
|
|
|
|
+ CHECK(!body.IsActive());
|
|
|
|
+ c.GetBodyInterface().AddAngularImpulse(body.GetID(), cImpulse);
|
|
|
|
+ CHECK(body.IsActive());
|
|
|
|
|
|
// Check resulting velocity change
|
|
// Check resulting velocity change
|
|
// dv = I^-1 * L
|
|
// dv = I^-1 * L
|
|
@@ -73,4 +77,77 @@ TEST_SUITE("OffsetCenterOfMassShapeTests")
|
|
CHECK_APPROX_EQUAL(body.GetLinearVelocity(), Vec3::sZero());
|
|
CHECK_APPROX_EQUAL(body.GetLinearVelocity(), Vec3::sZero());
|
|
CHECK_APPROX_EQUAL(body.GetAngularVelocity(), Vec3(0, delta_v, 0));
|
|
CHECK_APPROX_EQUAL(body.GetAngularVelocity(), Vec3(0, delta_v, 0));
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ TEST_CASE("TestAddTorqueCOMZero")
|
|
|
|
+ {
|
|
|
|
+ PhysicsTestContext c;
|
|
|
|
+ c.ZeroGravity();
|
|
|
|
+
|
|
|
|
+ // Create box
|
|
|
|
+ const Vec3 cHalfExtent = Vec3(0.5f, 1.0f, 1.5f);
|
|
|
|
+ BoxShapeSettings box(cHalfExtent);
|
|
|
|
+ box.SetEmbedded();
|
|
|
|
+
|
|
|
|
+ // Create body with COM offset 0
|
|
|
|
+ OffsetCenterOfMassShapeSettings com(Vec3::sZero(), &box);
|
|
|
|
+ com.SetEmbedded();
|
|
|
|
+ Body &body = c.CreateBody(&com, RVec3::sZero(), Quat::sIdentity(), EMotionType::Dynamic, EMotionQuality::Discrete, Layers::MOVING, EActivation::DontActivate);
|
|
|
|
+
|
|
|
|
+ // Check mass and inertia calculated correctly
|
|
|
|
+ float mass = (8.0f * cHalfExtent.GetX() * cHalfExtent.GetY() * cHalfExtent.GetZ()) * box.mDensity;
|
|
|
|
+ CHECK_APPROX_EQUAL(body.GetMotionProperties()->GetInverseMass(), 1.0f / mass);
|
|
|
|
+ float inertia_y = mass / 12.0f * (Square(2.0f * cHalfExtent.GetX()) + Square(2.0f * cHalfExtent.GetZ())); // See: https://en.wikipedia.org/wiki/List_of_moments_of_inertia
|
|
|
|
+ CHECK_APPROX_EQUAL(body.GetMotionProperties()->GetInverseInertiaForRotation(Mat44::sIdentity())(1, 1), 1.0f / inertia_y);
|
|
|
|
+
|
|
|
|
+ // Add torque
|
|
|
|
+ Vec3 cTorque(0, 100000, 0);
|
|
|
|
+ CHECK(!body.IsActive());
|
|
|
|
+ c.GetBodyInterface().AddTorque(body.GetID(), cTorque);
|
|
|
|
+ CHECK(body.IsActive());
|
|
|
|
+ CHECK(body.GetAngularVelocity() == Vec3::sZero()); // Angular velocity change should come after the next time step
|
|
|
|
+ c.SimulateSingleStep();
|
|
|
|
+
|
|
|
|
+ // Check resulting velocity change
|
|
|
|
+ // dv = I^-1 * T * dt
|
|
|
|
+ float delta_v = (1.0f / inertia_y) * cTorque.GetY() * c.GetDeltaTime();
|
|
|
|
+ CHECK_APPROX_EQUAL(body.GetLinearVelocity(), Vec3::sZero());
|
|
|
|
+ CHECK_APPROX_EQUAL(body.GetAngularVelocity(), Vec3(0, delta_v, 0));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ TEST_CASE("TestAddTorqueCOMOffset")
|
|
|
|
+ {
|
|
|
|
+ PhysicsTestContext c;
|
|
|
|
+ c.ZeroGravity();
|
|
|
|
+
|
|
|
|
+ // Create box
|
|
|
|
+ const Vec3 cHalfExtent = Vec3(0.5f, 1.0f, 1.5f);
|
|
|
|
+ BoxShapeSettings box(cHalfExtent);
|
|
|
|
+ box.SetEmbedded();
|
|
|
|
+
|
|
|
|
+ // Create body with COM offset
|
|
|
|
+ const Vec3 cCOMOffset(5.0f, 0, 0);
|
|
|
|
+ OffsetCenterOfMassShapeSettings com(cCOMOffset, &box);
|
|
|
|
+ com.SetEmbedded();
|
|
|
|
+ Body &body = c.CreateBody(&com, RVec3::sZero(), Quat::sIdentity(), EMotionType::Dynamic, EMotionQuality::Discrete, Layers::MOVING, EActivation::DontActivate);
|
|
|
|
+
|
|
|
|
+ // Check mass and inertia calculated correctly
|
|
|
|
+ float mass = (8.0f * cHalfExtent.GetX() * cHalfExtent.GetY() * cHalfExtent.GetZ()) * box.mDensity;
|
|
|
|
+ CHECK_APPROX_EQUAL(body.GetMotionProperties()->GetInverseMass(), 1.0f / mass);
|
|
|
|
+ float inertia_y = mass / 12.0f * (Square(2.0f * cHalfExtent.GetX()) + Square(2.0f * cHalfExtent.GetZ())) + mass * Square(cCOMOffset.GetX()); // See: https://en.wikipedia.org/wiki/List_of_moments_of_inertia & https://en.wikipedia.org/wiki/Parallel_axis_theorem
|
|
|
|
+ CHECK_APPROX_EQUAL(body.GetMotionProperties()->GetInverseInertiaForRotation(Mat44::sIdentity())(1, 1), 1.0f / inertia_y);
|
|
|
|
+
|
|
|
|
+ // Add torque
|
|
|
|
+ Vec3 cTorque(0, 100000, 0);
|
|
|
|
+ CHECK(!body.IsActive());
|
|
|
|
+ c.GetBodyInterface().AddTorque(body.GetID(), cTorque);
|
|
|
|
+ CHECK(body.IsActive());
|
|
|
|
+ CHECK(body.GetAngularVelocity() == Vec3::sZero()); // Angular velocity change should come after the next time step
|
|
|
|
+ c.SimulateSingleStep();
|
|
|
|
+
|
|
|
|
+ // Check resulting velocity change
|
|
|
|
+ // dv = I^-1 * T * dt
|
|
|
|
+ float delta_v = (1.0f / inertia_y) * cTorque.GetY() * c.GetDeltaTime();
|
|
|
|
+ CHECK_APPROX_EQUAL(body.GetLinearVelocity(), Vec3::sZero());
|
|
|
|
+ CHECK_APPROX_EQUAL(body.GetAngularVelocity(), Vec3(0, delta_v, 0));
|
|
|
|
+ }
|
|
}
|
|
}
|