Fix issue with update of inverse mass/inertia of a static body

This commit is contained in:
Daniel Chappuis 2021-01-27 21:49:31 +01:00
parent c615555daa
commit b18e617c76
2 changed files with 75 additions and 43 deletions

View File

@ -36,6 +36,8 @@ do not hesitate to take a look at the user manual.
- Issue with edge vs edge collision has been fixed in SAT algorithm (wrong contact normal was computed)
- Issue with sphere radius in DebugRenderer
- Issue [#157](https://github.com/DanielChappuis/reactphysics3d/issues/157) with matrix to quaternion conversion has been fixed
- Issue [#184](https://github.com/DanielChappuis/reactphysics3d/issues/184) with update of mass/inertia properties of static bodies
## Version 0.8.0 (May 31, 2020)

View File

@ -208,11 +208,16 @@ void RigidBody::setLocalInertiaTensor(const Vector3& inertiaTensorLocal) {
mWorld.mRigidBodyComponents.setLocalInertiaTensor(mEntity, inertiaTensorLocal);
// Compute the inverse local inertia tensor
Vector3 inverseInertiaTensorLocal(inertiaTensorLocal.x != decimal(0.0) ? decimal(1.0) / inertiaTensorLocal.x : 0,
inertiaTensorLocal.y != decimal(0.0) ? decimal(1.0) / inertiaTensorLocal.y : 0,
inertiaTensorLocal.z != decimal(0.0) ? decimal(1.0) / inertiaTensorLocal.z : 0);
mWorld.mRigidBodyComponents.setInverseInertiaTensorLocal(mEntity, inverseInertiaTensorLocal);
// If it is a dynamic body
const BodyType type = mWorld.mRigidBodyComponents.getBodyType(mEntity);
if (type == BodyType::DYNAMIC) {
// Compute the inverse local inertia tensor
Vector3 inverseInertiaTensorLocal(inertiaTensorLocal.x != decimal(0.0) ? decimal(1.0) / inertiaTensorLocal.x : 0,
inertiaTensorLocal.y != decimal(0.0) ? decimal(1.0) / inertiaTensorLocal.y : 0,
inertiaTensorLocal.z != decimal(0.0) ? decimal(1.0) / inertiaTensorLocal.z : 0);
mWorld.mRigidBodyComponents.setInverseInertiaTensorLocal(mEntity, inverseInertiaTensorLocal);
}
RP3D_LOG(mWorld.mConfig.worldName, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set inertiaTensorLocal=" + inertiaTensorLocal.to_string(), __FILE__, __LINE__);
@ -412,11 +417,16 @@ void RigidBody::updateLocalInertiaTensorFromColliders() {
mWorld.mRigidBodyComponents.setLocalInertiaTensor(mEntity, inertiaTensorLocal);
// Compute the inverse local inertia tensor
Vector3 inverseInertiaTensorLocal(inertiaTensorLocal.x != decimal(0.0) ? decimal(1.0) / inertiaTensorLocal.x : 0,
inertiaTensorLocal.y != decimal(0.0) ? decimal(1.0) / inertiaTensorLocal.y : 0,
inertiaTensorLocal.z != decimal(0.0) ? decimal(1.0) / inertiaTensorLocal.z : 0);
mWorld.mRigidBodyComponents.setInverseInertiaTensorLocal(mEntity, inverseInertiaTensorLocal);
// If it is a dynamic body
const BodyType type = mWorld.mRigidBodyComponents.getBodyType(mEntity);
if (type == BodyType::DYNAMIC) {
// Compute the inverse local inertia tensor
Vector3 inverseInertiaTensorLocal(inertiaTensorLocal.x != decimal(0.0) ? decimal(1.0) / inertiaTensorLocal.x : 0,
inertiaTensorLocal.y != decimal(0.0) ? decimal(1.0) / inertiaTensorLocal.y : 0,
inertiaTensorLocal.z != decimal(0.0) ? decimal(1.0) / inertiaTensorLocal.z : 0);
mWorld.mRigidBodyComponents.setInverseInertiaTensorLocal(mEntity, inverseInertiaTensorLocal);
}
RP3D_LOG(mWorld.mConfig.worldName, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set inertiaTensorLocal=" + inertiaTensorLocal.to_string(), __FILE__, __LINE__);
@ -447,12 +457,17 @@ void RigidBody::updateMassFromColliders() {
// Set the mass
mWorld.mRigidBodyComponents.setMass(mEntity, totalMass);
// Compute the inverse mass
if (totalMass > decimal(0.0)) {
mWorld.mRigidBodyComponents.setMassInverse(mEntity, decimal(1.0) / totalMass);
}
else {
mWorld.mRigidBodyComponents.setMassInverse(mEntity, decimal(0.0));
// If it is a dynamic body
const BodyType type = mWorld.mRigidBodyComponents.getBodyType(mEntity);
if (type == BodyType::DYNAMIC) {
// Compute the inverse mass
if (totalMass > decimal(0.0)) {
mWorld.mRigidBodyComponents.setMassInverse(mEntity, decimal(1.0) / totalMass);
}
else {
mWorld.mRigidBodyComponents.setMassInverse(mEntity, decimal(0.0));
}
}
RP3D_LOG(mWorld.mConfig.worldName, Logger::Level::Information, Logger::Category::Body,
@ -479,11 +494,16 @@ void RigidBody::updateMassPropertiesFromColliders() {
mWorld.mRigidBodyComponents.setCenterOfMassLocal(mEntity, centerOfMassLocal);
mWorld.mRigidBodyComponents.setCenterOfMassWorld(mEntity, centerOfMassWorld);
// Update the linear velocity of the center of mass
Vector3 linearVelocity = mWorld.mRigidBodyComponents.getAngularVelocity(mEntity);
const Vector3& angularVelocity = mWorld.mRigidBodyComponents.getAngularVelocity(mEntity);
linearVelocity += angularVelocity.cross(centerOfMassWorld - oldCenterOfMassWorld);
mWorld.mRigidBodyComponents.setLinearVelocity(mEntity, linearVelocity);
// If it is a dynamic body
const BodyType type = mWorld.mRigidBodyComponents.getBodyType(mEntity);
if (type == BodyType::DYNAMIC) {
// Update the linear velocity of the center of mass
Vector3 linearVelocity = mWorld.mRigidBodyComponents.getAngularVelocity(mEntity);
const Vector3& angularVelocity = mWorld.mRigidBodyComponents.getAngularVelocity(mEntity);
linearVelocity += angularVelocity.cross(centerOfMassWorld - oldCenterOfMassWorld);
mWorld.mRigidBodyComponents.setLinearVelocity(mEntity, linearVelocity);
}
RP3D_LOG(mWorld.mConfig.worldName, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set centerOfMassLocal=" + centerOfMassLocal.to_string(), __FILE__, __LINE__);
@ -495,11 +515,15 @@ void RigidBody::updateMassPropertiesFromColliders() {
mWorld.mRigidBodyComponents.setLocalInertiaTensor(mEntity, inertiaTensorLocal);
// Compute the inverse local inertia tensor
Vector3 inverseInertiaTensorLocal(inertiaTensorLocal.x != decimal(0.0) ? decimal(1.0) / inertiaTensorLocal.x : 0,
inertiaTensorLocal.y != decimal(0.0) ? decimal(1.0) / inertiaTensorLocal.y : 0,
inertiaTensorLocal.z != decimal(0.0) ? decimal(1.0) / inertiaTensorLocal.z : 0);
mWorld.mRigidBodyComponents.setInverseInertiaTensorLocal(mEntity, inverseInertiaTensorLocal);
// If it is a dynamic body
if (type == BodyType::DYNAMIC) {
// Compute the inverse local inertia tensor
Vector3 inverseInertiaTensorLocal(inertiaTensorLocal.x != decimal(0.0) ? decimal(1.0) / inertiaTensorLocal.x : 0,
inertiaTensorLocal.y != decimal(0.0) ? decimal(1.0) / inertiaTensorLocal.y : 0,
inertiaTensorLocal.z != decimal(0.0) ? decimal(1.0) / inertiaTensorLocal.z : 0);
mWorld.mRigidBodyComponents.setInverseInertiaTensorLocal(mEntity, inverseInertiaTensorLocal);
}
RP3D_LOG(mWorld.mConfig.worldName, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set inertiaTensorLocal=" + inertiaTensorLocal.to_string(), __FILE__, __LINE__);
@ -507,12 +531,16 @@ void RigidBody::updateMassPropertiesFromColliders() {
// Set the mass
mWorld.mRigidBodyComponents.setMass(mEntity, totalMass);
// Compute the inverse mass
if (totalMass > decimal(0.0)) {
mWorld.mRigidBodyComponents.setMassInverse(mEntity, decimal(1.0) / totalMass);
}
else {
mWorld.mRigidBodyComponents.setMassInverse(mEntity, decimal(0.0));
// If it is a dynamic body
if (type == BodyType::DYNAMIC) {
// Compute the inverse mass
if (totalMass > decimal(0.0)) {
mWorld.mRigidBodyComponents.setMassInverse(mEntity, decimal(1.0) / totalMass);
}
else {
mWorld.mRigidBodyComponents.setMassInverse(mEntity, decimal(0.0));
}
}
RP3D_LOG(mWorld.mConfig.worldName, Logger::Level::Information, Logger::Category::Body,
@ -526,24 +554,26 @@ void RigidBody::updateMassPropertiesFromColliders() {
*/
void RigidBody::setMass(decimal mass) {
mWorld.mRigidBodyComponents.setMass(mEntity, mass);
if (mass < decimal(0.0)) {
RP3D_LOG(mWorld.mConfig.worldName, Logger::Level::Error, Logger::Category::Body,
"Error when setting the mass of a rigid body: the mass must be a positive value", __FILE__, __LINE__);
"Error when setting mass of body " + std::to_string(mEntity.id) + ": mass cannot be negative", __FILE__, __LINE__);
return;
}
if (mWorld.mRigidBodyComponents.getMass(mEntity) > decimal(0.0)) {
mWorld.mRigidBodyComponents.setMassInverse(mEntity, decimal(1.0) / mass);
}
else {
mWorld.mRigidBodyComponents.setMassInverse(mEntity, decimal(0.0));
mWorld.mRigidBodyComponents.setMass(mEntity, mass);
if (mWorld.mRigidBodyComponents.getMass(mEntity) < decimal(0.0)) {
// If it is a dynamic body
const BodyType type = mWorld.mRigidBodyComponents.getBodyType(mEntity);
if (type == BodyType::DYNAMIC) {
if (mass > decimal(0.0)) {
mWorld.mRigidBodyComponents.setMassInverse(mEntity, decimal(1.0) / mass);
}
else {
mWorld.mRigidBodyComponents.setMassInverse(mEntity, decimal(0.0));
RP3D_LOG(mWorld.mConfig.worldName, Logger::Level::Error, Logger::Category::Body,
"Error when setting mass of body " + std::to_string(mEntity.id) + ": mass cannot be negative", __FILE__, __LINE__);
}
}