Refactor the way to set/update the center of mass, mass and inertia tensor of a rigid body

This commit is contained in:
Daniel Chappuis 2020-03-01 16:39:16 +01:00
parent 28560d034e
commit cda466f9da
59 changed files with 708 additions and 506 deletions

View File

@ -12,6 +12,14 @@
- It is now possible to change the scale of a HeightFieldShape using the HeightFieldShape::setScale() method - It is now possible to change the scale of a HeightFieldShape using the HeightFieldShape::setScale() method
- A method PhysicsWorld::getCollisionBody(uint index) has been added on a physics world to retrieve a given CollisionBody - A method PhysicsWorld::getCollisionBody(uint index) has been added on a physics world to retrieve a given CollisionBody
- A method PhysicsWorld::getRigidBody(uint index) has been added on a physics world to retrieve a given RigidBody - A method PhysicsWorld::getRigidBody(uint index) has been added on a physics world to retrieve a given RigidBody
- The Material of a Collider now has a mass density parameter that is used to compute its mass
- A RigidBody::getLocalCenterOfMass() method has been added to retrieve the current center of mass of a rigid body
- Add PhysicsCommon class that needs to be instanciated at the beginning and is used as a factory for other objects of the library
- The RigidBody::updateLocalCenterOfMassFromColliders() method has been added to compute and set the center of mass of a body using its colliders
- The RigidBody::updateLocalInertiaTensorFromColliders() method has been added to compute and set the local inertia tensor of a body using its colliders
- The RigidBody::getLocalInertiaTensor() method has been added to retrieve the local-space inertia tensor of a rigid body.
- The RigidBody::updateMassFromColliders() method has been added to compute and set the mass of a body using its colliders
- A Material nows has a mass density parameter that can be set using the Material::setMassDensity() method. The mass density is used to compute the mass of a collider when computing the mass of a rigid body
### Changed ### Changed
@ -37,6 +45,11 @@
- An instance of the PolyhedronMesh class cannot be instanciated directly anymore. You need to use the PhysicsCommon::createPolyhedronMesh() method. - An instance of the PolyhedronMesh class cannot be instanciated directly anymore. You need to use the PhysicsCommon::createPolyhedronMesh() method.
- An instance of the TriangleMesh class cannot be instanciated directly anymore. You need to use the PhysicsCommon::createTriangleMesh() method. - An instance of the TriangleMesh class cannot be instanciated directly anymore. You need to use the PhysicsCommon::createTriangleMesh() method.
- The ProxyShape class has been renamed to Collider. The CollisionBody::addCollider(), RigidBody::addCollider() methods have to be used to create and add a collider to a body. Then methods CollisionBody::removeCollider(), RigidBody::removeCollider() need to be used to remove a collider. - The ProxyShape class has been renamed to Collider. The CollisionBody::addCollider(), RigidBody::addCollider() methods have to be used to create and add a collider to a body. Then methods CollisionBody::removeCollider(), RigidBody::removeCollider() need to be used to remove a collider.
- The RigidBody::addCollider() method (previously addProxyShape() method) does not take a "mass" parameter anymore.
- The RigidBody::setCenterOfMassLocal() method has been renamed to RigidBody::setLocalCenterOfMass()
- The RigidBody::setInertiaTensorLocal() method has been renamed to RigidBody::setLocalInertiaTensor()
- The RigidBody::recomputeMassInformation() method has been renamed to RigidBody::updateMassPropertiesFromColliders.
- Now, you need to manually call the RigidBody::recomputeMassInformation() method after adding colliders to a rigid body to recompute its inertia tensor, center of mass and mass
- The rendering in the testbed application has been improved - The rendering in the testbed application has been improved
### Removed ### Removed
@ -48,6 +61,9 @@
- The EventListener::endInternalTick() method has been removed (because internal ticks do not exist anymore). - The EventListener::endInternalTick() method has been removed (because internal ticks do not exist anymore).
- The RigidBody::getJointsList() method has been removed. - The RigidBody::getJointsList() method has been removed.
- It is not possible anymore to set custom pool and stack frame allocators. Only the base allocator can be customized when creating a PhysicsCommon instance. - It is not possible anymore to set custom pool and stack frame allocators. Only the base allocator can be customized when creating a PhysicsCommon instance.
- The RigidBody::setInverseInertiaTensorLocal() method has been removed. The RigidBody::setInertiaTensorLocal() has to be used instead.
- The RigidBody::getInverseInertiaTensorWorld() method has been removed.
- The Collider::getMass() method has been removed.
## Version 0.7.1 (July 01, 2019) ## Version 0.7.1 (July 01, 2019)
@ -55,7 +71,6 @@
- Make possible for the user to get vertices, normals and triangle indices of a ConcaveMeshShape - Make possible for the user to get vertices, normals and triangle indices of a ConcaveMeshShape
- Make possible for the user to get vertices and height values of the HeightFieldShape - Make possible for the user to get vertices and height values of the HeightFieldShape
- Add PhysicsCommon class that needs to be instanciated at the beginning and is used as a factory for other objects of the library
### Fixed ### Fixed

View File

@ -86,7 +86,7 @@ Collider* CollisionBody::addCollider(CollisionShape* collisionShape, const Trans
const Transform localToWorldTransform = mWorld.mTransformComponents.getTransform(mEntity) * transform; const Transform localToWorldTransform = mWorld.mTransformComponents.getTransform(mEntity) * transform;
ColliderComponents::ColliderComponent colliderComponent(mEntity, collider, ColliderComponents::ColliderComponent colliderComponent(mEntity, collider,
AABB(localBoundsMin, localBoundsMax), AABB(localBoundsMin, localBoundsMax),
transform, collisionShape, decimal(1), 0x0001, 0xFFFF, localToWorldTransform); transform, collisionShape, 0x0001, 0xFFFF, localToWorldTransform);
bool isActive = mWorld.mCollisionBodyComponents.getIsActive(mEntity); bool isActive = mWorld.mCollisionBodyComponents.getIsActive(mEntity);
mWorld.mCollidersComponents.addComponent(colliderEntity, !isActive, colliderComponent); mWorld.mCollidersComponents.addComponent(colliderEntity, !isActive, colliderComponent);
@ -196,8 +196,8 @@ void CollisionBody::removeCollider(Collider* collider) {
mWorld.mMemoryManager.release(MemoryManager::AllocationType::Pool, collider, sizeof(Collider)); mWorld.mMemoryManager.release(MemoryManager::AllocationType::Pool, collider, sizeof(Collider));
} }
// Remove all the collision shapes // Remove all the colliders
void CollisionBody::removeAllCollisionShapes() { void CollisionBody::removeAllColliders() {
// Look for the collider that contains the collision shape in parameter. // Look for the collider that contains the collision shape in parameter.
// Note that we need to copy the list of collider entities because we are deleting them in a loop. // Note that we need to copy the list of collider entities because we are deleting them in a loop.

View File

@ -79,7 +79,7 @@ class CollisionBody {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Remove all the collision shapes /// Remove all the collision shapes
void removeAllCollisionShapes(); void removeAllColliders();
/// Update the broad-phase state for this body (because it has moved for instance) /// Update the broad-phase state for this body (because it has moved for instance)
void updateBroadPhaseState(decimal timeStep) const; void updateBroadPhaseState(decimal timeStep) const;

View File

@ -38,8 +38,7 @@ using namespace reactphysics3d;
* @param world The world where the body has been added * @param world The world where the body has been added
* @param id The ID of the body * @param id The ID of the body
*/ */
RigidBody::RigidBody(PhysicsWorld& world, Entity entity) RigidBody::RigidBody(PhysicsWorld& world, Entity entity) : CollisionBody(world, entity) {
: CollisionBody(world, entity), mIsCenterOfMassSetByUser(false), mIsInertiaTensorSetByUser(false) {
} }
@ -50,12 +49,12 @@ BodyType RigidBody::getType() const {
// Set the type of the body // Set the type of the body
/// The type of the body can either STATIC, KINEMATIC or DYNAMIC as described bellow: /// The type of the body can either STATIC, KINEMATIC or DYNAMIC as described bellow:
/// STATIC : A static body has infinite mass, zero velocity but the position can be /// STATIC : A static body is simulated as if it has infinite mass, zero velocity but its position can be
/// changed manually. A static body does not collide with other static or kinematic bodies. /// changed manually. A static body does not collide with other static or kinematic bodies.
/// KINEMATIC : A kinematic body has infinite mass, the velocity can be changed manually and its /// KINEMATIC : A kinematic body is simulated as if it has infinite mass, its velocity can be changed manually and its
/// position is computed by the physics engine. A kinematic body does not collide with /// position is computed by the physics engine. A kinematic body does not collide with
/// other static or kinematic bodies. /// other static or kinematic bodies.
/// DYNAMIC : A dynamic body has non-zero mass, non-zero velocity determined by forces and its /// DYNAMIC : A dynamic body has non-zero mass, its velocity is determined by forces and its
/// position is determined by the physics engine. A dynamic body can collide with other /// position is determined by the physics engine. A dynamic body can collide with other
/// dynamic, static or kinematic bodies. /// dynamic, static or kinematic bodies.
/** /**
@ -67,9 +66,6 @@ void RigidBody::setType(BodyType type) {
mWorld.mRigidBodyComponents.setBodyType(mEntity, type); mWorld.mRigidBodyComponents.setBodyType(mEntity, type);
// Recompute the total mass, center of mass and inertia tensor
recomputeMassInformation();
// If it is a static body // If it is a static body
if (type == BodyType::STATIC) { if (type == BodyType::STATIC) {
@ -86,10 +82,23 @@ void RigidBody::setType(BodyType type) {
mWorld.mRigidBodyComponents.setInverseInertiaTensorLocal(mEntity, Matrix3x3::zero()); mWorld.mRigidBodyComponents.setInverseInertiaTensorLocal(mEntity, Matrix3x3::zero());
} }
else { // If it is a dynamic body else { // If it is a dynamic body
mWorld.mRigidBodyComponents.setMassInverse(mEntity, decimal(1.0) / mWorld.mRigidBodyComponents.getInitMass(mEntity));
if (mIsInertiaTensorSetByUser) { const decimal mass = mWorld.mRigidBodyComponents.getMass(mEntity);
mWorld.mRigidBodyComponents.setInverseInertiaTensorLocal(mEntity, mUserInertiaTensorLocalInverse);
if (mass > decimal(0.0)) {
mWorld.mRigidBodyComponents.setMassInverse(mEntity, decimal(1.0) / mass) ;
}
else {
mWorld.mRigidBodyComponents.setMassInverse(mEntity, decimal(0.0));
}
// Compute the inverse local inertia tensor
const Matrix3x3& inertiaTensorLocal = mWorld.mRigidBodyComponents.getLocalInertiaTensor(mEntity);
if (approxEqual(inertiaTensorLocal.getDeterminant(), decimal(0.0))) {
mWorld.mRigidBodyComponents.setInverseInertiaTensorLocal(mEntity, Matrix3x3::zero());
}
else {
mWorld.mRigidBodyComponents.setInverseInertiaTensorLocal(mEntity, inertiaTensorLocal.getInverse());
} }
} }
@ -112,32 +121,12 @@ void RigidBody::setType(BodyType type) {
(type == BodyType::STATIC ? "Static" : (type == BodyType::DYNAMIC ? "Dynamic" : "Kinematic"))); (type == BodyType::STATIC ? "Static" : (type == BodyType::DYNAMIC ? "Dynamic" : "Kinematic")));
} }
// Get the inverse local inertia tensor of the body (in body coordinates)
const Matrix3x3& RigidBody::getInverseInertiaTensorLocal() const {
return mWorld.mRigidBodyComponents.getInertiaTensorLocalInverse(mEntity);
}
// Return the inverse of the inertia tensor in world coordinates.
/// The inertia tensor I_w in world coordinates is computed with the
/// local inverse inertia tensor I_b^-1 in body coordinates
/// by I_w = R * I_b^-1 * R^T
/// where R is the rotation matrix (and R^T its transpose) of the
/// current orientation quaternion of the body
/**
* @return The 3x3 inverse inertia tensor matrix of the body in world-space
* coordinates
*/
const Matrix3x3 RigidBody::getInertiaTensorInverseWorld() const {
return getInertiaTensorInverseWorld(mWorld, mEntity);
}
// Method that return the mass of the body // Method that return the mass of the body
/** /**
* @return The mass (in kilograms) of the body * @return The mass (in kilograms) of the body
*/ */
decimal RigidBody::getMass() const { decimal RigidBody::getMass() const {
return mWorld.mRigidBodyComponents.getInitMass(mEntity); return mWorld.mRigidBodyComponents.getMass(mEntity);
} }
// Apply an external force to the body at a given point (in world-space coordinates). // Apply an external force to the body at a given point (in world-space coordinates).
@ -171,22 +160,29 @@ void RigidBody::applyForce(const Vector3& force, const Vector3& point) {
mWorld.mRigidBodyComponents.setExternalTorque(mEntity, externalTorque + (point - centerOfMassWorld).cross(force)); mWorld.mRigidBodyComponents.setExternalTorque(mEntity, externalTorque + (point - centerOfMassWorld).cross(force));
} }
// Return the local inertia tensor of the body (in body coordinates)
const Matrix3x3& RigidBody::getLocalInertiaTensor() const {
return mWorld.mRigidBodyComponents.getLocalInertiaTensor(mEntity);
}
// 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 /// Note that an inertia tensor with a zero value on its diagonal is interpreted as infinite inertia.
/// 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
*/ */
void RigidBody::setInertiaTensorLocal(const Matrix3x3& inertiaTensorLocal) { void RigidBody::setLocalInertiaTensor(const Matrix3x3& inertiaTensorLocal) {
mUserInertiaTensorLocalInverse = inertiaTensorLocal.getInverse(); mWorld.mRigidBodyComponents.setLocalInertiaTensor(mEntity, inertiaTensorLocal);
mIsInertiaTensorSetByUser = true;
if (mWorld.mRigidBodyComponents.getBodyType(mEntity) != BodyType::DYNAMIC) return;
// Compute the inverse local inertia tensor // Compute the inverse local inertia tensor
mWorld.mRigidBodyComponents.setInverseInertiaTensorLocal(mEntity, mUserInertiaTensorLocalInverse); if (approxEqual(inertiaTensorLocal.getDeterminant(), decimal(0.0))) {
mWorld.mRigidBodyComponents.setInverseInertiaTensorLocal(mEntity, Matrix3x3::zero());
}
else {
mWorld.mRigidBodyComponents.setInverseInertiaTensorLocal(mEntity, inertiaTensorLocal.getInverse());
}
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set inertiaTensorLocal=" + inertiaTensorLocal.to_string()); "Body " + std::to_string(mEntity.id) + ": Set inertiaTensorLocal=" + inertiaTensorLocal.to_string());
@ -231,45 +227,18 @@ decimal RigidBody::getAngularDamping() const {
return mWorld.mRigidBodyComponents.getAngularDamping(mEntity); return mWorld.mRigidBodyComponents.getAngularDamping(mEntity);
} }
// Set the inverse local inertia tensor of the body (in local-space coordinates) // Set the center of mass of the body (in local-space coordinates)
/// If the inverse inertia tensor is set with this method, it will not be computed /// This method does not move the rigid body in the world.
/// using the collision shapes of the body.
/** /**
* @param inverseInertiaTensorLocal The 3x3 inverse inertia tensor matrix of the body in local-space * @param centerOfMass The center of mass of the body in local-space coordinates
* coordinates
*/ */
void RigidBody::setInverseInertiaTensorLocal(const Matrix3x3& inverseInertiaTensorLocal) { void RigidBody::setLocalCenterOfMass(const Vector3& centerOfMass) {
mUserInertiaTensorLocalInverse = inverseInertiaTensorLocal;
mIsInertiaTensorSetByUser = true;
if (mWorld.mRigidBodyComponents.getBodyType(mEntity) != BodyType::DYNAMIC) return;
// Compute the inverse local inertia tensor
mWorld.mRigidBodyComponents.setInverseInertiaTensorLocal(mEntity, mUserInertiaTensorLocalInverse);
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set inverseInertiaTensorLocal=" + inverseInertiaTensorLocal.to_string());
}
// 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
* coordinates
*/
void RigidBody::setCenterOfMassLocal(const Vector3& centerOfMassLocal) {
if (mWorld.mRigidBodyComponents.getBodyType(mEntity) != BodyType::DYNAMIC) return;
mIsCenterOfMassSetByUser = true;
const Vector3 oldCenterOfMass = mWorld.mRigidBodyComponents.getCenterOfMassWorld(mEntity); const Vector3 oldCenterOfMass = mWorld.mRigidBodyComponents.getCenterOfMassWorld(mEntity);
mWorld.mRigidBodyComponents.setCenterOfMassLocal(mEntity, centerOfMassLocal); mWorld.mRigidBodyComponents.setCenterOfMassLocal(mEntity, centerOfMass);
// Compute the center of mass in world-space coordinates // Compute the center of mass in world-space coordinates
mWorld.mRigidBodyComponents.setCenterOfMassWorld(mEntity, mWorld.mTransformComponents.getTransform(mEntity) * centerOfMassLocal); mWorld.mRigidBodyComponents.setCenterOfMassWorld(mEntity, mWorld.mTransformComponents.getTransform(mEntity) * centerOfMass);
// Update the linear velocity of the center of mass // Update the linear velocity of the center of mass
Vector3 linearVelocity = mWorld.mRigidBodyComponents.getAngularVelocity(mEntity); Vector3 linearVelocity = mWorld.mRigidBodyComponents.getAngularVelocity(mEntity);
@ -278,26 +247,258 @@ void RigidBody::setCenterOfMassLocal(const Vector3& centerOfMassLocal) {
linearVelocity += angularVelocity.cross(centerOfMassWorld - oldCenterOfMass); linearVelocity += angularVelocity.cross(centerOfMassWorld - oldCenterOfMass);
mWorld.mRigidBodyComponents.setLinearVelocity(mEntity, linearVelocity); mWorld.mRigidBodyComponents.setLinearVelocity(mEntity, linearVelocity);
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set centerOfMassLocal=" + centerOfMass.to_string());
}
// Return the center of mass of the body (in local-space coordinates)
const Vector3& RigidBody::getLocalCenterOfMass() const {
return mWorld.mRigidBodyComponents.getCenterOfMassLocal(mEntity);
}
// Compute and set the local-space center of mass of the body using its colliders
/// This method uses the shape, mass density and transforms of the colliders to set
/// the center of mass of the body. Note that calling this method will overwrite the
/// mass that has been previously set with the RigidBody::setCenterOfMass() method. Moreover, this method
/// does not use the mass set by the user with the RigidBody::setMass() method to compute the center
/// of mass but only the mass density and volume of the colliders.
void RigidBody::updateLocalCenterOfMassFromColliders() {
const Vector3 oldCenterOfMassWorld = mWorld.mRigidBodyComponents.getCenterOfMassWorld(mEntity);
Vector3 centerOfMassLocal = computeCenterOfMass();
const Vector3 centerOfMassWorld = mWorld.mTransformComponents.getTransform(mEntity) * centerOfMassLocal;
// Set the center of mass
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);
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set centerOfMassLocal=" + centerOfMassLocal.to_string()); "Body " + std::to_string(mEntity.id) + ": Set centerOfMassLocal=" + centerOfMassLocal.to_string());
} }
// Compute and return the local-space center of mass of the body using its colliders
Vector3 RigidBody::computeCenterOfMass() const {
decimal totalMass = decimal(0.0);
Vector3 centerOfMassLocal(0, 0, 0);
// Compute the local center of mass
const List<Entity>& colliderEntities = mWorld.mCollisionBodyComponents.getColliders(mEntity);
for (uint i=0; i < colliderEntities.size(); i++) {
Collider* collider = mWorld.mCollidersComponents.getCollider(colliderEntities[i]);
const decimal colliderVolume = mWorld.mCollidersComponents.getCollisionShape(colliderEntities[i])->getVolume();
const decimal colliderMassDensity = collider->getMaterial().getMassDensity();
const decimal colliderMass = colliderVolume * colliderMassDensity;
totalMass += colliderMass;
centerOfMassLocal += colliderMass * mWorld.mCollidersComponents.getLocalToBodyTransform(colliderEntities[i]).getPosition();
}
if (totalMass > decimal(0.0)) {
centerOfMassLocal /= totalMass;
}
return centerOfMassLocal;
}
// Compute the local-space inertia tensor and total mass of the body using its colliders
void RigidBody::computeMassAndInertiaTensorLocal(Matrix3x3& inertiaTensorLocal, decimal& totalMass) const {
inertiaTensorLocal.setToZero();
totalMass = decimal(0.0);
const Vector3 centerOfMassLocal = mWorld.mRigidBodyComponents.getCenterOfMassLocal(mEntity);
// Compute the inertia tensor using all the colliders
const List<Entity>& colliderEntities = mWorld.mCollisionBodyComponents.getColliders(mEntity);
for (uint i=0; i < colliderEntities.size(); i++) {
Collider* collider = mWorld.mCollidersComponents.getCollider(colliderEntities[i]);
const decimal colliderVolume = mWorld.mCollidersComponents.getCollisionShape(colliderEntities[i])->getVolume();
const decimal colliderMassDensity = collider->getMaterial().getMassDensity();
const decimal colliderMass = colliderVolume * colliderMassDensity;
totalMass += colliderMass;
// Get the inertia tensor of the collider in its local-space
Matrix3x3 inertiaTensor;
collider->getCollisionShape()->computeLocalInertiaTensor(inertiaTensor, colliderMass);
// Convert the collider inertia tensor into the local-space of the body
const Transform& shapeTransform = collider->getLocalToBodyTransform();
Matrix3x3 rotationMatrix = shapeTransform.getOrientation().getMatrix();
inertiaTensor = rotationMatrix * inertiaTensor * rotationMatrix.getTranspose();
// Use the parallel axis theorem to convert the inertia tensor w.r.t the collider
// center into a inertia tensor w.r.t to the body origin.
Vector3 offset = shapeTransform.getPosition() - centerOfMassLocal;
decimal offsetSquare = offset.lengthSquare();
Matrix3x3 offsetMatrix;
offsetMatrix[0].setAllValues(offsetSquare, decimal(0.0), decimal(0.0));
offsetMatrix[1].setAllValues(decimal(0.0), offsetSquare, decimal(0.0));
offsetMatrix[2].setAllValues(decimal(0.0), decimal(0.0), offsetSquare);
offsetMatrix[0] += offset * (-offset.x);
offsetMatrix[1] += offset * (-offset.y);
offsetMatrix[2] += offset * (-offset.z);
offsetMatrix *= colliderMass;
inertiaTensorLocal += inertiaTensor + offsetMatrix;
}
}
// Compute and set the local-space inertia tensor of the body using its colliders
/// This method uses the shape, mass density and transforms of the colliders to set
/// the local-space inertia tensor of the body. Note that calling this method will overwrite the
/// mass that has been set with the RigidBody::setInertiaTensorLocal() method.
void RigidBody::updateLocalInertiaTensorFromColliders() {
const Vector3 centerOfMassLocal = mWorld.mRigidBodyComponents.getCenterOfMassLocal(mEntity);
// Compute the local-space inertia tensor
Matrix3x3 inertiaTensorLocal;
decimal totalMass;
computeMassAndInertiaTensorLocal(inertiaTensorLocal, totalMass);
mWorld.mRigidBodyComponents.setLocalInertiaTensor(mEntity, inertiaTensorLocal);
// Compute the inverse local inertia tensor
if (approxEqual(inertiaTensorLocal.getDeterminant(), decimal(0.0))) {
mWorld.mRigidBodyComponents.setInverseInertiaTensorLocal(mEntity, Matrix3x3::zero());
}
else {
mWorld.mRigidBodyComponents.setInverseInertiaTensorLocal(mEntity, inertiaTensorLocal.getInverse());
}
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set inertiaTensorLocal=" + inertiaTensorLocal.to_string());
}
// Compute and set the mass of the body using its colliders
/// This method uses the shape, mass density and transforms of the colliders to set
/// the total mass of the body. Note that calling this method will overwrite the
/// mass that has been set with the RigidBody::setMass() method
void RigidBody::updateMassFromColliders() {
decimal totalMass = decimal(0.0);
// Compute the total mass of the body
const List<Entity>& colliderEntities = mWorld.mCollisionBodyComponents.getColliders(mEntity);
for (uint i=0; i < colliderEntities.size(); i++) {
Collider* collider = mWorld.mCollidersComponents.getCollider(colliderEntities[i]);
const decimal colliderVolume = mWorld.mCollidersComponents.getCollisionShape(colliderEntities[i])->getVolume();
const decimal colliderMassDensity = collider->getMaterial().getMassDensity();
const decimal colliderMass = colliderVolume * colliderMassDensity;
totalMass += colliderMass;
}
// 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));
}
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set mass=" + std::to_string(totalMass));
}
// Compute and set the center of mass, the mass and the local-space inertia tensor of the body using its colliders
/// This method uses the shape, mass density and transform of the colliders of the body to set
/// the total mass, the center of mass and the local inertia tensor of the body.
/// Note that calling this method will overwrite the
/// mass that has been set with the RigidBody::setMass(), the center of mass that has been
/// set with RigidBody::setCenterOfMass() and the local inertia tensor that has been set with
/// RigidBody::setInertiaTensorLocal().
void RigidBody::updateMassPropertiesFromColliders() {
const Vector3 oldCenterOfMassWorld = mWorld.mRigidBodyComponents.getCenterOfMassWorld(mEntity);
// Compute the local center of mass
Vector3 centerOfMassLocal = computeCenterOfMass();
const Vector3 centerOfMassWorld = mWorld.mTransformComponents.getTransform(mEntity) * centerOfMassLocal;
// Set the center of mass
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);
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set centerOfMassLocal=" + centerOfMassLocal.to_string());
// Compute the mass and local-space inertia tensor
Matrix3x3 inertiaTensorLocal;
decimal totalMass;
computeMassAndInertiaTensorLocal(inertiaTensorLocal, totalMass);
mWorld.mRigidBodyComponents.setLocalInertiaTensor(mEntity, inertiaTensorLocal);
// Compute the inverse local inertia tensor
if (approxEqual(inertiaTensorLocal.getDeterminant(), decimal(0.0))) {
mWorld.mRigidBodyComponents.setInverseInertiaTensorLocal(mEntity, Matrix3x3::zero());
}
else {
mWorld.mRigidBodyComponents.setInverseInertiaTensorLocal(mEntity, inertiaTensorLocal.getInverse());
}
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set inertiaTensorLocal=" + inertiaTensorLocal.to_string());
// 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));
}
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set mass=" + std::to_string(totalMass));
}
// Set the mass of the rigid body // Set the mass of the rigid body
/// Note that a mass of zero is interpreted as infinite mass.
/** /**
* @param mass The mass (in kilograms) of the body * @param mass The mass (in kilograms) of the body
*/ */
void RigidBody::setMass(decimal mass) { void RigidBody::setMass(decimal mass) {
if (mWorld.mRigidBodyComponents.getBodyType(mEntity) != BodyType::DYNAMIC) return; mWorld.mRigidBodyComponents.setMass(mEntity, mass);
mWorld.mRigidBodyComponents.setInitMass(mEntity, mass); // TODO : Report error if mass is negative
if (mWorld.mRigidBodyComponents.getInitMass(mEntity) > decimal(0.0)) { if (mWorld.mRigidBodyComponents.getMass(mEntity) > decimal(0.0)) {
mWorld.mRigidBodyComponents.setMassInverse(mEntity, decimal(1.0) / mWorld.mRigidBodyComponents.getInitMass(mEntity)); mWorld.mRigidBodyComponents.setMassInverse(mEntity, decimal(1.0) / mass);
} }
else { else {
mWorld.mRigidBodyComponents.setInitMass(mEntity, decimal(1.0)); mWorld.mRigidBodyComponents.setMassInverse(mEntity, decimal(0.0));
mWorld.mRigidBodyComponents.setMassInverse(mEntity, decimal(1.0));
} }
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
@ -315,10 +516,9 @@ void RigidBody::setMass(decimal mass) {
* @param collisionShape The collision shape of the new collider * @param collisionShape The collision shape of the new collider
* @param transform The transformation of the collider that transforms the * @param transform The transformation of the collider that transforms the
* local-space of the collider into the local-space of the body * local-space of the collider into the local-space of the body
* @param mass Mass (in kilograms) of the collider you want to add
* @return A pointer to the collider that has been created * @return A pointer to the collider that has been created
*/ */
Collider* RigidBody::addCollider(CollisionShape* collisionShape, const Transform& transform, decimal mass) { Collider* RigidBody::addCollider(CollisionShape* collisionShape, const Transform& transform) {
// Create a new entity for the collider // Create a new entity for the collider
Entity colliderEntity = mWorld.mEntityManager.createEntity(); Entity colliderEntity = mWorld.mEntityManager.createEntity();
@ -333,9 +533,8 @@ Collider* RigidBody::addCollider(CollisionShape* collisionShape, const Transform
// TODO : Maybe this method can directly returns an AABB // TODO : Maybe this method can directly returns an AABB
collisionShape->getLocalBounds(localBoundsMin, localBoundsMax); collisionShape->getLocalBounds(localBoundsMin, localBoundsMax);
const Transform localToWorldTransform = mWorld.mTransformComponents.getTransform(mEntity) * transform; const Transform localToWorldTransform = mWorld.mTransformComponents.getTransform(mEntity) * transform;
ColliderComponents::ColliderComponent colliderComponent(mEntity, collider, ColliderComponents::ColliderComponent colliderComponent(mEntity, collider, AABB(localBoundsMin, localBoundsMax),
AABB(localBoundsMin, localBoundsMax), transform, collisionShape, 0x0001, 0xFFFF, localToWorldTransform);
transform, collisionShape, mass, 0x0001, 0xFFFF, localToWorldTransform);
bool isSleeping = mWorld.mRigidBodyComponents.getIsSleeping(mEntity); bool isSleeping = mWorld.mRigidBodyComponents.getIsSleeping(mEntity);
mWorld.mCollidersComponents.addComponent(colliderEntity, isSleeping, colliderComponent); mWorld.mCollidersComponents.addComponent(colliderEntity, isSleeping, colliderComponent);
@ -365,10 +564,6 @@ Collider* RigidBody::addCollider(CollisionShape* collisionShape, const Transform
// Notify the collision detection about this new collision shape // Notify the collision detection about this new collision shape
mWorld.mCollisionDetection.addCollider(collider, aabb); mWorld.mCollisionDetection.addCollider(collider, aabb);
// Recompute the center of mass, total mass and inertia tensor of the body with the new
// collision shape
recomputeMassInformation();
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Collider " + std::to_string(collider->getBroadPhaseId()) + " added to body"); "Body " + std::to_string(mEntity.id) + ": Collider " + std::to_string(collider->getBroadPhaseId()) + " added to body");
@ -389,9 +584,6 @@ void RigidBody::removeCollider(Collider* collider) {
// Remove the collision shape // Remove the collision shape
CollisionBody::removeCollider(collider); CollisionBody::removeCollider(collider);
// Recompute the total mass, center of mass and inertia tensor
recomputeMassInformation();
} }
// Set the variable to know if the gravity is applied to this rigid body // Set the variable to know if the gravity is applied to this rigid body
@ -500,101 +692,6 @@ void RigidBody::setTransform(const Transform& transform) {
setIsSleeping(false); setIsSleeping(false);
} }
// Recompute the center of mass, total mass and inertia tensor of the body using all
// the collision shapes attached to the body.
void RigidBody::recomputeMassInformation() {
mWorld.mRigidBodyComponents.setInitMass(mEntity, decimal(0.0));
mWorld.mRigidBodyComponents.setMassInverse(mEntity, decimal(0.0));
if (!mIsInertiaTensorSetByUser) mWorld.mRigidBodyComponents.setInverseInertiaTensorLocal(mEntity, Matrix3x3::zero());
if (!mIsCenterOfMassSetByUser) mWorld.mRigidBodyComponents.setCenterOfMassLocal(mEntity, Vector3::zero());
Matrix3x3 inertiaTensorLocal;
inertiaTensorLocal.setToZero();
const Transform& transform = mWorld.mTransformComponents.getTransform(mEntity);
// If it is a STATIC or a KINEMATIC body
BodyType type = mWorld.mRigidBodyComponents.getBodyType(mEntity);
if (type == BodyType::STATIC || type == BodyType::KINEMATIC) {
mWorld.mRigidBodyComponents.setCenterOfMassWorld(mEntity, transform.getPosition());
return;
}
assert(mWorld.mRigidBodyComponents.getBodyType(mEntity) == BodyType::DYNAMIC);
// Compute the total mass of the body
const List<Entity>& colliderEntities = mWorld.mCollisionBodyComponents.getColliders(mEntity);
for (uint i=0; i < colliderEntities.size(); i++) {
Collider* collider = mWorld.mCollidersComponents.getCollider(colliderEntities[i]);
mWorld.mRigidBodyComponents.setInitMass(mEntity, mWorld.mRigidBodyComponents.getInitMass(mEntity) + collider->getMass());
if (!mIsCenterOfMassSetByUser) {
mWorld.mRigidBodyComponents.setCenterOfMassLocal(mEntity, mWorld.mRigidBodyComponents.getCenterOfMassLocal(mEntity) +
collider->getLocalToBodyTransform().getPosition() * collider->getMass());
}
}
if (mWorld.mRigidBodyComponents.getInitMass(mEntity) > decimal(0.0)) {
mWorld.mRigidBodyComponents.setMassInverse(mEntity, decimal(1.0) / mWorld.mRigidBodyComponents.getInitMass(mEntity));
}
else {
mWorld.mRigidBodyComponents.setCenterOfMassWorld(mEntity, transform.getPosition());
return;
}
// Compute the center of mass
const Vector3 oldCenterOfMass = mWorld.mRigidBodyComponents.getCenterOfMassWorld(mEntity);
if (!mIsCenterOfMassSetByUser) {
mWorld.mRigidBodyComponents.setCenterOfMassLocal(mEntity, mWorld.mRigidBodyComponents.getCenterOfMassLocal(mEntity) * mWorld.mRigidBodyComponents.getMassInverse(mEntity));
}
mWorld.mRigidBodyComponents.setCenterOfMassWorld(mEntity, transform * mWorld.mRigidBodyComponents.getCenterOfMassLocal(mEntity));
if (!mIsInertiaTensorSetByUser) {
// Compute the inertia tensor using all the colliders
const List<Entity>& colliderEntities = mWorld.mCollisionBodyComponents.getColliders(mEntity);
for (uint i=0; i < colliderEntities.size(); i++) {
Collider* collider = mWorld.mCollidersComponents.getCollider(colliderEntities[i]);
// Get the inertia tensor of the collider in its local-space
Matrix3x3 inertiaTensor;
collider->getCollisionShape()->computeLocalInertiaTensor(inertiaTensor, collider->getMass());
// Convert the collider inertia tensor into the local-space of the body
const Transform& shapeTransform = collider->getLocalToBodyTransform();
Matrix3x3 rotationMatrix = shapeTransform.getOrientation().getMatrix();
inertiaTensor = rotationMatrix * inertiaTensor * rotationMatrix.getTranspose();
// Use the parallel axis theorem to convert the inertia tensor w.r.t the collider
// center into a inertia tensor w.r.t to the body origin.
Vector3 offset = shapeTransform.getPosition() - mWorld.mRigidBodyComponents.getCenterOfMassLocal(mEntity);
decimal offsetSquare = offset.lengthSquare();
Matrix3x3 offsetMatrix;
offsetMatrix[0].setAllValues(offsetSquare, decimal(0.0), decimal(0.0));
offsetMatrix[1].setAllValues(decimal(0.0), offsetSquare, decimal(0.0));
offsetMatrix[2].setAllValues(decimal(0.0), decimal(0.0), offsetSquare);
offsetMatrix[0] += offset * (-offset.x);
offsetMatrix[1] += offset * (-offset.y);
offsetMatrix[2] += offset * (-offset.z);
offsetMatrix *= collider->getMass();
inertiaTensorLocal += inertiaTensor + offsetMatrix;
}
// Compute the local inverse inertia tensor
mWorld.mRigidBodyComponents.setInverseInertiaTensorLocal(mEntity, inertiaTensorLocal.getInverse());
}
// Update the linear velocity of the center of mass
Vector3 linearVelocity = mWorld.mRigidBodyComponents.getLinearVelocity(mEntity);
Vector3 angularVelocity = mWorld.mRigidBodyComponents.getAngularVelocity(mEntity);
linearVelocity += angularVelocity.cross(mWorld.mRigidBodyComponents.getCenterOfMassWorld(mEntity) - oldCenterOfMass);
mWorld.mRigidBodyComponents.setLinearVelocity(mEntity, linearVelocity);
}
// Return the linear velocity // Return the linear velocity
/** /**
* @return The linear velocity vector of the body * @return The linear velocity vector of the body

View File

@ -51,18 +51,6 @@ class RigidBody : public CollisionBody {
protected : protected :
// -------------------- Attributes -------------------- //
/// Inverse Local inertia tensor of the body (in local-space) set
/// by the user with respect to the center of mass of the body
Matrix3x3 mUserInertiaTensorLocalInverse;
/// 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 -------------------- //
/// Set the variable to know whether or not the body is sleeping /// Set the variable to know whether or not the body is sleeping
@ -71,6 +59,12 @@ class RigidBody : public CollisionBody {
/// Update whether the current overlapping pairs where this body is involed are active or not /// Update whether the current overlapping pairs where this body is involed are active or not
void updateOverlappingPairs(); void updateOverlappingPairs();
/// Compute and return the local-space center of mass of the body using its colliders
Vector3 computeCenterOfMass() const;
/// Compute the local-space inertia tensor and total mass of the body using its colliders
void computeMassAndInertiaTensorLocal(Matrix3x3& inertiaTensorLocal, decimal& totalMass) const;
/// Return the inverse of the inertia tensor in world coordinates. /// Return the inverse of the inertia tensor in world coordinates.
static const Matrix3x3 getInertiaTensorInverseWorld(PhysicsWorld& world, Entity bodyEntity); static const Matrix3x3 getInertiaTensorInverseWorld(PhysicsWorld& world, Entity bodyEntity);
@ -96,6 +90,9 @@ class RigidBody : public CollisionBody {
/// Return the mass of the body /// Return the mass of the body
decimal getMass() const; decimal getMass() const;
/// Set the mass of the rigid body
void setMass(decimal mass);
/// Return the linear velocity /// Return the linear velocity
Vector3 getLinearVelocity() const; Vector3 getLinearVelocity() const;
@ -108,23 +105,29 @@ class RigidBody : public CollisionBody {
/// Set the angular velocity. /// Set the angular velocity.
void setAngularVelocity(const Vector3& angularVelocity); void setAngularVelocity(const Vector3& angularVelocity);
/// Return the local inertia tensor of the body (in body coordinates)
const Matrix3x3& getLocalInertiaTensor() const;
/// Set the local inertia tensor of the body (in body coordinates) /// Set the local inertia tensor of the body (in body coordinates)
void setInertiaTensorLocal(const Matrix3x3& inertiaTensorLocal); void setLocalInertiaTensor(const Matrix3x3& inertiaTensorLocal);
/// Set the inverse local inertia tensor of the body (in body coordinates) /// Return the center of mass of the body (in local-space coordinates)
void setInverseInertiaTensorLocal(const Matrix3x3& inverseInertiaTensorLocal); const Vector3& getLocalCenterOfMass() const;
/// Get the inverse local inertia tensor of the body (in body coordinates) /// Set the center of mass of the body (in local-space coordinates)
const Matrix3x3& getInverseInertiaTensorLocal() const; void setLocalCenterOfMass(const Vector3& centerOfMass);
/// Return the inverse of the inertia tensor in world coordinates. /// Compute and set the local-space center of mass of the body using its colliders
const Matrix3x3 getInertiaTensorInverseWorld() const; void updateLocalCenterOfMassFromColliders();
/// Set the local center of mass of the body (in local-space coordinates) /// Compute and set the local-space inertia tensor of the body using its colliders
void setCenterOfMassLocal(const Vector3& centerOfMassLocal); void updateLocalInertiaTensorFromColliders();
/// Set the mass of the rigid body /// Compute and set the mass of the body using its colliders
void setMass(decimal mass); void updateMassFromColliders();
/// Compute and set the center of mass, the mass and the local-space inertia tensor of the body using its colliders
void updateMassPropertiesFromColliders();
/// Return the type of the body /// Return the type of the body
BodyType getType() const; BodyType getType() const;
@ -172,17 +175,11 @@ class RigidBody : public CollisionBody {
virtual void setIsActive(bool isActive) override; virtual void setIsActive(bool isActive) override;
/// Create a new collider and add it to the body /// Create a new collider and add it to the body
// TODO : Remove the mass from this parameter so that we can correctly use inheritance here virtual Collider* addCollider(CollisionShape* collisionShape, const Transform& transform) override;
// The user will then need to call Collider->setMass() to set the mass of the shape
virtual Collider* addCollider(CollisionShape* collisionShape, const Transform& transform, decimal mass);
/// Remove a collider from the body /// Remove a collider from the body
virtual void removeCollider(Collider* collider) override; virtual void removeCollider(Collider* collider) override;
/// Recompute the center of mass, total mass and inertia tensor of the body using all
/// the collision shapes attached to the body.
void recomputeMassInformation();
#ifdef IS_PROFILING_ACTIVE #ifdef IS_PROFILING_ACTIVE
/// Set the profiler /// Set the profiler

View File

@ -51,15 +51,6 @@ Collider::~Collider() {
} }
// Return the mass of the collision shape
/**
* @return Mass of the collision shape (in kilograms)
*/
decimal Collider::getMass() const {
return mBody->mWorld.mCollidersComponents.getMass(mEntity);
}
// Return true if a point is inside the collision shape // Return true if a point is inside the collision shape
/** /**
* @param worldPoint Point to test in world-space coordinates * @param worldPoint Point to test in world-space coordinates

View File

@ -112,9 +112,6 @@ class Collider {
/// Return the parent body /// Return the parent body
CollisionBody* getBody() const; CollisionBody* getBody() const;
/// Return the mass of the collision shape
decimal getMass() const;
/// Return a pointer to the user data attached to this body /// Return a pointer to the user data attached to this body
void* getUserData() const; void* getUserData() const;

View File

@ -27,6 +27,7 @@
#include "PolyhedronMesh.h" #include "PolyhedronMesh.h"
#include "memory/MemoryManager.h" #include "memory/MemoryManager.h"
#include "collision/PolygonVertexArray.h" #include "collision/PolygonVertexArray.h"
#include <cstdlib>
using namespace reactphysics3d; using namespace reactphysics3d;
@ -153,3 +154,48 @@ void PolyhedronMesh::computeCentroid() {
mCentroid /= getNbVertices(); mCentroid /= getNbVertices();
} }
// Compute and return the area of a face
decimal PolyhedronMesh::getFaceArea(uint faceIndex) const {
Vector3 sumCrossProducts(0, 0, 0);
const HalfEdgeStructure::Face& face = mHalfEdgeStructure.getFace(faceIndex);
assert(face.faceVertices.size() >= 3);
Vector3 v1 = getVertex(face.faceVertices[0]);
// For each vertex of the face
for (uint i=2; i < face.faceVertices.size(); i++) {
const Vector3 v2 = getVertex(face.faceVertices[i-1]);
const Vector3 v3 = getVertex(face.faceVertices[i]);
const Vector3 v1v2 = v2 - v1;
const Vector3 v1v3 = v3 - v1;
sumCrossProducts += v1v2.cross(v1v3);
}
return decimal(0.5) * sumCrossProducts.length();
}
// Compute and return the volume of the polyhedron
/// We use the divergence theorem to compute the volume of the polyhedron using a sum over its faces.
decimal PolyhedronMesh::getVolume() const {
decimal sum = 0.0;
// For each face of the polyhedron
for (uint f=0; f < getNbFaces(); f++) {
const HalfEdgeStructure::Face& face = mHalfEdgeStructure.getFace(f);
const decimal faceArea = getFaceArea(f);
const Vector3 faceNormal = mFacesNormals[f];
const Vector3 faceVertex = getVertex(face.faceVertices[0]);
sum += faceVertex.dot(faceNormal) * faceArea;
}
return std::abs(sum) / decimal(3.0);
}

View File

@ -77,6 +77,9 @@ class PolyhedronMesh {
/// Compute the centroid of the polyhedron /// Compute the centroid of the polyhedron
void computeCentroid() ; void computeCentroid() ;
/// Compute and return the area of a face
decimal getFaceArea(uint faceIndex) const;
public: public:
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
@ -102,6 +105,9 @@ class PolyhedronMesh {
/// Return the centroid of the polyhedron /// Return the centroid of the polyhedron
Vector3 getCentroid() const; Vector3 getCentroid() const;
/// Compute and return the volume of the polyhedron
decimal getVolume() const;
// ---------- Friendship ---------- // // ---------- Friendship ---------- //
friend class PhysicsCommon; friend class PhysicsCommon;

View File

@ -98,6 +98,9 @@ class BoxShape : public ConvexPolyhedronShape {
/// Return the local inertia tensor of the collision shape /// Return the local inertia tensor of the collision shape
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const override; virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const override;
/// Compute and return the volume of the collision shape
virtual decimal getVolume() const override;
/// Return the number of faces of the polyhedron /// Return the number of faces of the polyhedron
virtual uint getNbFaces() const override; virtual uint getNbFaces() const override;
@ -253,6 +256,11 @@ inline Vector3 BoxShape::getCentroid() const {
return Vector3::zero(); return Vector3::zero();
} }
// Compute and return the volume of the collision shape
inline decimal BoxShape::getVolume() const {
return 8 * mHalfExtents.x * mHalfExtents.y * mHalfExtents.z;
}
// Return the string representation of the shape // Return the string representation of the shape
inline std::string BoxShape::to_string() const { inline std::string BoxShape::to_string() const {
return "BoxShape{extents=" + mHalfExtents.to_string() + "}"; return "BoxShape{extents=" + mHalfExtents.to_string() + "}";

View File

@ -105,6 +105,9 @@ class CapsuleShape : public ConvexShape {
/// Return the local bounds of the shape in x, y and z directions /// Return the local bounds of the shape in x, y and z directions
virtual void getLocalBounds(Vector3& min, Vector3& max) const override; virtual void getLocalBounds(Vector3& min, Vector3& max) const override;
/// Compute and return the volume of the collision shape
virtual decimal getVolume() const override;
/// Return true if the collision shape is a polyhedron /// Return true if the collision shape is a polyhedron
virtual bool isPolyhedron() const override; virtual bool isPolyhedron() const override;
@ -188,6 +191,11 @@ inline void CapsuleShape::getLocalBounds(Vector3& min, Vector3& max) const {
min.z = min.x; min.z = min.x;
} }
// Compute and return the volume of the collision shape
inline decimal CapsuleShape::getVolume() const {
return reactphysics3d::PI * mMargin * mMargin * (decimal(4.0) * mMargin / decimal(3.0) + decimal(2.0) * mHalfHeight);
}
// Return true if the collision shape is a polyhedron // Return true if the collision shape is a polyhedron
inline bool CapsuleShape::isPolyhedron() const { inline bool CapsuleShape::isPolyhedron() const {
return false; return false;

View File

@ -30,6 +30,7 @@
#include <cassert> #include <cassert>
#include "configuration.h" #include "configuration.h"
#include "utils/Profiler.h" #include "utils/Profiler.h"
#include "containers/List.h"
/// ReactPhysics3D namespace /// ReactPhysics3D namespace
namespace reactphysics3d { namespace reactphysics3d {
@ -142,6 +143,9 @@ class CollisionShape {
/// Return the local inertia tensor of the collision shapes /// Return the local inertia tensor of the collision shapes
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const=0; virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const=0;
/// Compute and return the volume of the collision shape
virtual decimal getVolume() const=0;
/// Compute the world-space AABB of the collision shape given a transform /// Compute the world-space AABB of the collision shape given a transform
virtual void computeAABB(AABB& aabb, const Transform& transform) const; virtual void computeAABB(AABB& aabb, const Transform& transform) const;

View File

@ -36,3 +36,19 @@ ConcaveShape::ConcaveShape(CollisionShapeName name, MemoryAllocator& allocator,
mScale(scaling) { mScale(scaling) {
} }
// Compute and return the volume of the collision shape
/// Note that we approximate the volume of a concave shape with the volume of its AABB
decimal ConcaveShape::getVolume() const {
Vector3 minBounds, maxBounds;
// Compute the local bounds
getLocalBounds(minBounds, maxBounds);
const decimal lengthX = maxBounds.x - minBounds.x;
const decimal lengthY = maxBounds.y - minBounds.y;
const decimal lengthZ = maxBounds.z - minBounds.z;
// Approximate the volume of the concave shape as the volume of its AABB
return lengthX * lengthY * lengthZ;
}

View File

@ -111,6 +111,9 @@ class ConcaveShape : public CollisionShape {
virtual void computeOverlappingTriangles(const AABB& localAABB, List<Vector3>& triangleVertices, virtual void computeOverlappingTriangles(const AABB& localAABB, List<Vector3>& triangleVertices,
List<Vector3>& triangleVerticesNormals, List<uint>& shapeIds, List<Vector3>& triangleVerticesNormals, List<uint>& shapeIds,
MemoryAllocator& allocator) const=0; MemoryAllocator& allocator) const=0;
/// Compute and return the volume of the collision shape
virtual decimal getVolume() const override;
}; };
// Return true if the collision shape is convex, false if it is concave // Return true if the collision shape is convex, false if it is concave
@ -155,6 +158,7 @@ inline void ConcaveShape::setScale(const Vector3& scale) {
notifyColliderAboutChangedSize(); notifyColliderAboutChangedSize();
} }
} }
#endif #endif

View File

@ -135,6 +135,9 @@ class ConvexMeshShape : public ConvexPolyhedronShape {
/// Return the centroid of the polyhedron /// Return the centroid of the polyhedron
virtual Vector3 getCentroid() const override; virtual Vector3 getCentroid() const override;
/// Compute and return the volume of the collision shape
virtual decimal getVolume() const override;
/// Return the string representation of the shape /// Return the string representation of the shape
virtual std::string to_string() const override; virtual std::string to_string() const override;
@ -242,6 +245,12 @@ inline Vector3 ConvexMeshShape::getCentroid() const {
return mPolyhedronMesh->getCentroid() * mScale; return mPolyhedronMesh->getCentroid() * mScale;
} }
// Compute and return the volume of the collision shape
inline decimal ConvexMeshShape::getVolume() const {
return mPolyhedronMesh->getVolume();
}
} }
#endif #endif

View File

@ -93,6 +93,9 @@ class SphereShape : public ConvexShape {
/// Return the local inertia tensor of the collision shape /// Return the local inertia tensor of the collision shape
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const override; virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const override;
/// Compute and return the volume of the collision shape
virtual decimal getVolume() const override;
/// Update the AABB of a body using its collision shape /// Update the AABB of a body using its collision shape
virtual void computeAABB(AABB& aabb, const Transform& transform) const override; virtual void computeAABB(AABB& aabb, const Transform& transform) const override;
@ -180,6 +183,11 @@ inline void SphereShape::computeLocalInertiaTensor(Matrix3x3& tensor, decimal ma
0.0, 0.0, diag); 0.0, 0.0, diag);
} }
// Compute and return the volume of the collision shape
inline decimal SphereShape::getVolume() const {
return decimal(4.0) / decimal(3.0) * reactphysics3d::PI * mMargin * mMargin * mMargin;
}
// Return true if a point is inside the collision shape // Return true if a point is inside the collision shape
inline bool SphereShape::testPointInside(const Vector3& localPoint, Collider* collider) const { inline bool SphereShape::testPointInside(const Vector3& localPoint, Collider* collider) const {
return (localPoint.lengthSquare() < mMargin * mMargin); return (localPoint.lengthSquare() < mMargin * mMargin);

View File

@ -166,6 +166,9 @@ class TriangleShape : public ConvexPolyhedronShape {
/// Return the centroid of the polyhedron /// Return the centroid of the polyhedron
virtual Vector3 getCentroid() const override; virtual Vector3 getCentroid() const override;
/// Compute and return the volume of the collision shape
virtual decimal getVolume() const override;
/// This method compute the smooth mesh contact with a triangle in case one of the two collision shapes is a triangle. The idea in this case is to use a smooth vertex normal of the triangle mesh /// This method compute the smooth mesh contact with a triangle in case one of the two collision shapes is a triangle. The idea in this case is to use a smooth vertex normal of the triangle mesh
static void computeSmoothTriangleMeshContact(const CollisionShape* shape1, const CollisionShape* shape2, static void computeSmoothTriangleMeshContact(const CollisionShape* shape1, const CollisionShape* shape2,
Vector3& localContactPointShape1, Vector3& localContactPointShape2, Vector3& localContactPointShape1, Vector3& localContactPointShape2,
@ -304,6 +307,11 @@ inline std::string TriangleShape::to_string() const {
"v3=" + mPoints[2].to_string() + "}"; "v3=" + mPoints[2].to_string() + "}";
} }
// Compute and return the volume of the collision shape
inline decimal TriangleShape::getVolume() const {
return decimal(0.0);
}
} }
#endif #endif

View File

@ -35,8 +35,8 @@ using namespace reactphysics3d;
// Constructor // Constructor
ColliderComponents::ColliderComponents(MemoryAllocator& allocator) ColliderComponents::ColliderComponents(MemoryAllocator& allocator)
:Components(allocator, sizeof(Entity) + sizeof(Entity) + sizeof(Collider*) + sizeof(int) + :Components(allocator, sizeof(Entity) + sizeof(Entity) + sizeof(Collider*) + sizeof(int32) +
sizeof(Transform) + sizeof(CollisionShape*) + sizeof(decimal) + sizeof(unsigned short) + sizeof(Transform) + sizeof(CollisionShape*) + sizeof(unsigned short) +
sizeof(unsigned short) + sizeof(Transform) + sizeof(List<uint64>) + sizeof(bool)) { sizeof(unsigned short) + sizeof(Transform) + sizeof(List<uint64>) + sizeof(bool)) {
// Allocate memory for the components data // Allocate memory for the components data
@ -62,8 +62,7 @@ void ColliderComponents::allocate(uint32 nbComponentsToAllocate) {
int32* newBroadPhaseIds = reinterpret_cast<int32*>(newColliders + nbComponentsToAllocate); int32* newBroadPhaseIds = reinterpret_cast<int32*>(newColliders + nbComponentsToAllocate);
Transform* newLocalToBodyTransforms = reinterpret_cast<Transform*>(newBroadPhaseIds + nbComponentsToAllocate); Transform* newLocalToBodyTransforms = reinterpret_cast<Transform*>(newBroadPhaseIds + nbComponentsToAllocate);
CollisionShape** newCollisionShapes = reinterpret_cast<CollisionShape**>(newLocalToBodyTransforms + nbComponentsToAllocate); CollisionShape** newCollisionShapes = reinterpret_cast<CollisionShape**>(newLocalToBodyTransforms + nbComponentsToAllocate);
decimal* newMasses = reinterpret_cast<decimal*>(newCollisionShapes + nbComponentsToAllocate); unsigned short* newCollisionCategoryBits = reinterpret_cast<unsigned short*>(newCollisionShapes + nbComponentsToAllocate);
unsigned short* newCollisionCategoryBits = reinterpret_cast<unsigned short*>(newMasses + nbComponentsToAllocate);
unsigned short* newCollideWithMaskBits = reinterpret_cast<unsigned short*>(newCollisionCategoryBits + nbComponentsToAllocate); unsigned short* newCollideWithMaskBits = reinterpret_cast<unsigned short*>(newCollisionCategoryBits + nbComponentsToAllocate);
Transform* newLocalToWorldTransforms = reinterpret_cast<Transform*>(newCollideWithMaskBits + nbComponentsToAllocate); Transform* newLocalToWorldTransforms = reinterpret_cast<Transform*>(newCollideWithMaskBits + nbComponentsToAllocate);
List<uint64>* newOverlappingPairs = reinterpret_cast<List<uint64>*>(newLocalToWorldTransforms + nbComponentsToAllocate); List<uint64>* newOverlappingPairs = reinterpret_cast<List<uint64>*>(newLocalToWorldTransforms + nbComponentsToAllocate);
@ -79,7 +78,6 @@ void ColliderComponents::allocate(uint32 nbComponentsToAllocate) {
memcpy(newBroadPhaseIds, mBroadPhaseIds, mNbComponents * sizeof(int32)); memcpy(newBroadPhaseIds, mBroadPhaseIds, mNbComponents * sizeof(int32));
memcpy(newLocalToBodyTransforms, mLocalToBodyTransforms, mNbComponents * sizeof(Transform)); memcpy(newLocalToBodyTransforms, mLocalToBodyTransforms, mNbComponents * sizeof(Transform));
memcpy(newCollisionShapes, mCollisionShapes, mNbComponents * sizeof(CollisionShape*)); memcpy(newCollisionShapes, mCollisionShapes, mNbComponents * sizeof(CollisionShape*));
memcpy(newMasses, mMasses, mNbComponents * sizeof(decimal));
memcpy(newCollisionCategoryBits, mCollisionCategoryBits, mNbComponents * sizeof(unsigned short)); memcpy(newCollisionCategoryBits, mCollisionCategoryBits, mNbComponents * sizeof(unsigned short));
memcpy(newCollideWithMaskBits, mCollideWithMaskBits, mNbComponents * sizeof(unsigned short)); memcpy(newCollideWithMaskBits, mCollideWithMaskBits, mNbComponents * sizeof(unsigned short));
memcpy(newLocalToWorldTransforms, mLocalToWorldTransforms, mNbComponents * sizeof(Transform)); memcpy(newLocalToWorldTransforms, mLocalToWorldTransforms, mNbComponents * sizeof(Transform));
@ -98,7 +96,6 @@ void ColliderComponents::allocate(uint32 nbComponentsToAllocate) {
mBroadPhaseIds = newBroadPhaseIds; mBroadPhaseIds = newBroadPhaseIds;
mLocalToBodyTransforms = newLocalToBodyTransforms; mLocalToBodyTransforms = newLocalToBodyTransforms;
mCollisionShapes = newCollisionShapes; mCollisionShapes = newCollisionShapes;
mMasses = newMasses;
mCollisionCategoryBits = newCollisionCategoryBits; mCollisionCategoryBits = newCollisionCategoryBits;
mCollideWithMaskBits = newCollideWithMaskBits; mCollideWithMaskBits = newCollideWithMaskBits;
mLocalToWorldTransforms = newLocalToWorldTransforms; mLocalToWorldTransforms = newLocalToWorldTransforms;
@ -121,7 +118,6 @@ void ColliderComponents::addComponent(Entity colliderEntity, bool isSleeping, co
new (mBroadPhaseIds + index) int32(-1); new (mBroadPhaseIds + index) int32(-1);
new (mLocalToBodyTransforms + index) Transform(component.localToBodyTransform); new (mLocalToBodyTransforms + index) Transform(component.localToBodyTransform);
mCollisionShapes[index] = component.collisionShape; mCollisionShapes[index] = component.collisionShape;
new (mMasses + index) decimal(component.mass);
new (mCollisionCategoryBits + index) unsigned short(component.collisionCategoryBits); new (mCollisionCategoryBits + index) unsigned short(component.collisionCategoryBits);
new (mCollideWithMaskBits + index) unsigned short(component.collideWithMaskBits); new (mCollideWithMaskBits + index) unsigned short(component.collideWithMaskBits);
new (mLocalToWorldTransforms + index) Transform(component.localToWorldTransform); new (mLocalToWorldTransforms + index) Transform(component.localToWorldTransform);
@ -149,7 +145,6 @@ void ColliderComponents::moveComponentToIndex(uint32 srcIndex, uint32 destIndex)
new (mBroadPhaseIds + destIndex) int32(mBroadPhaseIds[srcIndex]); new (mBroadPhaseIds + destIndex) int32(mBroadPhaseIds[srcIndex]);
new (mLocalToBodyTransforms + destIndex) Transform(mLocalToBodyTransforms[srcIndex]); new (mLocalToBodyTransforms + destIndex) Transform(mLocalToBodyTransforms[srcIndex]);
mCollisionShapes[destIndex] = mCollisionShapes[srcIndex]; mCollisionShapes[destIndex] = mCollisionShapes[srcIndex];
new (mMasses + destIndex) decimal(mMasses[srcIndex]);
new (mCollisionCategoryBits + destIndex) unsigned short(mCollisionCategoryBits[srcIndex]); new (mCollisionCategoryBits + destIndex) unsigned short(mCollisionCategoryBits[srcIndex]);
new (mCollideWithMaskBits + destIndex) unsigned short(mCollideWithMaskBits[srcIndex]); new (mCollideWithMaskBits + destIndex) unsigned short(mCollideWithMaskBits[srcIndex]);
new (mLocalToWorldTransforms + destIndex) Transform(mLocalToWorldTransforms[srcIndex]); new (mLocalToWorldTransforms + destIndex) Transform(mLocalToWorldTransforms[srcIndex]);
@ -177,7 +172,6 @@ void ColliderComponents::swapComponents(uint32 index1, uint32 index2) {
int32 broadPhaseId1 = mBroadPhaseIds[index1]; int32 broadPhaseId1 = mBroadPhaseIds[index1];
Transform localToBodyTransform1 = mLocalToBodyTransforms[index1]; Transform localToBodyTransform1 = mLocalToBodyTransforms[index1];
CollisionShape* collisionShape1 = mCollisionShapes[index1]; CollisionShape* collisionShape1 = mCollisionShapes[index1];
decimal mass1 = mMasses[index1];
unsigned short collisionCategoryBits1 = mCollisionCategoryBits[index1]; unsigned short collisionCategoryBits1 = mCollisionCategoryBits[index1];
unsigned short collideWithMaskBits1 = mCollideWithMaskBits[index1]; unsigned short collideWithMaskBits1 = mCollideWithMaskBits[index1];
Transform localToWorldTransform1 = mLocalToWorldTransforms[index1]; Transform localToWorldTransform1 = mLocalToWorldTransforms[index1];
@ -196,7 +190,6 @@ void ColliderComponents::swapComponents(uint32 index1, uint32 index2) {
new (mBroadPhaseIds + index2) int32(broadPhaseId1); new (mBroadPhaseIds + index2) int32(broadPhaseId1);
new (mLocalToBodyTransforms + index2) Transform(localToBodyTransform1); new (mLocalToBodyTransforms + index2) Transform(localToBodyTransform1);
mCollisionShapes[index2] = collisionShape1; mCollisionShapes[index2] = collisionShape1;
new (mMasses + index2) decimal(mass1);
new (mCollisionCategoryBits + index2) unsigned short(collisionCategoryBits1); new (mCollisionCategoryBits + index2) unsigned short(collisionCategoryBits1);
new (mCollideWithMaskBits + index2) unsigned short(collideWithMaskBits1); new (mCollideWithMaskBits + index2) unsigned short(collideWithMaskBits1);
new (mLocalToWorldTransforms + index2) Transform(localToWorldTransform1); new (mLocalToWorldTransforms + index2) Transform(localToWorldTransform1);

View File

@ -73,9 +73,6 @@ class ColliderComponents : public Components {
/// Pointers to the collision shapes of the colliders /// Pointers to the collision shapes of the colliders
CollisionShape** mCollisionShapes; CollisionShape** mCollisionShapes;
/// Masses (in kilogramms) of the colliders
decimal* mMasses;
/// Array of bits used to define the collision category of this shape. /// Array of bits used to define the collision category of this shape.
/// You can set a single bit to one to define a category value for this /// You can set a single bit to one to define a category value for this
/// shape. This value is one (0x0001) by default. This variable can be used /// shape. This value is one (0x0001) by default. This variable can be used
@ -124,17 +121,16 @@ class ColliderComponents : public Components {
AABB localBounds; AABB localBounds;
const Transform& localToBodyTransform; const Transform& localToBodyTransform;
CollisionShape* collisionShape; CollisionShape* collisionShape;
decimal mass;
unsigned short collisionCategoryBits; unsigned short collisionCategoryBits;
unsigned short collideWithMaskBits; unsigned short collideWithMaskBits;
const Transform& localToWorldTransform; const Transform& localToWorldTransform;
/// Constructor /// Constructor
ColliderComponent(Entity bodyEntity, Collider* collider, AABB localBounds, const Transform& localToBodyTransform, ColliderComponent(Entity bodyEntity, Collider* collider, AABB localBounds, const Transform& localToBodyTransform,
CollisionShape* collisionShape, decimal mass, unsigned short collisionCategoryBits, CollisionShape* collisionShape, unsigned short collisionCategoryBits,
unsigned short collideWithMaskBits, const Transform& localToWorldTransform) unsigned short collideWithMaskBits, const Transform& localToWorldTransform)
:bodyEntity(bodyEntity), collider(collider), localBounds(localBounds), localToBodyTransform(localToBodyTransform), :bodyEntity(bodyEntity), collider(collider), localBounds(localBounds), localToBodyTransform(localToBodyTransform),
collisionShape(collisionShape), mass(mass), collisionCategoryBits(collisionCategoryBits), collideWithMaskBits(collideWithMaskBits), collisionShape(collisionShape), collisionCategoryBits(collisionCategoryBits), collideWithMaskBits(collideWithMaskBits),
localToWorldTransform(localToWorldTransform) { localToWorldTransform(localToWorldTransform) {
} }
@ -154,9 +150,6 @@ class ColliderComponents : public Components {
/// Return the body entity of a given collider /// Return the body entity of a given collider
Entity getBody(Entity colliderEntity) const; Entity getBody(Entity colliderEntity) const;
/// Return the mass of a collider
decimal getMass(Entity colliderEntity) const;
/// Return a pointer to a given collider /// Return a pointer to a given collider
Collider* getCollider(Entity colliderEntity) const; Collider* getCollider(Entity colliderEntity) const;
@ -218,14 +211,6 @@ inline Entity ColliderComponents::getBody(Entity colliderEntity) const {
return mBodiesEntities[mMapEntityToComponentIndex[colliderEntity]]; return mBodiesEntities[mMapEntityToComponentIndex[colliderEntity]];
} }
// Return the mass of a collider
inline decimal ColliderComponents::getMass(Entity colliderEntity) const {
assert(mMapEntityToComponentIndex.containsKey(colliderEntity));
return mMasses[mMapEntityToComponentIndex[colliderEntity]];
}
// Return a pointer to a given collider // Return a pointer to a given collider
inline Collider *ColliderComponents::getCollider(Entity colliderEntity) const { inline Collider *ColliderComponents::getCollider(Entity colliderEntity) const {

View File

@ -40,7 +40,7 @@ RigidBodyComponents::RigidBodyComponents(MemoryAllocator& allocator)
sizeof(Vector3) + sizeof(Vector3) + sizeof(Vector3) + sizeof(Vector3) + sizeof(Vector3) + sizeof(Vector3) +
sizeof(Vector3) + sizeof(decimal) + sizeof(decimal) + sizeof(Vector3) + sizeof(decimal) + sizeof(decimal) +
sizeof(decimal) + sizeof(decimal) + sizeof(Matrix3x3) + sizeof(decimal) + sizeof(decimal) + sizeof(Matrix3x3) +
sizeof(Vector3) + sizeof(Vector3) + sizeof(Matrix3x3) + sizeof(Vector3) + sizeof(Vector3) +
sizeof(Vector3) + sizeof(Vector3) + sizeof(Vector3) + sizeof(Vector3) + sizeof(Vector3) + sizeof(Vector3) +
sizeof(Quaternion) + sizeof(Vector3) + sizeof(Vector3) + sizeof(Quaternion) + sizeof(Vector3) + sizeof(Vector3) +
sizeof(bool) + sizeof(bool) + sizeof(List<Entity>)) { sizeof(bool) + sizeof(bool) + sizeof(List<Entity>)) {
@ -74,9 +74,10 @@ void RigidBodyComponents::allocate(uint32 nbComponentsToAllocate) {
Vector3* newExternalTorques = reinterpret_cast<Vector3*>(newExternalForces + nbComponentsToAllocate); Vector3* newExternalTorques = reinterpret_cast<Vector3*>(newExternalForces + nbComponentsToAllocate);
decimal* newLinearDampings = reinterpret_cast<decimal*>(newExternalTorques + nbComponentsToAllocate); decimal* newLinearDampings = reinterpret_cast<decimal*>(newExternalTorques + nbComponentsToAllocate);
decimal* newAngularDampings = reinterpret_cast<decimal*>(newLinearDampings + nbComponentsToAllocate); decimal* newAngularDampings = reinterpret_cast<decimal*>(newLinearDampings + nbComponentsToAllocate);
decimal* newInitMasses = reinterpret_cast<decimal*>(newAngularDampings + nbComponentsToAllocate); decimal* newMasses = reinterpret_cast<decimal*>(newAngularDampings + nbComponentsToAllocate);
decimal* newInverseMasses = reinterpret_cast<decimal*>(newInitMasses + nbComponentsToAllocate); decimal* newInverseMasses = reinterpret_cast<decimal*>(newMasses + nbComponentsToAllocate);
Matrix3x3* newInertiaTensorLocalInverses = reinterpret_cast<Matrix3x3*>(newInverseMasses + nbComponentsToAllocate); Matrix3x3* newInertiaTensorLocal = reinterpret_cast<Matrix3x3*>(newInverseMasses + nbComponentsToAllocate);
Matrix3x3* newInertiaTensorLocalInverses = reinterpret_cast<Matrix3x3*>(newInertiaTensorLocal + nbComponentsToAllocate);
Vector3* newConstrainedLinearVelocities = reinterpret_cast<Vector3*>(newInertiaTensorLocalInverses + nbComponentsToAllocate); Vector3* newConstrainedLinearVelocities = reinterpret_cast<Vector3*>(newInertiaTensorLocalInverses + nbComponentsToAllocate);
Vector3* newConstrainedAngularVelocities = reinterpret_cast<Vector3*>(newConstrainedLinearVelocities + nbComponentsToAllocate); Vector3* newConstrainedAngularVelocities = reinterpret_cast<Vector3*>(newConstrainedLinearVelocities + nbComponentsToAllocate);
Vector3* newSplitLinearVelocities = reinterpret_cast<Vector3*>(newConstrainedAngularVelocities + nbComponentsToAllocate); Vector3* newSplitLinearVelocities = reinterpret_cast<Vector3*>(newConstrainedAngularVelocities + nbComponentsToAllocate);
@ -105,8 +106,9 @@ void RigidBodyComponents::allocate(uint32 nbComponentsToAllocate) {
memcpy(newExternalTorques, mExternalTorques, mNbComponents * sizeof(Vector3)); memcpy(newExternalTorques, mExternalTorques, mNbComponents * sizeof(Vector3));
memcpy(newLinearDampings, mLinearDampings, mNbComponents * sizeof(decimal)); memcpy(newLinearDampings, mLinearDampings, mNbComponents * sizeof(decimal));
memcpy(newAngularDampings, mAngularDampings, mNbComponents * sizeof(decimal)); memcpy(newAngularDampings, mAngularDampings, mNbComponents * sizeof(decimal));
memcpy(newInitMasses, mInitMasses, mNbComponents * sizeof(decimal)); memcpy(newMasses, mMasses, mNbComponents * sizeof(decimal));
memcpy(newInverseMasses, mInverseMasses, mNbComponents * sizeof(decimal)); memcpy(newInverseMasses, mInverseMasses, mNbComponents * sizeof(decimal));
memcpy(newInertiaTensorLocal, mLocalInertiaTensors, mNbComponents * sizeof(Matrix3x3));
memcpy(newInertiaTensorLocalInverses, mInverseInertiaTensorsLocal, mNbComponents * sizeof(Matrix3x3)); memcpy(newInertiaTensorLocalInverses, mInverseInertiaTensorsLocal, mNbComponents * sizeof(Matrix3x3));
memcpy(newConstrainedLinearVelocities, mConstrainedLinearVelocities, mNbComponents * sizeof(Vector3)); memcpy(newConstrainedLinearVelocities, mConstrainedLinearVelocities, mNbComponents * sizeof(Vector3));
memcpy(newConstrainedAngularVelocities, mConstrainedAngularVelocities, mNbComponents * sizeof(Vector3)); memcpy(newConstrainedAngularVelocities, mConstrainedAngularVelocities, mNbComponents * sizeof(Vector3));
@ -138,8 +140,9 @@ void RigidBodyComponents::allocate(uint32 nbComponentsToAllocate) {
mExternalTorques = newExternalTorques; mExternalTorques = newExternalTorques;
mLinearDampings = newLinearDampings; mLinearDampings = newLinearDampings;
mAngularDampings = newAngularDampings; mAngularDampings = newAngularDampings;
mInitMasses = newInitMasses; mMasses = newMasses;
mInverseMasses = newInverseMasses; mInverseMasses = newInverseMasses;
mLocalInertiaTensors = newInertiaTensorLocal;
mInverseInertiaTensorsLocal = newInertiaTensorLocalInverses; mInverseInertiaTensorsLocal = newInertiaTensorLocalInverses;
mConstrainedLinearVelocities = newConstrainedLinearVelocities; mConstrainedLinearVelocities = newConstrainedLinearVelocities;
mConstrainedAngularVelocities = newConstrainedAngularVelocities; mConstrainedAngularVelocities = newConstrainedAngularVelocities;
@ -173,8 +176,9 @@ void RigidBodyComponents::addComponent(Entity bodyEntity, bool isSleeping, const
new (mExternalTorques + index) Vector3(0, 0, 0); new (mExternalTorques + index) Vector3(0, 0, 0);
mLinearDampings[index] = decimal(0.0); mLinearDampings[index] = decimal(0.0);
mAngularDampings[index] = decimal(0.0); mAngularDampings[index] = decimal(0.0);
mInitMasses[index] = decimal(1.0); mMasses[index] = decimal(1.0);
mInverseMasses[index] = decimal(1.0); mInverseMasses[index] = decimal(1.0);
new (mLocalInertiaTensors + index) Matrix3x3(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0);
new (mInverseInertiaTensorsLocal + index) Matrix3x3(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0); new (mInverseInertiaTensorsLocal + index) Matrix3x3(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0);
new (mConstrainedLinearVelocities + index) Vector3(0, 0, 0); new (mConstrainedLinearVelocities + index) Vector3(0, 0, 0);
new (mConstrainedAngularVelocities + index) Vector3(0, 0, 0); new (mConstrainedAngularVelocities + index) Vector3(0, 0, 0);
@ -216,8 +220,9 @@ void RigidBodyComponents::moveComponentToIndex(uint32 srcIndex, uint32 destIndex
new (mExternalTorques + destIndex) Vector3(mExternalTorques[srcIndex]); new (mExternalTorques + destIndex) Vector3(mExternalTorques[srcIndex]);
mLinearDampings[destIndex] = mLinearDampings[srcIndex]; mLinearDampings[destIndex] = mLinearDampings[srcIndex];
mAngularDampings[destIndex] = mAngularDampings[srcIndex]; mAngularDampings[destIndex] = mAngularDampings[srcIndex];
mInitMasses[destIndex] = mInitMasses[srcIndex]; mMasses[destIndex] = mMasses[srcIndex];
mInverseMasses[destIndex] = mInverseMasses[srcIndex]; mInverseMasses[destIndex] = mInverseMasses[srcIndex];
new (mLocalInertiaTensors + destIndex) Matrix3x3(mLocalInertiaTensors[srcIndex]);
new (mInverseInertiaTensorsLocal + destIndex) Matrix3x3(mInverseInertiaTensorsLocal[srcIndex]); new (mInverseInertiaTensorsLocal + destIndex) Matrix3x3(mInverseInertiaTensorsLocal[srcIndex]);
new (mConstrainedLinearVelocities + destIndex) Vector3(mConstrainedLinearVelocities[srcIndex]); new (mConstrainedLinearVelocities + destIndex) Vector3(mConstrainedLinearVelocities[srcIndex]);
new (mConstrainedAngularVelocities + destIndex) Vector3(mConstrainedAngularVelocities[srcIndex]); new (mConstrainedAngularVelocities + destIndex) Vector3(mConstrainedAngularVelocities[srcIndex]);
@ -258,8 +263,9 @@ void RigidBodyComponents::swapComponents(uint32 index1, uint32 index2) {
Vector3 externalTorque1(mExternalTorques[index1]); Vector3 externalTorque1(mExternalTorques[index1]);
decimal linearDamping1 = mLinearDampings[index1]; decimal linearDamping1 = mLinearDampings[index1];
decimal angularDamping1 = mAngularDampings[index1]; decimal angularDamping1 = mAngularDampings[index1];
decimal initMass1 = mInitMasses[index1]; decimal mass1 = mMasses[index1];
decimal inverseMass1 = mInverseMasses[index1]; decimal inverseMass1 = mInverseMasses[index1];
Matrix3x3 inertiaTensorLocal1 = mLocalInertiaTensors[index1];
Matrix3x3 inertiaTensorLocalInverse1 = mInverseInertiaTensorsLocal[index1]; Matrix3x3 inertiaTensorLocalInverse1 = mInverseInertiaTensorsLocal[index1];
Vector3 constrainedLinearVelocity1(mConstrainedLinearVelocities[index1]); Vector3 constrainedLinearVelocity1(mConstrainedLinearVelocities[index1]);
Vector3 constrainedAngularVelocity1(mConstrainedAngularVelocities[index1]); Vector3 constrainedAngularVelocity1(mConstrainedAngularVelocities[index1]);
@ -291,8 +297,9 @@ void RigidBodyComponents::swapComponents(uint32 index1, uint32 index2) {
new (mExternalTorques + index2) Vector3(externalTorque1); new (mExternalTorques + index2) Vector3(externalTorque1);
mLinearDampings[index2] = linearDamping1; mLinearDampings[index2] = linearDamping1;
mAngularDampings[index2] = angularDamping1; mAngularDampings[index2] = angularDamping1;
mInitMasses[index2] = initMass1; mMasses[index2] = mass1;
mInverseMasses[index2] = inverseMass1; mInverseMasses[index2] = inverseMass1;
mLocalInertiaTensors[index2] = inertiaTensorLocal1;
mInverseInertiaTensorsLocal[index2] = inertiaTensorLocalInverse1; mInverseInertiaTensorsLocal[index2] = inertiaTensorLocalInverse1;
new (mConstrainedLinearVelocities + index2) Vector3(constrainedLinearVelocity1); new (mConstrainedLinearVelocities + index2) Vector3(constrainedLinearVelocity1);
new (mConstrainedAngularVelocities + index2) Vector3(constrainedAngularVelocity1); new (mConstrainedAngularVelocities + index2) Vector3(constrainedAngularVelocity1);
@ -329,6 +336,7 @@ void RigidBodyComponents::destroyComponent(uint32 index) {
mAngularVelocities[index].~Vector3(); mAngularVelocities[index].~Vector3();
mExternalForces[index].~Vector3(); mExternalForces[index].~Vector3();
mExternalTorques[index].~Vector3(); mExternalTorques[index].~Vector3();
mLocalInertiaTensors[index].~Matrix3x3();
mInverseInertiaTensorsLocal[index].~Matrix3x3(); mInverseInertiaTensorsLocal[index].~Matrix3x3();
mConstrainedLinearVelocities[index].~Vector3(); mConstrainedLinearVelocities[index].~Vector3();
mConstrainedAngularVelocities[index].~Vector3(); mConstrainedAngularVelocities[index].~Vector3();

View File

@ -100,13 +100,17 @@ class RigidBodyComponents : public Components {
/// Array with the angular damping factor of each component /// Array with the angular damping factor of each component
decimal* mAngularDampings; decimal* mAngularDampings;
/// Array with the initial mass of each component /// Array with the mass of each component
decimal* mInitMasses; decimal* mMasses;
/// Array with the inverse mass of each component /// Array with the inverse mass of each component
decimal* mInverseMasses; decimal* mInverseMasses;
/// Array with the inertia tensor of each component
Matrix3x3* mLocalInertiaTensors;
/// Array with the inverse of the inertia tensor of each component /// Array with the inverse of the inertia tensor of each component
// TODO : We should use a Vector3 here for the diagonal instead of a Matrix3x3
Matrix3x3* mInverseInertiaTensorsLocal; Matrix3x3* mInverseInertiaTensorsLocal;
/// Array with the constrained linear velocity of each component /// Array with the constrained linear velocity of each component
@ -234,12 +238,24 @@ class RigidBodyComponents : public Components {
/// Return the angular damping factor of an entity /// Return the angular damping factor of an entity
decimal getAngularDamping(Entity bodyEntity) const; decimal getAngularDamping(Entity bodyEntity) const;
/// Return the initial mass of an entity /// Return the mass of an entity
decimal getInitMass(Entity bodyEntity) const; decimal getMass(Entity bodyEntity) const;
/// Set the mass of an entity
void setMass(Entity bodyEntity, decimal mass);
/// Return the mass inverse of an entity /// Return the mass inverse of an entity
decimal getMassInverse(Entity bodyEntity) const; decimal getMassInverse(Entity bodyEntity) const;
/// Set the inverse mass of an entity
void setMassInverse(Entity bodyEntity, decimal inverseMass);
/// Return the local inertia tensor of an entity
const Matrix3x3& getLocalInertiaTensor(Entity bodyEntity);
/// Set the local inertia tensor of an entity
void setLocalInertiaTensor(Entity bodyEntity, const Matrix3x3& inertiaTensorLocal);
/// Return the inverse local inertia tensor of an entity /// Return the inverse local inertia tensor of an entity
const Matrix3x3& getInertiaTensorLocalInverse(Entity bodyEntity); const Matrix3x3& getInertiaTensorLocalInverse(Entity bodyEntity);
@ -255,12 +271,6 @@ class RigidBodyComponents : public Components {
/// Set the angular damping factor of an entity /// Set the angular damping factor of an entity
void setAngularDamping(Entity bodyEntity, decimal angularDamping); void setAngularDamping(Entity bodyEntity, decimal angularDamping);
/// Set the initial mass of an entity
void setInitMass(Entity bodyEntity, decimal initMass);
/// Set the inverse mass of an entity
void setMassInverse(Entity bodyEntity, decimal inverseMass);
/// Set the inverse local inertia tensor of an entity /// Set the inverse local inertia tensor of an entity
void setInverseInertiaTensorLocal(Entity bodyEntity, const Matrix3x3& inertiaTensorLocalInverse); void setInverseInertiaTensorLocal(Entity bodyEntity, const Matrix3x3& inertiaTensorLocalInverse);
@ -484,12 +494,12 @@ inline decimal RigidBodyComponents::getAngularDamping(Entity bodyEntity) const {
return mAngularDampings[mMapEntityToComponentIndex[bodyEntity]]; return mAngularDampings[mMapEntityToComponentIndex[bodyEntity]];
} }
// Return the initial mass of an entity // Return the mass of an entity
inline decimal RigidBodyComponents::getInitMass(Entity bodyEntity) const { inline decimal RigidBodyComponents::getMass(Entity bodyEntity) const {
assert(mMapEntityToComponentIndex.containsKey(bodyEntity)); assert(mMapEntityToComponentIndex.containsKey(bodyEntity));
return mInitMasses[mMapEntityToComponentIndex[bodyEntity]]; return mMasses[mMapEntityToComponentIndex[bodyEntity]];
} }
// Return the inverse mass of an entity // Return the inverse mass of an entity
@ -540,12 +550,12 @@ inline void RigidBodyComponents::setAngularDamping(Entity bodyEntity, decimal an
mAngularDampings[mMapEntityToComponentIndex[bodyEntity]] = angularDamping; mAngularDampings[mMapEntityToComponentIndex[bodyEntity]] = angularDamping;
} }
// Set the initial mass of an entity // Set the mass of an entity
inline void RigidBodyComponents::setInitMass(Entity bodyEntity, decimal initMass) { inline void RigidBodyComponents::setMass(Entity bodyEntity, decimal mass) {
assert(mMapEntityToComponentIndex.containsKey(bodyEntity)); assert(mMapEntityToComponentIndex.containsKey(bodyEntity));
mInitMasses[mMapEntityToComponentIndex[bodyEntity]] = initMass; mMasses[mMapEntityToComponentIndex[bodyEntity]] = mass;
} }
// Set the mass inverse of an entity // Set the mass inverse of an entity
@ -556,6 +566,22 @@ inline void RigidBodyComponents::setMassInverse(Entity bodyEntity, decimal inver
mInverseMasses[mMapEntityToComponentIndex[bodyEntity]] = inverseMass; mInverseMasses[mMapEntityToComponentIndex[bodyEntity]] = inverseMass;
} }
// Return the local inertia tensor of an entity
inline const Matrix3x3& RigidBodyComponents::getLocalInertiaTensor(Entity bodyEntity) {
assert(mMapEntityToComponentIndex.containsKey(bodyEntity));
return mLocalInertiaTensors[mMapEntityToComponentIndex[bodyEntity]];
}
// Set the local inertia tensor of an entity
inline void RigidBodyComponents::setLocalInertiaTensor(Entity bodyEntity, const Matrix3x3& inertiaTensorLocal) {
assert(mMapEntityToComponentIndex.containsKey(bodyEntity));
mLocalInertiaTensors[mMapEntityToComponentIndex[bodyEntity]] = inertiaTensorLocal;
}
// Set the inverse local inertia tensor of an entity // Set the inverse local inertia tensor of an entity
inline void RigidBodyComponents::setInverseInertiaTensorLocal(Entity bodyEntity, const Matrix3x3& inertiaTensorLocalInverse) { inline void RigidBodyComponents::setInverseInertiaTensorLocal(Entity bodyEntity, const Matrix3x3& inertiaTensorLocalInverse) {

View File

@ -29,8 +29,9 @@
using namespace reactphysics3d; using namespace reactphysics3d;
// Constructor // Constructor
Material::Material(decimal frictionCoefficient, decimal rollingResistance, decimal bounciness) Material::Material(decimal frictionCoefficient, decimal rollingResistance, decimal bounciness, decimal massDensity)
: mFrictionCoefficient(frictionCoefficient), mRollingResistance(rollingResistance), mBounciness(bounciness) { : mFrictionCoefficient(frictionCoefficient), mRollingResistance(rollingResistance), mBounciness(bounciness),
mMassDensity(massDensity) {
} }

View File

@ -34,7 +34,7 @@ namespace reactphysics3d {
// Class Material // Class Material
/** /**
* This class contains the material properties of a rigid body that will be use for * This class contains the material properties of a collider that will be use for
* the dynamics simulation like the friction coefficient or the bounciness of the rigid * the dynamics simulation like the friction coefficient or the bounciness of the rigid
* body. * body.
*/ */
@ -53,10 +53,14 @@ class Material {
/// Bounciness during collisions (between 0 and 1) where 1 is for a very bouncy body /// Bounciness during collisions (between 0 and 1) where 1 is for a very bouncy body
decimal mBounciness; decimal mBounciness;
/// Density of mass used to compute the mass of the collider
decimal mMassDensity;
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
Material(decimal frictionCoefficient, decimal rollingResistance, decimal bounciness); Material(decimal frictionCoefficient, decimal rollingResistance, decimal bounciness,
decimal massDensity = decimal(1.0));
/// Copy-constructor /// Copy-constructor
Material(const Material& material); Material(const Material& material);
@ -86,6 +90,12 @@ class Material {
/// Set the rolling resistance factor /// Set the rolling resistance factor
void setRollingResistance(decimal rollingResistance); void setRollingResistance(decimal rollingResistance);
/// Return the mass density of the collider
decimal getMassDensity() const;
/// Set the mass density of the collider
void setMassDensity(decimal massDensity);
/// Return a string representation for the material /// Return a string representation for the material
std::string to_string() const; std::string to_string() const;
@ -156,6 +166,19 @@ inline void Material::setRollingResistance(decimal rollingResistance) {
mRollingResistance = rollingResistance; mRollingResistance = rollingResistance;
} }
// Return the mass density of the collider
inline decimal Material::getMassDensity() const {
return mMassDensity;
}
// Set the mass density of the collider
/**
* @param massDensity The mass density of the collider
*/
inline void Material::setMassDensity(decimal massDensity) {
mMassDensity = massDensity;
}
// Return a string representation for the material // Return a string representation for the material
inline std::string Material::to_string() const { inline std::string Material::to_string() const {

View File

@ -95,15 +95,26 @@ void PhysicsCommon::release() {
destroyTriangleMesh(*it); destroyTriangleMesh(*it);
} }
// If logging is enabled
#ifdef IS_LOGGING_ACTIVE
// Destroy the loggers // Destroy the loggers
for (auto it = mLoggers.begin(); it != mLoggers.end(); ++it) { for (auto it = mLoggers.begin(); it != mLoggers.end(); ++it) {
destroyLogger(*it); destroyLogger(*it);
} }
#endif
// If profiling is enabled
#ifdef IS_PROFILING_ACTIVE
// Destroy the profilers // Destroy the profilers
for (auto it = mProfilers.begin(); it != mProfilers.end(); ++it) { for (auto it = mProfilers.begin(); it != mProfilers.end(); ++it) {
destroyProfiler(*it); destroyProfiler(*it);
} }
#endif
} }
// Create and return an instance of PhysicsWorld // Create and return an instance of PhysicsWorld
@ -168,6 +179,10 @@ SphereShape* PhysicsCommon::createSphereShape(const decimal radius) {
// Destroy a sphere collision shape // Destroy a sphere collision shape
void PhysicsCommon::destroySphereShape(SphereShape* sphereShape) { void PhysicsCommon::destroySphereShape(SphereShape* sphereShape) {
// TODO Test if collision shape is still part of some colliders, if so throw error
assert(sphereShape->mColliders.size() == 0);
// Call the destructor of the shape // Call the destructor of the shape
sphereShape->~SphereShape(); sphereShape->~SphereShape();
@ -190,6 +205,10 @@ BoxShape* PhysicsCommon::createBoxShape(const Vector3& extent) {
// Destroy a box collision shape // Destroy a box collision shape
void PhysicsCommon::destroyBoxShape(BoxShape* boxShape) { void PhysicsCommon::destroyBoxShape(BoxShape* boxShape) {
// TODO Test if collision shape is still part of some colliders, if so throw error
assert(boxShape->mColliders.size() == 0);
// Call the destructor of the shape // Call the destructor of the shape
boxShape->~BoxShape(); boxShape->~BoxShape();
@ -212,6 +231,10 @@ CapsuleShape* PhysicsCommon::createCapsuleShape(decimal radius, decimal height)
// Destroy a capsule collision shape // Destroy a capsule collision shape
void PhysicsCommon::destroyCapsuleShape(CapsuleShape* capsuleShape) { void PhysicsCommon::destroyCapsuleShape(CapsuleShape* capsuleShape) {
// TODO Test if collision shape is still part of some colliders, if so throw error
assert(capsuleShape->mColliders.size() == 0);
// Call the destructor of the shape // Call the destructor of the shape
capsuleShape->~CapsuleShape(); capsuleShape->~CapsuleShape();
@ -234,6 +257,10 @@ ConvexMeshShape* PhysicsCommon::createConvexMeshShape(PolyhedronMesh* polyhedron
// Destroy a convex mesh shape // Destroy a convex mesh shape
void PhysicsCommon::destroyConvexMeshShape(ConvexMeshShape* convexMeshShape) { void PhysicsCommon::destroyConvexMeshShape(ConvexMeshShape* convexMeshShape) {
// TODO Test if collision shape is still part of some colliders, if so throw error
assert(convexMeshShape->mColliders.size() == 0);
// Call the destructor of the shape // Call the destructor of the shape
convexMeshShape->~ConvexMeshShape(); convexMeshShape->~ConvexMeshShape();
@ -259,6 +286,10 @@ HeightFieldShape* PhysicsCommon::createHeightFieldShape(int nbGridColumns, int n
// Destroy a height-field shape // Destroy a height-field shape
void PhysicsCommon::destroyHeightFieldShape(HeightFieldShape* heightFieldShape) { void PhysicsCommon::destroyHeightFieldShape(HeightFieldShape* heightFieldShape) {
// TODO Test if collision shape is still part of some colliders, if so throw error
assert(heightFieldShape->mColliders.size() == 0);
// Call the destructor of the shape // Call the destructor of the shape
heightFieldShape->~HeightFieldShape(); heightFieldShape->~HeightFieldShape();
@ -281,6 +312,10 @@ ConcaveMeshShape* PhysicsCommon::createConcaveMeshShape(TriangleMesh* triangleMe
// Destroy a concave mesh shape // Destroy a concave mesh shape
void PhysicsCommon::destroyConcaveMeshShape(ConcaveMeshShape* concaveMeshShape) { void PhysicsCommon::destroyConcaveMeshShape(ConcaveMeshShape* concaveMeshShape) {
// TODO Test if collision shape is still part of some colliders, if so throw error
assert(concaveMeshShape->mColliders.size() == 0);
// Call the destructor of the shape // Call the destructor of the shape
concaveMeshShape->~ConcaveMeshShape(); concaveMeshShape->~ConcaveMeshShape();
@ -334,6 +369,9 @@ void PhysicsCommon::destroyTriangleMesh(TriangleMesh* triangleMesh) {
mTriangleMeshes.remove(triangleMesh); mTriangleMeshes.remove(triangleMesh);
} }
// If logging is enabled
#ifdef IS_LOGGING_ACTIVE
// Create and return a new logger // Create and return a new logger
Logger* PhysicsCommon::createLogger() { Logger* PhysicsCommon::createLogger() {
@ -356,6 +394,11 @@ void PhysicsCommon::destroyLogger(Logger* logger) {
mLoggers.remove(logger); mLoggers.remove(logger);
} }
#endif
// If profiling is enabled
#ifdef IS_PROFILING_ACTIVE
// Create and return a new profiler // Create and return a new profiler
/// Note that you need to use a different profiler for each PhysicsWorld. /// Note that you need to use a different profiler for each PhysicsWorld.
Profiler* PhysicsCommon::createProfiler() { Profiler* PhysicsCommon::createProfiler() {
@ -378,3 +421,5 @@ void PhysicsCommon::destroyProfiler(Profiler* profiler) {
mProfilers.remove(profiler); mProfilers.remove(profiler);
} }
#endif

View File

@ -167,17 +167,28 @@ class PhysicsCommon {
/// Destroy a triangle mesh /// Destroy a triangle mesh
void destroyTriangleMesh(TriangleMesh* triangleMesh); void destroyTriangleMesh(TriangleMesh* triangleMesh);
// If logging is enabled
#ifdef IS_LOGGING_ACTIVE
/// Create and return a new logger /// Create and return a new logger
Logger* createLogger(); Logger* createLogger();
/// Destroy a logger /// Destroy a logger
void destroyLogger(Logger* logger); void destroyLogger(Logger* logger);
#endif
// If profiling is enabled
#ifdef IS_PROFILING_ACTIVE
/// Create and return a new profiler /// Create and return a new profiler
Profiler* createProfiler(); Profiler* createProfiler();
/// Destroy a profiler /// Destroy a profiler
void destroyProfiler(Profiler* profiler); void destroyProfiler(Profiler* profiler);
#endif
}; };
} }

View File

@ -209,7 +209,7 @@ void PhysicsWorld::destroyCollisionBody(CollisionBody* collisionBody) {
"Body " + std::to_string(collisionBody->getEntity().id) + ": collision body destroyed"); "Body " + std::to_string(collisionBody->getEntity().id) + ": collision body destroyed");
// Remove all the collision shapes of the body // Remove all the collision shapes of the body
collisionBody->removeAllCollisionShapes(); collisionBody->removeAllColliders();
mCollisionBodyComponents.removeComponent(collisionBody->getEntity()); mCollisionBodyComponents.removeComponent(collisionBody->getEntity());
mTransformComponents.removeComponent(collisionBody->getEntity()); mTransformComponents.removeComponent(collisionBody->getEntity());
@ -458,7 +458,7 @@ RigidBody* PhysicsWorld::createRigidBody(const Transform& transform) {
mRigidBodyComponents.addComponent(entity, false, rigidBodyComponent); mRigidBodyComponents.addComponent(entity, false, rigidBodyComponent);
// Compute the inverse mass // Compute the inverse mass
mRigidBodyComponents.setMassInverse(entity, decimal(1.0) / mRigidBodyComponents.getInitMass(entity)); mRigidBodyComponents.setMassInverse(entity, decimal(1.0) / mRigidBodyComponents.getMass(entity));
// Add the rigid body to the physics world // Add the rigid body to the physics world
mRigidBodies.add(rigidBody); mRigidBodies.add(rigidBody);
@ -488,7 +488,7 @@ void PhysicsWorld::destroyRigidBody(RigidBody* rigidBody) {
"Body " + std::to_string(rigidBody->getEntity().id) + ": rigid body destroyed"); "Body " + std::to_string(rigidBody->getEntity().id) + ": rigid body destroyed");
// Remove all the collision shapes of the body // Remove all the collision shapes of the body
rigidBody->removeAllCollisionShapes(); rigidBody->removeAllColliders();
// Destroy all the joints in which the rigid body to be destroyed is involved // Destroy all the joints in which the rigid body to be destroyed is involved
const List<Entity>& joints = mRigidBodyComponents.getJoints(rigidBody->getEntity()); const List<Entity>& joints = mRigidBodyComponents.getJoints(rigidBody->getEntity());

View File

@ -88,7 +88,7 @@ void DynamicsSystem::updateBodiesState() {
mTransformComponents.getTransform(mRigidBodyComponents.mBodiesEntities[i]).setOrientation(constrainedOrientation.getUnit()); mTransformComponents.getTransform(mRigidBodyComponents.mBodiesEntities[i]).setOrientation(constrainedOrientation.getUnit());
} }
// Update the transform of the body (using the new center of mass and new orientation) // Update the position of the body (using the new center of mass and new orientation)
for (uint32 i=0; i < mRigidBodyComponents.getNbEnabledComponents(); i++) { for (uint32 i=0; i < mRigidBodyComponents.getNbEnabledComponents(); i++) {
Transform& transform = mTransformComponents.getTransform(mRigidBodyComponents.mBodiesEntities[i]); Transform& transform = mTransformComponents.getTransform(mRigidBodyComponents.mBodiesEntities[i]);
@ -144,7 +144,7 @@ void DynamicsSystem::integrateRigidBodiesVelocities(decimal timeStep) {
// Integrate the gravity force // Integrate the gravity force
mRigidBodyComponents.mConstrainedLinearVelocities[i] = mRigidBodyComponents.mConstrainedLinearVelocities[i] + timeStep * mRigidBodyComponents.mConstrainedLinearVelocities[i] = mRigidBodyComponents.mConstrainedLinearVelocities[i] + timeStep *
mRigidBodyComponents.mInverseMasses[i] * mRigidBodyComponents.mInitMasses[i] * mGravity; mRigidBodyComponents.mInverseMasses[i] * mRigidBodyComponents.mMasses[i] * mGravity;
} }
} }
} }

View File

@ -461,6 +461,8 @@ class TestCollisionWorld : public Test {
/// Destructor /// Destructor
virtual ~TestCollisionWorld() { virtual ~TestCollisionWorld() {
mPhysicsCommon.destroyPhysicsWorld(mWorld);
mPhysicsCommon.destroyBoxShape(mBoxShape1); mPhysicsCommon.destroyBoxShape(mBoxShape1);
mPhysicsCommon.destroyBoxShape(mBoxShape2); mPhysicsCommon.destroyBoxShape(mBoxShape2);
@ -486,7 +488,6 @@ class TestCollisionWorld : public Test {
delete mConcaveMeshTriangleVertexArray; delete mConcaveMeshTriangleVertexArray;
mPhysicsCommon.destroyPhysicsWorld(mWorld);
} }
/// Run the tests /// Run the tests

View File

@ -176,11 +176,11 @@ class TestPointInside : public Test {
/// Destructor /// Destructor
virtual ~TestPointInside() { virtual ~TestPointInside() {
mPhysicsCommon.destroyPhysicsWorld(mWorld);
mPhysicsCommon.destroyBoxShape(mBoxShape); mPhysicsCommon.destroyBoxShape(mBoxShape);
mPhysicsCommon.destroySphereShape(mSphereShape); mPhysicsCommon.destroySphereShape(mSphereShape);
mPhysicsCommon.destroyCapsuleShape(mCapsuleShape); mPhysicsCommon.destroyCapsuleShape(mCapsuleShape);
mPhysicsCommon.destroyConvexMeshShape(mConvexMeshShape); mPhysicsCommon.destroyConvexMeshShape(mConvexMeshShape);
mPhysicsCommon.destroyPhysicsWorld(mWorld);
mPhysicsCommon.destroyPolyhedronMesh(mConvexMeshPolyhedronMesh); mPhysicsCommon.destroyPolyhedronMesh(mConvexMeshPolyhedronMesh);
delete[] mConvexMeshPolygonFaces; delete[] mConvexMeshPolygonFaces;
delete mConvexMeshPolygonVertexArray; delete mConvexMeshPolygonVertexArray;

View File

@ -304,6 +304,7 @@ class TestRaycast : public Test {
/// Destructor /// Destructor
virtual ~TestRaycast() { virtual ~TestRaycast() {
mPhysicsCommon.destroyPhysicsWorld(mWorld);
mPhysicsCommon.destroyBoxShape(mBoxShape); mPhysicsCommon.destroyBoxShape(mBoxShape);
mPhysicsCommon.destroySphereShape(mSphereShape); mPhysicsCommon.destroySphereShape(mSphereShape);
mPhysicsCommon.destroyCapsuleShape(mCapsuleShape); mPhysicsCommon.destroyCapsuleShape(mCapsuleShape);
@ -311,7 +312,6 @@ class TestRaycast : public Test {
mPhysicsCommon.destroyConcaveMeshShape(mConcaveMeshShape); mPhysicsCommon.destroyConcaveMeshShape(mConcaveMeshShape);
mPhysicsCommon.destroyHeightFieldShape(mHeightFieldShape); mPhysicsCommon.destroyHeightFieldShape(mHeightFieldShape);
mPhysicsCommon.destroyPhysicsWorld(mWorld);
delete mConcaveMeshVertexArray; delete mConcaveMeshVertexArray;
delete mPolygonVertexArray; delete mPolygonVertexArray;

View File

@ -38,49 +38,7 @@ openglframework::VertexArrayObject Box::mVAO;
int Box::totalNbBoxes = 0; int Box::totalNbBoxes = 0;
// Constructor // Constructor
Box::Box(const openglframework::Vector3& size, reactphysics3d::PhysicsCommon& physicsCommon, reactphysics3d::PhysicsWorld* world, Box::Box(bool createRigidBody, const openglframework::Vector3& size, reactphysics3d::PhysicsCommon& physicsCommon, reactphysics3d::PhysicsWorld* world,
const std::string& meshFolderPath)
: PhysicsObject(physicsCommon, meshFolderPath + "cube.obj") {
// Initialize the size of the box
mSize[0] = size.x * 0.5f;
mSize[1] = size.y * 0.5f;
mSize[2] = size.z * 0.5f;
// Compute the scaling matrix
mScalingMatrix = openglframework::Matrix4(mSize[0], 0, 0, 0,
0, mSize[1], 0, 0,
0, 0, mSize[2], 0,
0, 0, 0, 1);
// Create the collision shape for the rigid body (box shape)
// ReactPhysics3D will clone this object to create an internal one. Therefore,
// it is OK if this object is destroyed right after calling RigidBody::addCollisionShape()
mBoxShape = mPhysicsCommon.createBoxShape(rp3d::Vector3(mSize[0], mSize[1], mSize[2]));
//mBoxShape->setLocalScaling(rp3d::Vector3(2, 2, 2));
mPreviousTransform = rp3d::Transform::identity();
// Create a rigid body in the physics world
mBody = world->createCollisionBody(mPreviousTransform);
// Add the collision shape to the body
mCollider = mBody->addCollider(mBoxShape, rp3d::Transform::identity());
// If the Vertex Buffer object has not been created yet
if (totalNbBoxes == 0) {
// Create the Vertex Buffer
createVBOAndVAO();
}
totalNbBoxes++;
mTransformMatrix = mTransformMatrix * mScalingMatrix;
}
// Constructor
Box::Box(const openglframework::Vector3& size, float mass, reactphysics3d::PhysicsCommon &physicsCommon, reactphysics3d::PhysicsWorld* world,
const std::string& meshFolderPath) const std::string& meshFolderPath)
: PhysicsObject(physicsCommon, meshFolderPath + "cube.obj") { : PhysicsObject(physicsCommon, meshFolderPath + "cube.obj") {
@ -102,13 +60,20 @@ Box::Box(const openglframework::Vector3& size, float mass, reactphysics3d::Physi
mPreviousTransform = rp3d::Transform::identity(); mPreviousTransform = rp3d::Transform::identity();
if (createRigidBody) {
// Create a rigid body in the physics world // Create a rigid body in the physics world
rp3d::RigidBody* body = world->createRigidBody(mPreviousTransform); rp3d::RigidBody* body = world->createRigidBody(mPreviousTransform);
mCollider = body->addCollider(mBoxShape, rp3d::Transform::identity());
// Add the collision shape to the body body->updateMassPropertiesFromColliders();
mCollider = body->addCollider(mBoxShape, rp3d::Transform::identity(), mass);
mBody = body; mBody = body;
}
else {
// Create a body in the physics world
mBody = world->createCollisionBody(mPreviousTransform);
mCollider = mBody->addCollider(mBoxShape, rp3d::Transform::identity());
}
// If the Vertex Buffer object has not been created yet // If the Vertex Buffer object has not been created yet
if (totalNbBoxes == 0) { if (totalNbBoxes == 0) {

View File

@ -75,12 +75,9 @@ class Box : public PhysicsObject {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
Box(const openglframework::Vector3& size, reactphysics3d::PhysicsCommon& physicsCommon, Box(bool createRigidBody, const openglframework::Vector3& size, reactphysics3d::PhysicsCommon& physicsCommon,
reactphysics3d::PhysicsWorld* world, const std::string& meshFolderPath); reactphysics3d::PhysicsWorld* world, const std::string& meshFolderPath);
/// Constructor
Box(const openglframework::Vector3& size, float mass, reactphysics3d::PhysicsCommon& physicsCommon, reactphysics3d::PhysicsWorld *world, const std::string& meshFolderPath);
/// Destructor /// Destructor
virtual ~Box() override; virtual ~Box() override;

View File

@ -34,7 +34,7 @@ openglframework::VertexArrayObject Capsule::mVAO;
int Capsule::totalNbCapsules = 0; int Capsule::totalNbCapsules = 0;
// Constructor // Constructor
Capsule::Capsule(bool createRigidBody, float radius, float height, float mass, reactphysics3d::PhysicsCommon &physicsCommon, rp3d::PhysicsWorld* physicsWorld, Capsule::Capsule(bool createRigidBody, float radius, float height, reactphysics3d::PhysicsCommon &physicsCommon, rp3d::PhysicsWorld* physicsWorld,
const std::string& meshFolderPath) const std::string& meshFolderPath)
: PhysicsObject(physicsCommon, meshFolderPath + "capsule.obj"), mRadius(radius), mHeight(height) { : PhysicsObject(physicsCommon, meshFolderPath + "capsule.obj"), mRadius(radius), mHeight(height) {
@ -55,18 +55,14 @@ Capsule::Capsule(bool createRigidBody, float radius, float height, float mass, r
if (createRigidBody) { if (createRigidBody) {
rp3d::RigidBody* body = physicsWorld->createRigidBody(mPreviousTransform); rp3d::RigidBody* body = physicsWorld->createRigidBody(mPreviousTransform);
mCollider = body->addCollider(mCapsuleShape, rp3d::Transform::identity());
// Add a collision shape to the body and specify the mass of the shape body->updateMassPropertiesFromColliders();
mCollider = body->addCollider(mCapsuleShape, rp3d::Transform::identity(), mass);
mBody = body; mBody = body;
} }
else { else {
// Create a rigid body corresponding in the physics world // Create a rigid body corresponding in the physics world
mBody = physicsWorld->createCollisionBody(mPreviousTransform); mBody = physicsWorld->createCollisionBody(mPreviousTransform);
// Add a collision shape to the body and specify the mass of the shape
mCollider = mBody->addCollider(mCapsuleShape, rp3d::Transform::identity()); mCollider = mBody->addCollider(mCapsuleShape, rp3d::Transform::identity());
} }

View File

@ -79,7 +79,7 @@ class Capsule : public PhysicsObject {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
Capsule(bool createRigidBody, float radius, float height, float mass, reactphysics3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* physicsWorld, Capsule(bool createRigidBody, float radius, float height, reactphysics3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* physicsWorld,
const std::string& meshFolderPath); const std::string& meshFolderPath);
/// Destructor /// Destructor

View File

@ -27,7 +27,7 @@
#include "ConcaveMesh.h" #include "ConcaveMesh.h"
// Constructor // Constructor
ConcaveMesh::ConcaveMesh(bool createRigidBody, float mass, reactphysics3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* physicsWorld, const std::string& meshPath) ConcaveMesh::ConcaveMesh(bool createRigidBody, reactphysics3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* physicsWorld, const std::string& meshPath)
: PhysicsObject(physicsCommon, meshPath), mVBOVertices(GL_ARRAY_BUFFER), : PhysicsObject(physicsCommon, meshPath), mVBOVertices(GL_ARRAY_BUFFER),
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER),
mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) { mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) {
@ -60,7 +60,8 @@ ConcaveMesh::ConcaveMesh(bool createRigidBody, float mass, reactphysics3d::Physi
// Create the body // Create the body
if (createRigidBody) { if (createRigidBody) {
rp3d::RigidBody* body = physicsWorld->createRigidBody(mPreviousTransform); rp3d::RigidBody* body = physicsWorld->createRigidBody(mPreviousTransform);
mCollider = body->addCollider(mConcaveShape, rp3d::Transform::identity(), mass); mCollider = body->addCollider(mConcaveShape, rp3d::Transform::identity());
body->updateMassPropertiesFromColliders();
mBody = body; mBody = body;
} }
else { else {

View File

@ -73,7 +73,7 @@ class ConcaveMesh : public PhysicsObject {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
ConcaveMesh(bool createRigidBody, float mass, reactphysics3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* physicsWorld, const std::string& meshPath); ConcaveMesh(bool createRigidBody, reactphysics3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* physicsWorld, const std::string& meshPath);
/// Destructor /// Destructor
virtual ~ConcaveMesh() override; virtual ~ConcaveMesh() override;

View File

@ -28,7 +28,7 @@
#include <unordered_set> #include <unordered_set>
// Constructor // Constructor
ConvexMesh::ConvexMesh(bool createRigidBody, float mass, rp3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* physicsWorld, const std::string& meshPath) ConvexMesh::ConvexMesh(bool createRigidBody, rp3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* physicsWorld, const std::string& meshPath)
: PhysicsObject(physicsCommon, meshPath), mVBOVertices(GL_ARRAY_BUFFER), : PhysicsObject(physicsCommon, meshPath), mVBOVertices(GL_ARRAY_BUFFER),
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER),
mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) { mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) {
@ -39,7 +39,7 @@ ConvexMesh::ConvexMesh(bool createRigidBody, float mass, rp3d::PhysicsCommon& ph
// Polygon faces descriptions for the polyhedron // Polygon faces descriptions for the polyhedron
mPolygonFaces = new rp3d::PolygonVertexArray::PolygonFace[getNbFaces(0)]; mPolygonFaces = new rp3d::PolygonVertexArray::PolygonFace[getNbFaces(0)];
rp3d::PolygonVertexArray::PolygonFace* face = mPolygonFaces; rp3d::PolygonVertexArray::PolygonFace* face = mPolygonFaces;
for (int f=0; f < getNbFaces(0); f++) { for (uint f=0; f < getNbFaces(0); f++) {
for (int v = 0; v < 3; v++) { for (int v = 0; v < 3; v++) {
@ -78,7 +78,8 @@ ConvexMesh::ConvexMesh(bool createRigidBody, float mass, rp3d::PhysicsCommon& ph
// Create a rigid body corresponding to the sphere in the physics world // Create a rigid body corresponding to the sphere in the physics world
if (createRigidBody) { if (createRigidBody) {
rp3d::RigidBody* body = physicsWorld->createRigidBody(mPreviousTransform); rp3d::RigidBody* body = physicsWorld->createRigidBody(mPreviousTransform);
mCollider = body->addCollider(mConvexShape, rp3d::Transform::identity(), mass); mCollider = body->addCollider(mConvexShape, rp3d::Transform::identity());
body->updateMassPropertiesFromColliders();
mBody = body; mBody = body;
} }
else { else {
@ -87,6 +88,7 @@ ConvexMesh::ConvexMesh(bool createRigidBody, float mass, rp3d::PhysicsCommon& ph
mCollider = mBody->addCollider(mConvexShape, rp3d::Transform::identity()); mCollider = mBody->addCollider(mConvexShape, rp3d::Transform::identity());
} }
// Create the VBOs and VAO // Create the VBOs and VAO
createVBOAndVAO(); createVBOAndVAO();

View File

@ -86,7 +86,7 @@ class ConvexMesh : public PhysicsObject {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
ConvexMesh(bool createRigidBody, float mass, rp3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* physicsWorld, const std::string& meshPath); ConvexMesh(bool createRigidBody, rp3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* physicsWorld, const std::string& meshPath);
/// Destructor /// Destructor
virtual ~ConvexMesh() override; virtual ~ConvexMesh() override;

View File

@ -46,7 +46,6 @@ Dumbbell::Dumbbell(bool createRigidBody, rp3d::PhysicsCommon& physicsCommon, rp3
// ReactPhysics3D will clone this object to create an internal one. Therefore, // ReactPhysics3D will clone this object to create an internal one. Therefore,
// it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape()
const rp3d::decimal radiusSphere = rp3d::decimal(1.5); const rp3d::decimal radiusSphere = rp3d::decimal(1.5);
const rp3d::decimal massSphere = rp3d::decimal(2.0);
mSphereShape = mPhysicsCommon.createSphereShape(radiusSphere); mSphereShape = mPhysicsCommon.createSphereShape(radiusSphere);
// Create a capsule collision shape for the middle of the dumbbell // Create a capsule collision shape for the middle of the dumbbell
@ -54,7 +53,6 @@ Dumbbell::Dumbbell(bool createRigidBody, rp3d::PhysicsCommon& physicsCommon, rp3
// it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape()
const rp3d::decimal radiusCapsule = rp3d::decimal(0.5); const rp3d::decimal radiusCapsule = rp3d::decimal(0.5);
const rp3d::decimal heightCapsule = rp3d::decimal(7.0); const rp3d::decimal heightCapsule = rp3d::decimal(7.0);
const rp3d::decimal massCylinder = rp3d::decimal(1.0);
mCapsuleShape = mPhysicsCommon.createCapsuleShape(radiusCapsule, heightCapsule); mCapsuleShape = mPhysicsCommon.createCapsuleShape(radiusCapsule, heightCapsule);
mPreviousTransform = rp3d::Transform::identity(); mPreviousTransform = rp3d::Transform::identity();
@ -71,26 +69,24 @@ Dumbbell::Dumbbell(bool createRigidBody, rp3d::PhysicsCommon& physicsCommon, rp3
// Create a body corresponding to the dumbbell in the physics world // Create a body corresponding to the dumbbell in the physics world
if (createRigidBody) { if (createRigidBody) {
rp3d::RigidBody* body; rp3d::RigidBody* body = physicsWorld->createRigidBody(mPreviousTransform);
body = physicsWorld->createRigidBody(mPreviousTransform); mColliderSphere1 = body->addCollider(mSphereShape, transformSphereShape1);
mColliderSphere2 = body->addCollider(mSphereShape, transformSphereShape2);
// Add the three collision shapes to the body and specify the mass and transform of the shapes mColliderCapsule = body->addCollider(mCapsuleShape, transformCylinderShape);
mColliderSphere1 = body->addCollider(mSphereShape, transformSphereShape1, massSphere); mColliderSphere1->getMaterial().setMassDensity(2);
mColliderSphere2 = body->addCollider(mSphereShape, transformSphereShape2, massSphere); mColliderSphere2->getMaterial().setMassDensity(2);
mColliderCapsule = body->addCollider(mCapsuleShape, transformCylinderShape, massCylinder); body->updateMassPropertiesFromColliders();
mBody = body; mBody = body;
} }
else { else {
mBody = physicsWorld->createCollisionBody(mPreviousTransform); mBody = physicsWorld->createCollisionBody(mPreviousTransform);
// Add the three collision shapes to the body and specify the mass and transform of the shapes
mColliderSphere1 = mBody->addCollider(mSphereShape, transformSphereShape1); mColliderSphere1 = mBody->addCollider(mSphereShape, transformSphereShape1);
mColliderSphere2 = mBody->addCollider(mSphereShape, transformSphereShape2); mColliderSphere2 = mBody->addCollider(mSphereShape, transformSphereShape2);
mColliderCapsule = mBody->addCollider(mCapsuleShape, transformCylinderShape); mColliderCapsule = mBody->addCollider(mCapsuleShape, transformCylinderShape);
} }
mTransformMatrix = mTransformMatrix * mScalingMatrix; mTransformMatrix = mTransformMatrix * mScalingMatrix;
// Create the VBOs and VAO // Create the VBOs and VAO

View File

@ -28,7 +28,7 @@
#include "PerlinNoise.h" #include "PerlinNoise.h"
// Constructor // Constructor
HeightField::HeightField(bool createRigidBody, float mass, reactphysics3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* physicsWorld) HeightField::HeightField(bool createRigidBody, reactphysics3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* physicsWorld)
: PhysicsObject(physicsCommon), mVBOVertices(GL_ARRAY_BUFFER), : PhysicsObject(physicsCommon), mVBOVertices(GL_ARRAY_BUFFER),
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER),
mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) { mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) {
@ -54,7 +54,8 @@ HeightField::HeightField(bool createRigidBody, float mass, reactphysics3d::Physi
// Create a body // Create a body
if (createRigidBody) { if (createRigidBody) {
rp3d::RigidBody* body = physicsWorld->createRigidBody(mPreviousTransform); rp3d::RigidBody* body = physicsWorld->createRigidBody(mPreviousTransform);
mCollider = body->addCollider(mHeightFieldShape, rp3d::Transform::identity(), mass); mCollider = body->addCollider(mHeightFieldShape, rp3d::Transform::identity());
body->updateMassPropertiesFromColliders();
mBody = body; mBody = body;
} }
else { else {
@ -62,6 +63,7 @@ HeightField::HeightField(bool createRigidBody, float mass, reactphysics3d::Physi
mCollider = mBody->addCollider(mHeightFieldShape, rp3d::Transform::identity()); mCollider = mBody->addCollider(mHeightFieldShape, rp3d::Transform::identity());
} }
// Create the VBOs and VAO // Create the VBOs and VAO
createVBOAndVAO(); createVBOAndVAO();

View File

@ -86,7 +86,7 @@ class HeightField : public PhysicsObject {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
HeightField(bool createRigidBody, float mass, rp3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* physicsWorld); HeightField(bool createRigidBody, rp3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* physicsWorld);
/// Destructor /// Destructor
virtual ~HeightField() override; virtual ~HeightField() override;

View File

@ -34,42 +34,7 @@ openglframework::VertexArrayObject Sphere::mVAO;
int Sphere::totalNbSpheres = 0; int Sphere::totalNbSpheres = 0;
// Constructor // Constructor
Sphere::Sphere(float radius, rp3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* world, Sphere::Sphere(bool createRigidBody, float radius, rp3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* world,
const std::string& meshFolderPath)
: PhysicsObject(physicsCommon, meshFolderPath + "sphere.obj"), mRadius(radius) {
// Compute the scaling matrix
mScalingMatrix = openglframework::Matrix4(mRadius, 0, 0, 0,
0, mRadius, 0, 0,
0, 0, mRadius, 0,
0, 0, 0, 1);
// Create the collision shape for the rigid body (sphere shape)
// ReactPhysics3D will clone this object to create an internal one. Therefore,
// it is OK if this object is destroyed right after calling RigidBody::addCollisionShape()
mCollisionShape = mPhysicsCommon.createSphereShape(mRadius);
//mCollisionShape->setLocalScaling(rp3d::Vector3(2, 2, 2));
mPreviousTransform = rp3d::Transform::identity();
// Create a rigid body corresponding to the sphere in the physics world
mBody = world->createCollisionBody(mPreviousTransform);
// Add a collision shape to the body and specify the mass of the shape
mCollider = mBody->addCollider(mCollisionShape, rp3d::Transform::identity());
mTransformMatrix = mTransformMatrix * mScalingMatrix;
// Create the VBOs and VAO
if (totalNbSpheres == 0) {
createVBOAndVAO();
}
totalNbSpheres++;
}
// Constructor
Sphere::Sphere(float radius, float mass, rp3d::PhysicsCommon& physicsCommon,reactphysics3d::PhysicsWorld* world,
const std::string& meshFolderPath) const std::string& meshFolderPath)
: PhysicsObject(physicsCommon, meshFolderPath + "sphere.obj"), mRadius(radius) { : PhysicsObject(physicsCommon, meshFolderPath + "sphere.obj"), mRadius(radius) {
@ -86,13 +51,20 @@ Sphere::Sphere(float radius, float mass, rp3d::PhysicsCommon& physicsCommon,rea
mPreviousTransform = rp3d::Transform::identity(); mPreviousTransform = rp3d::Transform::identity();
if (createRigidBody) {
// Create a rigid body corresponding to the sphere in the physics world // Create a rigid body corresponding to the sphere in the physics world
rp3d::RigidBody* body = world->createRigidBody(mPreviousTransform); rp3d::RigidBody* body = world->createRigidBody(mPreviousTransform);
mCollider = body->addCollider(mCollisionShape, rp3d::Transform::identity());
// Add a collision shape to the body and specify the mass of the shape body->updateMassPropertiesFromColliders();
mCollider = body->addCollider(mCollisionShape, rp3d::Transform::identity(), mass);
mBody = body; mBody = body;
}
else {
// Create a body corresponding to the sphere in the physics world
mBody = world->createCollisionBody(mPreviousTransform);
mCollider = mBody->addCollider(mCollisionShape, rp3d::Transform::identity());
}
mTransformMatrix = mTransformMatrix * mScalingMatrix; mTransformMatrix = mTransformMatrix * mScalingMatrix;

View File

@ -76,10 +76,7 @@ class Sphere : public PhysicsObject {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
Sphere(float radius, rp3d::PhysicsCommon& physicsCommon, reactphysics3d::PhysicsWorld* world, const std::string& meshFolderPath); Sphere(bool createRigidBody, float radius, rp3d::PhysicsCommon& physicsCommon, reactphysics3d::PhysicsWorld* world, const std::string& meshFolderPath);
/// Constructor
Sphere(float radius, float mass, reactphysics3d::PhysicsCommon &physicsCommon, rp3d::PhysicsWorld* physicsWorld, const std::string& meshFolderPath);
/// Destructor /// Destructor
virtual ~Sphere() override; virtual ~Sphere() override;

View File

@ -57,7 +57,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine
// ---------- Sphere 1 ---------- // // ---------- Sphere 1 ---------- //
// Create a sphere and a corresponding collision body in the physics world // Create a sphere and a corresponding collision body in the physics world
mSphere1 = new Sphere(4, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); mSphere1 = new Sphere(false, 4, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
mAllShapes.push_back(mSphere1); mAllShapes.push_back(mSphere1);
// Set the color // Set the color
@ -69,7 +69,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine
// ---------- Sphere 2 ---------- // // ---------- Sphere 2 ---------- //
// Create a sphere and a corresponding collision body in the physics world // Create a sphere and a corresponding collision body in the physics world
mSphere2 = new Sphere(2, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); mSphere2 = new Sphere(false, 2, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
mAllShapes.push_back(mSphere2); mAllShapes.push_back(mSphere2);
// Set the color // Set the color
@ -81,7 +81,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine
// ---------- Capsule 1 ---------- // // ---------- Capsule 1 ---------- //
// Create a cylinder and a corresponding collision body in the physics world // Create a cylinder and a corresponding collision body in the physics world
mCapsule1 = new Capsule(false, CAPSULE_RADIUS, CAPSULE_HEIGHT, 1.0, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); mCapsule1 = new Capsule(false, CAPSULE_RADIUS, CAPSULE_HEIGHT, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
mAllShapes.push_back(mCapsule1); mAllShapes.push_back(mCapsule1);
// Set the color // Set the color
@ -92,7 +92,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine
// ---------- Capsule 2 ---------- // // ---------- Capsule 2 ---------- //
// Create a cylinder and a corresponding collision body in the physics world // Create a cylinder and a corresponding collision body in the physics world
mCapsule2 = new Capsule(false, CAPSULE_RADIUS, CAPSULE_HEIGHT, 1.0, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); mCapsule2 = new Capsule(false, CAPSULE_RADIUS, CAPSULE_HEIGHT, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
mAllShapes.push_back(mCapsule2); mAllShapes.push_back(mCapsule2);
// Set the color // Set the color
@ -103,7 +103,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine
// ---------- Concave Mesh ---------- // // ---------- Concave Mesh ---------- //
// Create a convex mesh and a corresponding collision body in the physics world // Create a convex mesh and a corresponding collision body in the physics world
mConcaveMesh = new ConcaveMesh(false, 1.0f, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath + "city.obj"); mConcaveMesh = new ConcaveMesh(false, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath + "city.obj");
mAllShapes.push_back(mConcaveMesh); mAllShapes.push_back(mConcaveMesh);
// Set the color // Set the color
@ -114,7 +114,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine
// ---------- Box 1 ---------- // // ---------- Box 1 ---------- //
// Create a cylinder and a corresponding collision body in the physics world // Create a cylinder and a corresponding collision body in the physics world
mBox1 = new Box(BOX_SIZE, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); mBox1 = new Box(false, BOX_SIZE, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
mAllShapes.push_back(mBox1); mAllShapes.push_back(mBox1);
// Set the color // Set the color
@ -125,7 +125,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine
// ---------- Box 2 ---------- // // ---------- Box 2 ---------- //
// Create a cylinder and a corresponding collision body in the physics world // Create a cylinder and a corresponding collision body in the physics world
mBox2 = new Box(openglframework::Vector3(3, 2, 5), mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); mBox2 = new Box(false, openglframework::Vector3(3, 2, 5), mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
mAllShapes.push_back(mBox2); mAllShapes.push_back(mBox2);
// Set the color // Set the color
@ -136,7 +136,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine
// ---------- Convex Mesh ---------- // // ---------- Convex Mesh ---------- //
// Create a convex mesh and a corresponding collision body in the physics world // Create a convex mesh and a corresponding collision body in the physics world
mConvexMesh = new ConvexMesh(false, 1.0f, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath + "convexmesh.obj"); mConvexMesh = new ConvexMesh(false, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath + "convexmesh.obj");
mAllShapes.push_back(mConvexMesh); mAllShapes.push_back(mConvexMesh);
// Set the color // Set the color
@ -147,7 +147,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine
// ---------- Heightfield ---------- // // ---------- Heightfield ---------- //
// Create a convex mesh and a corresponding collision body in the physics world // Create a convex mesh and a corresponding collision body in the physics world
mHeightField = new HeightField(false, 1.0f, mPhysicsCommon, mPhysicsWorld); mHeightField = new HeightField(false, mPhysicsCommon, mPhysicsWorld);
// Set the color // Set the color
mHeightField->setColor(mObjectColorDemo); mHeightField->setColor(mObjectColorDemo);

View File

@ -79,7 +79,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin
for (int i=0; i<NB_BOXES; i++) { for (int i=0; i<NB_BOXES; i++) {
// Create a sphere and a corresponding rigid in the physics world // Create a sphere and a corresponding rigid in the physics world
Box* box = new Box(BOX_SIZE, BOX_MASS, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); Box* box = new Box(true, BOX_SIZE, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
// Set the box color // Set the box color
box->setColor(mObjectColorDemo); box->setColor(mObjectColorDemo);
@ -98,7 +98,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin
for (int i=0; i<NB_SPHERES; i++) { for (int i=0; i<NB_SPHERES; i++) {
// Create a sphere and a corresponding rigid in the physics world // Create a sphere and a corresponding rigid in the physics world
Sphere* sphere = new Sphere(SPHERE_RADIUS, BOX_MASS, mPhysicsCommon, mPhysicsWorld, meshFolderPath); Sphere* sphere = new Sphere(true, SPHERE_RADIUS, mPhysicsCommon, mPhysicsWorld, meshFolderPath);
// Add some rolling resistance // Add some rolling resistance
sphere->getCollider()->getMaterial().setRollingResistance(rp3d::decimal(0.08)); sphere->getCollider()->getMaterial().setRollingResistance(rp3d::decimal(0.08));
@ -120,7 +120,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin
for (int i=0; i<NB_CAPSULES; i++) { for (int i=0; i<NB_CAPSULES; i++) {
// Create a cylinder and a corresponding rigid in the physics world // Create a cylinder and a corresponding rigid in the physics world
Capsule* capsule = new Capsule(true, CAPSULE_RADIUS, CAPSULE_HEIGHT, CAPSULE_MASS, Capsule* capsule = new Capsule(true, CAPSULE_RADIUS, CAPSULE_HEIGHT,
mPhysicsCommon, mPhysicsWorld, meshFolderPath); mPhysicsCommon, mPhysicsWorld, meshFolderPath);
capsule->getCollider()->getMaterial().setRollingResistance(rp3d::decimal(0.08f)); capsule->getCollider()->getMaterial().setRollingResistance(rp3d::decimal(0.08f));
@ -142,7 +142,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin
for (int i=0; i<NB_MESHES; i++) { for (int i=0; i<NB_MESHES; i++) {
// Create a convex mesh and a corresponding rigid in the physics world // Create a convex mesh and a corresponding rigid in the physics world
ConvexMesh* mesh = new ConvexMesh(true, MESH_MASS, mPhysicsCommon, mPhysicsWorld, meshFolderPath + "convexmesh.obj"); ConvexMesh* mesh = new ConvexMesh(true, mPhysicsCommon, mPhysicsWorld, meshFolderPath + "convexmesh.obj");
// Set the box color // Set the box color
mesh->setColor(mObjectColorDemo); mesh->setColor(mObjectColorDemo);
@ -159,7 +159,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin
// ---------- Create the floor --------- // ---------- Create the floor ---------
mFloor = new Box(FLOOR_SIZE, FLOOR_MASS, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); mFloor = new Box(true, FLOOR_SIZE, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
mPhysicsObjects.push_back(mFloor); mPhysicsObjects.push_back(mFloor);
// Set the box color // Set the box color

View File

@ -57,12 +57,6 @@ const float CAPSULE_RADIUS = 1.0f;
const float CAPSULE_HEIGHT = 1.0f; const float CAPSULE_HEIGHT = 1.0f;
const float DUMBBELL_HEIGHT = 1.0f; const float DUMBBELL_HEIGHT = 1.0f;
const openglframework::Vector3 FLOOR_SIZE(50, 0.5f, 50); // Floor dimensions in meters const openglframework::Vector3 FLOOR_SIZE(50, 0.5f, 50); // Floor dimensions in meters
const float BOX_MASS = 1.0f;
const float CONE_MASS = 1.0f;
const float CYLINDER_MASS = 1.0f;
const float CAPSULE_MASS = 1.0f;
const float MESH_MASS = 1.0f;
const float FLOOR_MASS = 100.0f; // Floor mass in kilograms
// Class CollisionShapesScene // Class CollisionShapesScene
class CollisionShapesScene : public SceneDemo { class CollisionShapesScene : public SceneDemo {

View File

@ -80,7 +80,7 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett
for (int i = 0; i<NB_BOXES; i++) { for (int i = 0; i<NB_BOXES; i++) {
// Create a sphere and a corresponding rigid in the physics world // Create a sphere and a corresponding rigid in the physics world
Box* box = new Box(BOX_SIZE, BOX_MASS, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); Box* box = new Box(true, BOX_SIZE, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
// Set the box color // Set the box color
box->setColor(mObjectColorDemo); box->setColor(mObjectColorDemo);
@ -99,7 +99,7 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett
for (int i = 0; i<NB_SPHERES; i++) { for (int i = 0; i<NB_SPHERES; i++) {
// Create a sphere and a corresponding rigid in the physics world // Create a sphere and a corresponding rigid in the physics world
Sphere* sphere = new Sphere(SPHERE_RADIUS, BOX_MASS, mPhysicsCommon, mPhysicsWorld, meshFolderPath); Sphere* sphere = new Sphere(true, SPHERE_RADIUS, mPhysicsCommon, mPhysicsWorld, meshFolderPath);
// Add some rolling resistance // Add some rolling resistance
sphere->getCollider()->getMaterial().setRollingResistance(rp3d::decimal(0.08)); sphere->getCollider()->getMaterial().setRollingResistance(rp3d::decimal(0.08));
@ -121,7 +121,7 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett
for (int i = 0; i<NB_CAPSULES; i++) { for (int i = 0; i<NB_CAPSULES; i++) {
// Create a cylinder and a corresponding rigid in the physics world // Create a cylinder and a corresponding rigid in the physics world
Capsule* capsule = new Capsule(true, CAPSULE_RADIUS, CAPSULE_HEIGHT, CAPSULE_MASS, Capsule* capsule = new Capsule(true, CAPSULE_RADIUS, CAPSULE_HEIGHT,
mPhysicsCommon, mPhysicsWorld, meshFolderPath); mPhysicsCommon, mPhysicsWorld, meshFolderPath);
capsule->getCollider()->getMaterial().setRollingResistance(rp3d::decimal(0.08)); capsule->getCollider()->getMaterial().setRollingResistance(rp3d::decimal(0.08));
@ -143,7 +143,7 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett
for (int i = 0; i<NB_MESHES; i++) { for (int i = 0; i<NB_MESHES; i++) {
// Create a convex mesh and a corresponding rigid in the physics world // Create a convex mesh and a corresponding rigid in the physics world
ConvexMesh* mesh = new ConvexMesh(true, MESH_MASS, mPhysicsCommon, mPhysicsWorld, meshFolderPath + "convexmesh.obj"); ConvexMesh* mesh = new ConvexMesh(true, mPhysicsCommon, mPhysicsWorld, meshFolderPath + "convexmesh.obj");
// Set the box color // Set the box color
mesh->setColor(mObjectColorDemo); mesh->setColor(mObjectColorDemo);
@ -160,11 +160,8 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett
// ---------- Create the triangular mesh ---------- // // ---------- Create the triangular mesh ---------- //
// Position
rp3d::decimal mass = 1.0;
// Create a convex mesh and a corresponding rigid in the physics world // Create a convex mesh and a corresponding rigid in the physics world
mConcaveMesh = new ConcaveMesh(true, mass, mPhysicsCommon, mPhysicsWorld, meshFolderPath + "city.obj"); mConcaveMesh = new ConcaveMesh(true, mPhysicsCommon, mPhysicsWorld, meshFolderPath + "city.obj");
// Set the mesh as beeing static // Set the mesh as beeing static
mConcaveMesh->getRigidBody()->setType(rp3d::BodyType::STATIC); mConcaveMesh->getRigidBody()->setType(rp3d::BodyType::STATIC);

View File

@ -56,11 +56,6 @@ const float CYLINDER_HEIGHT = 5.0f;
const float CAPSULE_RADIUS = 1.0f; const float CAPSULE_RADIUS = 1.0f;
const float CAPSULE_HEIGHT = 1.0f; const float CAPSULE_HEIGHT = 1.0f;
const float DUMBBELL_HEIGHT = 1.0f; const float DUMBBELL_HEIGHT = 1.0f;
const float BOX_MASS = 1.0f;
const float CONE_MASS = 1.0f;
const float CYLINDER_MASS = 1.0f;
const float CAPSULE_MASS = 1.0f;
const float MESH_MASS = 1.0f;
// Class TriangleMeshScene // Class TriangleMeshScene
class ConcaveMeshScene : public SceneDemo { class ConcaveMeshScene : public SceneDemo {

View File

@ -34,6 +34,8 @@ using namespace cubesscene;
CubesScene::CubesScene(const std::string& name, EngineSettings& settings) CubesScene::CubesScene(const std::string& name, EngineSettings& settings)
: SceneDemo(name, settings, true, SCENE_RADIUS) { : SceneDemo(name, settings, true, SCENE_RADIUS) {
iter = 0;
// Compute the radius and the center of the scene // Compute the radius and the center of the scene
openglframework::Vector3 center(0, 5, 0); openglframework::Vector3 center(0, 5, 0);
@ -55,7 +57,7 @@ CubesScene::CubesScene(const std::string& name, EngineSettings& settings)
for (int i=0; i<NB_CUBES; i++) { for (int i=0; i<NB_CUBES; i++) {
// Create a cube and a corresponding rigid in the physics world // Create a cube and a corresponding rigid in the physics world
Box* cube = new Box(BOX_SIZE, BOX_MASS, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); Box* cube = new Box(true, BOX_SIZE, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
// Set the box color // Set the box color
cube->setColor(mObjectColorDemo); cube->setColor(mObjectColorDemo);
@ -73,7 +75,7 @@ CubesScene::CubesScene(const std::string& name, EngineSettings& settings)
// ------------------------- FLOOR ----------------------- // // ------------------------- FLOOR ----------------------- //
// Create the floor // Create the floor
mFloor = new Box(FLOOR_SIZE, FLOOR_MASS, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); mFloor = new Box(true, FLOOR_SIZE, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
mFloor->setColor(mFloorColorDemo); mFloor->setColor(mFloorColorDemo);
mFloor->setSleepingColor(mFloorColorDemo); mFloor->setSleepingColor(mFloorColorDemo);

View File

@ -39,8 +39,6 @@ const float SCENE_RADIUS = 30.0f; // Radius of the sce
const int NB_CUBES = 30; // Number of boxes in the scene const int NB_CUBES = 30; // Number of boxes in the scene
const openglframework::Vector3 BOX_SIZE(2, 2, 2); // Box dimensions in meters const openglframework::Vector3 BOX_SIZE(2, 2, 2); // Box dimensions in meters
const openglframework::Vector3 FLOOR_SIZE(50, 1, 50); // Floor dimensions in meters const openglframework::Vector3 FLOOR_SIZE(50, 1, 50); // Floor dimensions in meters
const float BOX_MASS = 1.0f; // Box mass in kilograms
const float FLOOR_MASS = 100.0f; // Floor mass in kilograms
// Class CubesScene // Class CubesScene
class CubesScene : public SceneDemo { class CubesScene : public SceneDemo {
@ -55,6 +53,8 @@ class CubesScene : public SceneDemo {
/// Box for the floor /// Box for the floor
Box* mFloor; Box* mFloor;
uint iter;
public: public:
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //

View File

@ -57,7 +57,7 @@ CubeStackScene::CubeStackScene(const std::string& name, EngineSettings& settings
for (int j=0; j<i; j++) { for (int j=0; j<i; j++) {
// Create a cube and a corresponding rigid in the physics world // Create a cube and a corresponding rigid in the physics world
Box* cube = new Box(BOX_SIZE, BOX_MASS, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); Box* cube = new Box(true, BOX_SIZE, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
// Set the box color // Set the box color
cube->setColor(mObjectColorDemo); cube->setColor(mObjectColorDemo);
@ -76,7 +76,7 @@ CubeStackScene::CubeStackScene(const std::string& name, EngineSettings& settings
// ------------------------- FLOOR ----------------------- // // ------------------------- FLOOR ----------------------- //
// Create the floor // Create the floor
mFloor = new Box(FLOOR_SIZE, FLOOR_MASS, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); mFloor = new Box(true, FLOOR_SIZE, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
mFloor->setColor(mFloorColorDemo); mFloor->setColor(mFloorColorDemo);
mFloor->setSleepingColor(mFloorColorDemo); mFloor->setSleepingColor(mFloorColorDemo);

View File

@ -39,8 +39,6 @@ const float SCENE_RADIUS = 30.0f; // Radius of the sce
const int NB_FLOORS = 15; // Number of boxes in the scene const int NB_FLOORS = 15; // Number of boxes in the scene
const openglframework::Vector3 BOX_SIZE(2, 2, 2); // Box dimensions in meters const openglframework::Vector3 BOX_SIZE(2, 2, 2); // Box dimensions in meters
const openglframework::Vector3 FLOOR_SIZE(50, 1, 50); // Floor dimensions in meters const openglframework::Vector3 FLOOR_SIZE(50, 1, 50); // Floor dimensions in meters
const float BOX_MASS = 1.0f; // Box mass in kilograms
const float FLOOR_MASS = 100.0f; // Floor mass in kilograms
// Class CubeStackScene // Class CubeStackScene
class CubeStackScene : public SceneDemo { class CubeStackScene : public SceneDemo {

View File

@ -79,7 +79,7 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett
for (int i = 0; i<NB_BOXES; i++) { for (int i = 0; i<NB_BOXES; i++) {
// Create a sphere and a corresponding rigid in the physics world // Create a sphere and a corresponding rigid in the physics world
Box* box = new Box(BOX_SIZE, BOX_MASS, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); Box* box = new Box(true, BOX_SIZE, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
// Set the box color // Set the box color
box->setColor(mObjectColorDemo); box->setColor(mObjectColorDemo);
@ -98,7 +98,7 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett
for (int i = 0; i<NB_SPHERES; i++) { for (int i = 0; i<NB_SPHERES; i++) {
// Create a sphere and a corresponding rigid in the physics world // Create a sphere and a corresponding rigid in the physics world
Sphere* sphere = new Sphere(SPHERE_RADIUS, BOX_MASS, mPhysicsCommon, mPhysicsWorld, meshFolderPath); Sphere* sphere = new Sphere(true, SPHERE_RADIUS, mPhysicsCommon, mPhysicsWorld, meshFolderPath);
// Add some rolling resistance // Add some rolling resistance
sphere->getCollider()->getMaterial().setRollingResistance(0.08f); sphere->getCollider()->getMaterial().setRollingResistance(0.08f);
@ -120,8 +120,7 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett
for (int i = 0; i<NB_CAPSULES; i++) { for (int i = 0; i<NB_CAPSULES; i++) {
// Create a cylinder and a corresponding rigid in the physics world // Create a cylinder and a corresponding rigid in the physics world
Capsule* capsule = new Capsule(true, CAPSULE_RADIUS, CAPSULE_HEIGHT, CAPSULE_MASS, Capsule* capsule = new Capsule(true, CAPSULE_RADIUS, CAPSULE_HEIGHT, mPhysicsCommon, mPhysicsWorld, meshFolderPath);
mPhysicsCommon, mPhysicsWorld, meshFolderPath);
capsule->getCollider()->getMaterial().setRollingResistance(0.08f); capsule->getCollider()->getMaterial().setRollingResistance(0.08f);
@ -142,7 +141,7 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett
for (int i = 0; i<NB_MESHES; i++) { for (int i = 0; i<NB_MESHES; i++) {
// Create a convex mesh and a corresponding rigid in the physics world // Create a convex mesh and a corresponding rigid in the physics world
ConvexMesh* mesh = new ConvexMesh(true, MESH_MASS, mPhysicsCommon, mPhysicsWorld, meshFolderPath + "convexmesh.obj"); ConvexMesh* mesh = new ConvexMesh(true, mPhysicsCommon, mPhysicsWorld, meshFolderPath + "convexmesh.obj");
// Set the box color // Set the box color
mesh->setColor(mObjectColorDemo); mesh->setColor(mObjectColorDemo);
@ -159,11 +158,8 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett
// ---------- Create the height field ---------- // // ---------- Create the height field ---------- //
// Position
rp3d::decimal mass = 1.0;
// Create a convex mesh and a corresponding rigid in the physics world // Create a convex mesh and a corresponding rigid in the physics world
mHeightField = new HeightField(true, mass, mPhysicsCommon, mPhysicsWorld); mHeightField = new HeightField(true, mPhysicsCommon, mPhysicsWorld);
// Set the mesh as beeing static // Set the mesh as beeing static
mHeightField->getRigidBody()->setType(rp3d::BodyType::STATIC); mHeightField->getRigidBody()->setType(rp3d::BodyType::STATIC);

View File

@ -56,12 +56,6 @@ const float CAPSULE_RADIUS = 1.0f;
const float CAPSULE_HEIGHT = 1.0f; const float CAPSULE_HEIGHT = 1.0f;
const float DUMBBELL_HEIGHT = 1.0f; const float DUMBBELL_HEIGHT = 1.0f;
const openglframework::Vector3 FLOOR_SIZE(50, 0.5f, 50); // Floor dimensions in meters const openglframework::Vector3 FLOOR_SIZE(50, 0.5f, 50); // Floor dimensions in meters
const float BOX_MASS = 1.0f;
const float CONE_MASS = 1.0f;
const float CYLINDER_MASS = 1.0f;
const float CAPSULE_MASS = 1.0f;
const float MESH_MASS = 1.0f;
const float FLOOR_MASS = 100.0f;
// Class HeightFieldScene // Class HeightFieldScene
class HeightFieldScene : public SceneDemo { class HeightFieldScene : public SceneDemo {

View File

@ -213,8 +213,7 @@ void JointsScene::createBallAndSocketJoints() {
for (int i=0; i<NB_BALLSOCKETJOINT_BOXES; i++) { for (int i=0; i<NB_BALLSOCKETJOINT_BOXES; i++) {
// Create a box and a corresponding rigid in the physics world // Create a box and a corresponding rigid in the physics world
mBallAndSocketJointChainBoxes[i] = new Box(boxDimension, boxMass, mBallAndSocketJointChainBoxes[i] = new Box(true, boxDimension, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
mBallAndSocketJointChainBoxes[i]->setTransform(rp3d::Transform(positionBox, rp3d::Quaternion::identity())); mBallAndSocketJointChainBoxes[i]->setTransform(rp3d::Transform(positionBox, rp3d::Quaternion::identity()));
// Set the box color // Set the box color
@ -266,7 +265,7 @@ void JointsScene::createSliderJoint() {
// Create a box and a corresponding rigid in the physics world // Create a box and a corresponding rigid in the physics world
openglframework::Vector3 box1Dimension(2, 4, 2); openglframework::Vector3 box1Dimension(2, 4, 2);
mSliderJointBottomBox = new Box(box1Dimension , BOX_MASS, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); mSliderJointBottomBox = new Box(true, box1Dimension, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
mSliderJointBottomBox->setTransform(rp3d::Transform(positionBox1, rp3d::Quaternion::identity())); mSliderJointBottomBox->setTransform(rp3d::Transform(positionBox1, rp3d::Quaternion::identity()));
// Set the box color // Set the box color
@ -288,7 +287,7 @@ void JointsScene::createSliderJoint() {
// Create a box and a corresponding rigid in the physics world // Create a box and a corresponding rigid in the physics world
openglframework::Vector3 box2Dimension(1.5f, 4, 1.5f); openglframework::Vector3 box2Dimension(1.5f, 4, 1.5f);
mSliderJointTopBox = new Box(box2Dimension, BOX_MASS, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); mSliderJointTopBox = new Box(true, box2Dimension, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
mSliderJointTopBox->setTransform(rp3d::Transform(positionBox2, rp3d::Quaternion::identity())); mSliderJointTopBox->setTransform(rp3d::Transform(positionBox2, rp3d::Quaternion::identity()));
// Set the box color // Set the box color
@ -330,7 +329,7 @@ void JointsScene::createPropellerHingeJoint() {
// Create a box and a corresponding rigid in the physics world // Create a box and a corresponding rigid in the physics world
openglframework::Vector3 boxDimension(10, 1, 1); openglframework::Vector3 boxDimension(10, 1, 1);
mPropellerBox = new Box(boxDimension, BOX_MASS, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); mPropellerBox = new Box(true, boxDimension, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
mPropellerBox->setTransform(rp3d::Transform(positionBox1, rp3d::Quaternion::identity())); mPropellerBox->setTransform(rp3d::Transform(positionBox1, rp3d::Quaternion::identity()));
// Set the box color // Set the box color
@ -371,7 +370,7 @@ void JointsScene::createFixedJoints() {
// Create a box and a corresponding rigid in the physics world // Create a box and a corresponding rigid in the physics world
openglframework::Vector3 boxDimension(1.5, 1.5, 1.5); openglframework::Vector3 boxDimension(1.5, 1.5, 1.5);
mFixedJointBox1 = new Box(boxDimension, BOX_MASS, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); mFixedJointBox1 = new Box(true, boxDimension, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
mFixedJointBox1->setTransform(rp3d::Transform(positionBox1, rp3d::Quaternion::identity())); mFixedJointBox1->setTransform(rp3d::Transform(positionBox1, rp3d::Quaternion::identity()));
// Set the box color // Set the box color
@ -389,7 +388,7 @@ void JointsScene::createFixedJoints() {
rp3d::Vector3 positionBox2(-5, 7, 0); rp3d::Vector3 positionBox2(-5, 7, 0);
// Create a box and a corresponding rigid in the physics world // Create a box and a corresponding rigid in the physics world
mFixedJointBox2 = new Box(boxDimension, BOX_MASS, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); mFixedJointBox2 = new Box(true, boxDimension, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
mFixedJointBox2->setTransform(rp3d::Transform(positionBox2, rp3d::Quaternion::identity())); mFixedJointBox2->setTransform(rp3d::Transform(positionBox2, rp3d::Quaternion::identity()));
// Set the box color // Set the box color
@ -430,7 +429,7 @@ void JointsScene::createFloor() {
// Create the floor // Create the floor
rp3d::Vector3 floorPosition(0, 0, 0); rp3d::Vector3 floorPosition(0, 0, 0);
mFloor = new Box(FLOOR_SIZE, FLOOR_MASS, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); mFloor = new Box(true, FLOOR_SIZE, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
// Set the box color // Set the box color
mFloor->setColor(mFloorColorDemo); mFloor->setColor(mFloorColorDemo);

View File

@ -38,8 +38,6 @@ namespace jointsscene {
const float SCENE_RADIUS = 30.0f; const float SCENE_RADIUS = 30.0f;
const openglframework::Vector3 BOX_SIZE(2, 2, 2); // Box dimensions in meters const openglframework::Vector3 BOX_SIZE(2, 2, 2); // Box dimensions in meters
const openglframework::Vector3 FLOOR_SIZE(50, 0.5f, 50); // Floor dimensions in meters const openglframework::Vector3 FLOOR_SIZE(50, 0.5f, 50); // Floor dimensions in meters
const float BOX_MASS = 1.0f; // Box mass in kilograms
const float FLOOR_MASS = 100.0f; // Floor mass in kilograms
const int NB_BALLSOCKETJOINT_BOXES = 7; // Number of Ball-And-Socket chain boxes const int NB_BALLSOCKETJOINT_BOXES = 7; // Number of Ball-And-Socket chain boxes
const int NB_HINGE_BOXES = 7; // Number of Hinge chain boxes const int NB_HINGE_BOXES = 7; // Number of Hinge chain boxes

View File

@ -77,7 +77,7 @@ PileScene::PileScene(const std::string& name, EngineSettings& settings)
for (int i=0; i<NB_BOXES; i++) { for (int i=0; i<NB_BOXES; i++) {
// Create a sphere and a corresponding rigid in the physics world // Create a sphere and a corresponding rigid in the physics world
Box* box = new Box(BOX_SIZE, BOX_MASS, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); Box* box = new Box(true, BOX_SIZE, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
// Set the box color // Set the box color
box->setColor(mObjectColorDemo); box->setColor(mObjectColorDemo);
@ -96,7 +96,7 @@ PileScene::PileScene(const std::string& name, EngineSettings& settings)
for (int i=0; i<NB_SPHERES; i++) { for (int i=0; i<NB_SPHERES; i++) {
// Create a sphere and a corresponding rigid in the physics world // Create a sphere and a corresponding rigid in the physics world
Sphere* sphere = new Sphere(SPHERE_RADIUS, BOX_MASS, mPhysicsCommon, mPhysicsWorld, meshFolderPath); Sphere* sphere = new Sphere(true, SPHERE_RADIUS, mPhysicsCommon, mPhysicsWorld, meshFolderPath);
// Add some rolling resistance // Add some rolling resistance
sphere->getCollider()->getMaterial().setRollingResistance(rp3d::decimal(0.08)); sphere->getCollider()->getMaterial().setRollingResistance(rp3d::decimal(0.08));
@ -118,7 +118,7 @@ PileScene::PileScene(const std::string& name, EngineSettings& settings)
for (int i=0; i<NB_CAPSULES; i++) { for (int i=0; i<NB_CAPSULES; i++) {
// Create a cylinder and a corresponding rigid in the physics world // Create a cylinder and a corresponding rigid in the physics world
Capsule* capsule = new Capsule(true, CAPSULE_RADIUS, CAPSULE_HEIGHT, CAPSULE_MASS, Capsule* capsule = new Capsule(true, CAPSULE_RADIUS, CAPSULE_HEIGHT,
mPhysicsCommon, mPhysicsWorld, meshFolderPath); mPhysicsCommon, mPhysicsWorld, meshFolderPath);
capsule->getCollider()->getMaterial().setRollingResistance(rp3d::decimal(0.08f)); capsule->getCollider()->getMaterial().setRollingResistance(rp3d::decimal(0.08f));
@ -140,7 +140,7 @@ PileScene::PileScene(const std::string& name, EngineSettings& settings)
for (int i=0; i<NB_MESHES; i++) { for (int i=0; i<NB_MESHES; i++) {
// Create a convex mesh and a corresponding rigid in the physics world // Create a convex mesh and a corresponding rigid in the physics world
ConvexMesh* mesh = new ConvexMesh(true, MESH_MASS, mPhysicsCommon, mPhysicsWorld, meshFolderPath + "convexmesh.obj"); ConvexMesh* mesh = new ConvexMesh(true, mPhysicsCommon, mPhysicsWorld, meshFolderPath + "convexmesh.obj");
// Set the box color // Set the box color
mesh->setColor(mObjectColorDemo); mesh->setColor(mObjectColorDemo);
@ -161,7 +161,7 @@ PileScene::PileScene(const std::string& name, EngineSettings& settings)
rp3d::decimal mass = 1.0; rp3d::decimal mass = 1.0;
// Create a convex mesh and a corresponding rigid in the physics world // Create a convex mesh and a corresponding rigid in the physics world
mSandbox = new ConcaveMesh(true, mass, mPhysicsCommon, mPhysicsWorld, meshFolderPath + "sandbox.obj"); mSandbox = new ConcaveMesh(true, mPhysicsCommon, mPhysicsWorld, meshFolderPath + "sandbox.obj");
// Set the mesh as beeing static // Set the mesh as beeing static
mSandbox->getRigidBody()->setType(rp3d::BodyType::STATIC); mSandbox->getRigidBody()->setType(rp3d::BodyType::STATIC);

View File

@ -57,12 +57,6 @@ const float CAPSULE_RADIUS = 1.0f;
const float CAPSULE_HEIGHT = 1.0f; const float CAPSULE_HEIGHT = 1.0f;
const float DUMBBELL_HEIGHT = 1.0f; const float DUMBBELL_HEIGHT = 1.0f;
const openglframework::Vector3 FLOOR_SIZE(50, 0.5f, 50); // Floor dimensions in meters const openglframework::Vector3 FLOOR_SIZE(50, 0.5f, 50); // Floor dimensions in meters
const float BOX_MASS = 1.0f;
const float CONE_MASS = 1.0f;
const float CYLINDER_MASS = 1.0f;
const float CAPSULE_MASS = 1.0f;
const float MESH_MASS = 1.0f;
const float FLOOR_MASS = 100.0f; // Floor mass in kilograms
// Class PileScene // Class PileScene
class PileScene : public SceneDemo { class PileScene : public SceneDemo {

View File

@ -63,7 +63,7 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
// ---------- Box ---------- // // ---------- Box ---------- //
// Create a box and a corresponding collision body in the physics world // Create a box and a corresponding collision body in the physics world
mBox = new Box(BOX_SIZE, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); mBox = new Box(false, BOX_SIZE, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
mBox->getCollisionBody()->setIsActive(false); mBox->getCollisionBody()->setIsActive(false);
// Set the box color // Set the box color
@ -74,7 +74,7 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
// ---------- Sphere ---------- // // ---------- Sphere ---------- //
// Create a sphere and a corresponding collision body in the physics world // Create a sphere and a corresponding collision body in the physics world
mSphere = new Sphere(SPHERE_RADIUS, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); mSphere = new Sphere(false, SPHERE_RADIUS, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
// Set the color // Set the color
mSphere->setColor(mObjectColorDemo); mSphere->setColor(mObjectColorDemo);
@ -85,7 +85,7 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
openglframework::Vector3 position6(0, 0, 0); openglframework::Vector3 position6(0, 0, 0);
// Create a cylinder and a corresponding collision body in the physics world // Create a cylinder and a corresponding collision body in the physics world
mCapsule = new Capsule(false, CAPSULE_RADIUS, CAPSULE_HEIGHT, 1.0, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); mCapsule = new Capsule(false, CAPSULE_RADIUS, CAPSULE_HEIGHT, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
// Set the color // Set the color
mCapsule->setColor(mObjectColorDemo); mCapsule->setColor(mObjectColorDemo);
@ -95,7 +95,7 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
// ---------- Convex Mesh ---------- // // ---------- Convex Mesh ---------- //
// Create a convex mesh and a corresponding collision body in the physics world // Create a convex mesh and a corresponding collision body in the physics world
mConvexMesh = new ConvexMesh(false, 1.0f, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath + "convexmesh.obj"); mConvexMesh = new ConvexMesh(false, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath + "convexmesh.obj");
// Set the color // Set the color
mConvexMesh->setColor(mObjectColorDemo); mConvexMesh->setColor(mObjectColorDemo);
@ -105,7 +105,7 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
// ---------- Concave Mesh ---------- // // ---------- Concave Mesh ---------- //
// Create a convex mesh and a corresponding collision body in the physics world // Create a convex mesh and a corresponding collision body in the physics world
mConcaveMesh = new ConcaveMesh(false, 1.0f, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath + "city.obj"); mConcaveMesh = new ConcaveMesh(false, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath + "city.obj");
// Set the color // Set the color
mConcaveMesh->setColor(mObjectColorDemo); mConcaveMesh->setColor(mObjectColorDemo);
@ -115,7 +115,7 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
// ---------- Heightfield ---------- // // ---------- Heightfield ---------- //
// Create a convex mesh and a corresponding collision body in the physics world // Create a convex mesh and a corresponding collision body in the physics world
mHeightField = new HeightField(false, 1.0f, mPhysicsCommon, mPhysicsWorld); mHeightField = new HeightField(false, mPhysicsCommon, mPhysicsWorld);
// Set the color // Set the color
mHeightField->setColor(mObjectColorDemo); mHeightField->setColor(mObjectColorDemo);