Fixed bug where intertia tensors were not reset when unlocking axes

This commit is contained in:
Diren D Bharwani 2022-12-16 02:02:20 +08:00
parent 27760a95c9
commit 6b8232ae91
5 changed files with 74 additions and 11 deletions

View File

@ -11,7 +11,7 @@
RigidBody Component: RigidBody Component:
Type: Dynamic Type: Dynamic
Auto Mass: false Auto Mass: false
Mass: 1 Mass: 10
Drag: 1 Drag: 1
Angular Drag: 1 Angular Drag: 1
Use Gravity: false Use Gravity: false

View File

@ -83,8 +83,8 @@ public class PhysicsTestObj : Script
if (Input.GetKeyDown(moveInputKeys[i])) if (Input.GetKeyDown(moveInputKeys[i]))
move[i] = true; move[i] = true;
//if (Input.GetKeyDown(rotateInputKeys[i])) if (Input.GetKeyDown(rotateInputKeys[i]))
// rotate[i] = true; rotate[i] = true;
} }
} }
@ -97,8 +97,9 @@ public class PhysicsTestObj : Script
if (shouldMove) if (shouldMove)
{ {
Vector3 offset = new Vector3(0.25f, 0.0f, 0.0f); //Vector3 offset = new Vector3(0.25f, 0.0f, 0.0f);
rb.AddForceAtLocalPos(moveVec[i] * forceAmount, offset); //rb.AddForceAtLocalPos(moveVec[i] * forceAmount, offset);
rb.AddForce(moveVec[i] * forceAmount);
move[i] = false; move[i] = false;
} }

View File

@ -511,11 +511,12 @@ namespace SHADE
// Reset angular velocity along X-axis // Reset angular velocity along X-axis
angularVelocity.x = 0.0f; angularVelocity.x = 0.0f;
// Set inertia tensor on the x-axis to 0 // Set inertia tensor on the x-axis to 0
localInvInertia.m[0][0] = worldInvInertia.m[0][0] = 0.0f; localInvInertia.m[0][0] = 0.0f;
} }
else else
{ {
flags &= ~VALUE; flags &= ~VALUE;
computeInertiaTensor();
} }
} }
@ -530,11 +531,12 @@ namespace SHADE
// Reset angular velocity along Y-axis // Reset angular velocity along Y-axis
angularVelocity.y = 0.0f; angularVelocity.y = 0.0f;
// Set inertia tensor on the y-axis to 0 // Set inertia tensor on the y-axis to 0
localInvInertia.m[1][1] = worldInvInertia.m[1][1] = 0.0f; localInvInertia.m[1][1] = 0.0f;
} }
else else
{ {
flags &= ~VALUE; flags &= ~VALUE;
computeInertiaTensor();
} }
} }
@ -549,11 +551,12 @@ namespace SHADE
// Reset angular velocity along Z-axis // Reset angular velocity along Z-axis
angularVelocity.z = 0.0f; angularVelocity.z = 0.0f;
// Set inertia tensor on the z-axis to 0 // Set inertia tensor on the z-axis to 0
localInvInertia.m[2][2] = worldInvInertia.m[2][2] = 0.0f; localInvInertia.m[2][2] = 0.0f;
} }
else else
{ {
flags &= ~VALUE; flags &= ~VALUE;
computeInertiaTensor();
} }
} }
@ -606,20 +609,59 @@ namespace SHADE
void SHRigidBody::ComputeMassData() noexcept void SHRigidBody::ComputeMassData() noexcept
{ {
// TODO: Compute total inertia and centroid from composited colliders using the Parallel Axis Theorem. computeCentroid();
computeMassAndInertiaTensor();
}
/*-----------------------------------------------------------------------------------*/
/* Private Member Function Definition */
/*-----------------------------------------------------------------------------------*/
void SHRigidBody::computeCentroid() noexcept
{
// TODO
}
void SHRigidBody::computeMass() noexcept
{
// TODO: If auto mass in enabled, compute total mass based from each collider. // TODO: If auto mass in enabled, compute total mass based from each collider.
// TODO: If auto mass disabled, compute inertia tensor for each shape using the ratio of its mass / total mass by comparing the volume / total volume. // TODO: If auto mass disabled, compute inertia tensor for each shape using the ratio of its mass / total mass by comparing the volume / total volume.
}
if (collider && !collider->GetCollisionShapes().empty()) void SHRigidBody::computeInertiaTensor() noexcept
{
// TODO: Compute total inertia from composited colliders using the Parallel Axis Theorem.
if (!collider || collider->GetCollisionShapes().empty())
{
localInvInertia.m[0][0] = localInvInertia.m[1][1] = localInvInertia.m[2][2] = invMass;
}
else
{ {
// HACK: For now, take only the first shape as we are testing with non-composited colliders. We are using the center as the centroid. // HACK: For now, take only the first shape as we are testing with non-composited colliders. We are using the center as the centroid.
const auto* FIRST_SHAPE = collider->GetCollisionShape(0); const auto* FIRST_SHAPE = collider->GetCollisionShape(0);
localInvInertia = SHMatrix::Inverse(FIRST_SHAPE->GetInertiaTensor(1.0f / invMass)); localInvInertia = SHMatrix::Inverse(FIRST_SHAPE->GetInertiaTensor(1.0f / invMass));
} }
else }
void SHRigidBody::computeMassAndInertiaTensor() noexcept
{
// TODO: If auto mass in enabled, compute total mass based from each collider.
// TODO: If auto mass disabled, compute inertia tensor for each shape using the ratio of its mass / total mass by comparing the volume / total volume.
// TODO: Compute total inertia from composited colliders using the Parallel Axis Theorem.
if (!collider || collider->GetCollisionShapes().empty())
{ {
localInvInertia.m[0][0] = localInvInertia.m[1][1] = localInvInertia.m[2][2] = invMass; localInvInertia.m[0][0] = localInvInertia.m[1][1] = localInvInertia.m[2][2] = invMass;
} }
else
{
// HACK: For now, take only the first shape as we are testing with non-composited colliders. We are using the center as the centroid.
const auto* FIRST_SHAPE = collider->GetCollisionShape(0);
localInvInertia = SHMatrix::Inverse(FIRST_SHAPE->GetInertiaTensor(1.0f / invMass));
}
} }
} // namespace SHADE } // namespace SHADE

View File

@ -252,6 +252,16 @@ namespace SHADE
uint16_t flags; uint16_t flags;
SHMotionState motionState; SHMotionState motionState;
/*-----------------------------------------------------------------------------------*/
/* Member Functions */
/*-----------------------------------------------------------------------------------*/
void computeCentroid () noexcept;
void computeMass () noexcept;
void computeInertiaTensor () noexcept;
void computeMassAndInertiaTensor() noexcept;
}; };
} // namespace SHADE } // namespace SHADE

View File

@ -92,8 +92,12 @@ namespace SHADE
// Link with collider if it exists // Link with collider if it exists
if (collider) if (collider)
{
collider->SetRigidBody(rigidBody); collider->SetRigidBody(rigidBody);
rigidBody->SetCollider(collider);
}
rigidBody->ComputeMassData();
return rigidBody; return rigidBody;
} }
@ -119,7 +123,10 @@ namespace SHADE
// Link with rigidBody if it exists // Link with rigidBody if it exists
if (rigidBody) if (rigidBody)
{
rigidBody->SetCollider(collider); rigidBody->SetCollider(collider);
collider->SetRigidBody(rigidBody);
}
return collider; return collider;
} }
@ -131,7 +138,10 @@ namespace SHADE
// Unlink with rigid body // Unlink with rigid body
if (rigidBody) if (rigidBody)
{
rigidBody->SetCollider(nullptr); rigidBody->SetCollider(nullptr);
rigidBody->ComputeMassData();
}
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/