12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
- // SPDX-License-Identifier: MIT
- #include "UnitTestFramework.h"
- #include "PhysicsTestContext.h"
- #include "Layers.h"
- #include <Jolt/Physics/Collision/Shape/BoxShape.h>
- #include <Jolt/Physics/Collision/Shape/OffsetCenterOfMassShape.h>
- TEST_SUITE("OffsetCenterOfMassShapeTests")
- {
- TEST_CASE("TestAngularImpulseCOMZero")
- {
- 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 impulse
- Vec3 cImpulse(0, 10000, 0);
- body.AddAngularImpulse(cImpulse);
- // Check resulting velocity change
- // dv = I^-1 * L
- float delta_v = (1.0f / inertia_y) * cImpulse.GetY();
- CHECK_APPROX_EQUAL(body.GetLinearVelocity(), Vec3::sZero());
- CHECK_APPROX_EQUAL(body.GetAngularVelocity(), Vec3(0, delta_v, 0));
- }
- TEST_CASE("TestAngularImpulseCOMOffset")
- {
- 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 impulse
- Vec3 cImpulse(0, 10000, 0);
- body.AddAngularImpulse(cImpulse);
- // Check resulting velocity change
- // dv = I^-1 * L
- float delta_v = (1.0f / inertia_y) * cImpulse.GetY();
- CHECK_APPROX_EQUAL(body.GetLinearVelocity(), Vec3::sZero());
- CHECK_APPROX_EQUAL(body.GetAngularVelocity(), Vec3(0, delta_v, 0));
- }
- }
|