Make sure we do not recompute automatically center of mass and inertia tensor when they are set by the user

This commit is contained in:
Daniel Chappuis 2018-01-21 13:11:11 +01:00
parent c7f7a169f8
commit 010d7876ef
2 changed files with 72 additions and 40 deletions

View File

@ -42,7 +42,7 @@ RigidBody::RigidBody(const Transform& transform, CollisionWorld& world, bodyinde
: CollisionBody(transform, world, id), mArrayIndex(0), mInitMass(decimal(1.0)), : CollisionBody(transform, world, id), mArrayIndex(0), mInitMass(decimal(1.0)),
mCenterOfMassLocal(0, 0, 0), mCenterOfMassWorld(transform.getPosition()), mCenterOfMassLocal(0, 0, 0), mCenterOfMassWorld(transform.getPosition()),
mIsGravityEnabled(true), mLinearDamping(decimal(0.0)), mAngularDamping(decimal(0.0)), mIsGravityEnabled(true), mLinearDamping(decimal(0.0)), mAngularDamping(decimal(0.0)),
mJointsList(nullptr) { mJointsList(nullptr), mIsCenterOfMassSetByUser(false), mIsInertiaTensorSetByUser(false) {
// Compute the inverse mass // Compute the inverse mass
mMassInverse = decimal(1.0) / mInitMass; mMassInverse = decimal(1.0) / mInitMass;
@ -93,15 +93,17 @@ void RigidBody::setType(BodyType type) {
mMassInverse = decimal(0.0); mMassInverse = decimal(0.0);
mInertiaTensorLocalInverse.setToZero(); mInertiaTensorLocalInverse.setToZero();
mInertiaTensorInverseWorld.setToZero(); mInertiaTensorInverseWorld.setToZero();
} }
else { // If it is a dynamic body else { // If it is a dynamic body
mMassInverse = decimal(1.0) / mInitMass; mMassInverse = decimal(1.0) / mInitMass;
if (mIsInertiaTensorSetByUser) {
mInertiaTensorLocalInverse = mUserInertiaTensorLocalInverse; mInertiaTensorLocalInverse = mUserInertiaTensorLocalInverse;
}
}
// Update the world inverse inertia tensor // Update the world inverse inertia tensor
updateInertiaTensorInverseWorld(); updateInertiaTensorInverseWorld();
}
// Awake the body // Awake the body
setIsSleeping(false); setIsSleeping(false);
@ -119,6 +121,8 @@ void RigidBody::setType(BodyType type) {
} }
// Set the local inertia tensor of the body (in local-space coordinates) // Set the local inertia tensor of the body (in local-space coordinates)
/// If the inertia tensor is set with this method, it will not be computed
/// using the collision shapes of the body.
/** /**
* @param inertiaTensorLocal The 3x3 inertia tensor matrix of the body in local-space * @param inertiaTensorLocal The 3x3 inertia tensor matrix of the body in local-space
* coordinates * coordinates
@ -126,6 +130,7 @@ void RigidBody::setType(BodyType type) {
void RigidBody::setInertiaTensorLocal(const Matrix3x3& inertiaTensorLocal) { void RigidBody::setInertiaTensorLocal(const Matrix3x3& inertiaTensorLocal) {
mUserInertiaTensorLocalInverse = inertiaTensorLocal.getInverse(); mUserInertiaTensorLocalInverse = inertiaTensorLocal.getInverse();
mIsInertiaTensorSetByUser = true;
if (mType != BodyType::DYNAMIC) return; if (mType != BodyType::DYNAMIC) return;
@ -136,10 +141,17 @@ void RigidBody::setInertiaTensorLocal(const Matrix3x3& inertiaTensorLocal) {
updateInertiaTensorInverseWorld(); updateInertiaTensorInverseWorld();
} }
// Set the inverse local inertia tensor of the body (in body coordinates) // Set the inverse local inertia tensor of the body (in local-space coordinates)
/// If the inverse inertia tensor is set with this method, it will not be computed
/// using the collision shapes of the body.
/**
* @param inverseInertiaTensorLocal The 3x3 inverse inertia tensor matrix of the body in local-space
* coordinates
*/
void RigidBody::setInverseInertiaTensorLocal(const Matrix3x3& inverseInertiaTensorLocal) { void RigidBody::setInverseInertiaTensorLocal(const Matrix3x3& inverseInertiaTensorLocal) {
mUserInertiaTensorLocalInverse = inverseInertiaTensorLocal; mUserInertiaTensorLocalInverse = inverseInertiaTensorLocal;
mIsInertiaTensorSetByUser = true;
if (mType != BodyType::DYNAMIC) return; if (mType != BodyType::DYNAMIC) return;
@ -151,6 +163,8 @@ void RigidBody::setInverseInertiaTensorLocal(const Matrix3x3& inverseInertiaTens
} }
// Set the local center of mass of the body (in local-space coordinates) // Set the local center of mass of the body (in local-space coordinates)
/// If you set the center of mass with the method, it will not be computed
/// automatically using collision shapes.
/** /**
* @param centerOfMassLocal The center of mass of the body in local-space * @param centerOfMassLocal The center of mass of the body in local-space
* coordinates * coordinates
@ -159,6 +173,8 @@ void RigidBody::setCenterOfMassLocal(const Vector3& centerOfMassLocal) {
if (mType != BodyType::DYNAMIC) return; if (mType != BodyType::DYNAMIC) return;
mIsCenterOfMassSetByUser = true;
const Vector3 oldCenterOfMass = mCenterOfMassWorld; const Vector3 oldCenterOfMass = mCenterOfMassWorld;
mCenterOfMassLocal = centerOfMassLocal; mCenterOfMassLocal = centerOfMassLocal;
@ -359,9 +375,9 @@ void RigidBody::recomputeMassInformation() {
mInitMass = decimal(0.0); mInitMass = decimal(0.0);
mMassInverse = decimal(0.0); mMassInverse = decimal(0.0);
mInertiaTensorLocalInverse.setToZero(); if (!mIsInertiaTensorSetByUser) mInertiaTensorLocalInverse.setToZero();
mInertiaTensorInverseWorld.setToZero(); if (!mIsInertiaTensorSetByUser) mInertiaTensorInverseWorld.setToZero();
mCenterOfMassLocal.setToZero(); if (!mIsCenterOfMassSetByUser) mCenterOfMassLocal.setToZero();
Matrix3x3 inertiaTensorLocal; Matrix3x3 inertiaTensorLocal;
inertiaTensorLocal.setToZero(); inertiaTensorLocal.setToZero();
@ -376,8 +392,11 @@ void RigidBody::recomputeMassInformation() {
// Compute the total mass of the body // Compute the total mass of the body
for (ProxyShape* shape = mProxyCollisionShapes; shape != nullptr; shape = shape->mNext) { for (ProxyShape* shape = mProxyCollisionShapes; shape != nullptr; shape = shape->mNext) {
mInitMass += shape->getMass(); mInitMass += shape->getMass();
if (!mIsCenterOfMassSetByUser) {
mCenterOfMassLocal += shape->getLocalToBodyTransform().getPosition() * shape->getMass(); mCenterOfMassLocal += shape->getLocalToBodyTransform().getPosition() * shape->getMass();
} }
}
if (mInitMass > decimal(0.0)) { if (mInitMass > decimal(0.0)) {
mMassInverse = decimal(1.0) / mInitMass; mMassInverse = decimal(1.0) / mInitMass;
@ -389,10 +408,16 @@ void RigidBody::recomputeMassInformation() {
// Compute the center of mass // Compute the center of mass
const Vector3 oldCenterOfMass = mCenterOfMassWorld; const Vector3 oldCenterOfMass = mCenterOfMassWorld;
if (!mIsCenterOfMassSetByUser) {
mCenterOfMassLocal *= mMassInverse; mCenterOfMassLocal *= mMassInverse;
}
mCenterOfMassWorld = mTransform * mCenterOfMassLocal; mCenterOfMassWorld = mTransform * mCenterOfMassLocal;
// Compute the total mass and inertia tensor using all the collision shapes if (!mIsInertiaTensorSetByUser) {
// Compute the inertia tensor using all the collision shapes
for (ProxyShape* shape = mProxyCollisionShapes; shape != nullptr; shape = shape->mNext) { for (ProxyShape* shape = mProxyCollisionShapes; shape != nullptr; shape = shape->mNext) {
// Get the inertia tensor of the collision shape in its local-space // Get the inertia tensor of the collision shape in its local-space
@ -422,6 +447,7 @@ void RigidBody::recomputeMassInformation() {
// Compute the local inverse inertia tensor // Compute the local inverse inertia tensor
mInertiaTensorLocalInverse = inertiaTensorLocal.getInverse(); mInertiaTensorLocalInverse = inertiaTensorLocal.getInverse();
}
// Update the world inverse inertia tensor // Update the world inverse inertia tensor
updateInertiaTensorInverseWorld(); updateInertiaTensorInverseWorld();

View File

@ -109,6 +109,12 @@ class RigidBody : public CollisionBody {
/// First element of the linked list of joints involving this body /// First element of the linked list of joints involving this body
JointListElement* mJointsList; JointListElement* mJointsList;
/// True if the center of mass is set by the user
bool mIsCenterOfMassSetByUser;
/// True if the inertia tensor is set by the user
bool mIsInertiaTensorSetByUser;
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Remove a joint from the joints list /// Remove a joint from the joints list