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
- 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
- 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
@ -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 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 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
### Removed
@ -48,6 +61,9 @@
- The EventListener::endInternalTick() method has been removed (because internal ticks do not exist anymore).
- 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.
- 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)
@ -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 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

View File

@ -86,7 +86,7 @@ Collider* CollisionBody::addCollider(CollisionShape* collisionShape, const Trans
const Transform localToWorldTransform = mWorld.mTransformComponents.getTransform(mEntity) * transform;
ColliderComponents::ColliderComponent colliderComponent(mEntity, collider,
AABB(localBoundsMin, localBoundsMax),
transform, collisionShape, decimal(1), 0x0001, 0xFFFF, localToWorldTransform);
transform, collisionShape, 0x0001, 0xFFFF, localToWorldTransform);
bool isActive = mWorld.mCollisionBodyComponents.getIsActive(mEntity);
mWorld.mCollidersComponents.addComponent(colliderEntity, !isActive, colliderComponent);
@ -196,8 +196,8 @@ void CollisionBody::removeCollider(Collider* collider) {
mWorld.mMemoryManager.release(MemoryManager::AllocationType::Pool, collider, sizeof(Collider));
}
// Remove all the collision shapes
void CollisionBody::removeAllCollisionShapes() {
// Remove all the colliders
void CollisionBody::removeAllColliders() {
// 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.

View File

@ -79,7 +79,7 @@ class CollisionBody {
// -------------------- Methods -------------------- //
/// Remove all the collision shapes
void removeAllCollisionShapes();
void removeAllColliders();
/// Update the broad-phase state for this body (because it has moved for instance)
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 id The ID of the body
*/
RigidBody::RigidBody(PhysicsWorld& world, Entity entity)
: CollisionBody(world, entity), mIsCenterOfMassSetByUser(false), mIsInertiaTensorSetByUser(false) {
RigidBody::RigidBody(PhysicsWorld& world, Entity entity) : CollisionBody(world, entity) {
}
@ -50,12 +49,12 @@ BodyType RigidBody::getType() const {
// Set the type of the body
/// 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.
/// 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
/// 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
/// dynamic, static or kinematic bodies.
/**
@ -67,9 +66,6 @@ void RigidBody::setType(BodyType type) {
mWorld.mRigidBodyComponents.setBodyType(mEntity, type);
// Recompute the total mass, center of mass and inertia tensor
recomputeMassInformation();
// If it is a static body
if (type == BodyType::STATIC) {
@ -86,10 +82,23 @@ void RigidBody::setType(BodyType type) {
mWorld.mRigidBodyComponents.setInverseInertiaTensorLocal(mEntity, Matrix3x3::zero());
}
else { // If it is a dynamic body
mWorld.mRigidBodyComponents.setMassInverse(mEntity, decimal(1.0) / mWorld.mRigidBodyComponents.getInitMass(mEntity));
if (mIsInertiaTensorSetByUser) {
mWorld.mRigidBodyComponents.setInverseInertiaTensorLocal(mEntity, mUserInertiaTensorLocalInverse);
const decimal mass = mWorld.mRigidBodyComponents.getMass(mEntity);
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")));
}
// 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
/**
* @return The mass (in kilograms) of the body
*/
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).
@ -171,22 +160,29 @@ void RigidBody::applyForce(const Vector3& force, const Vector3& point) {
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)
/// If the inertia tensor is set with this method, it will not be computed
/// using the collision shapes of the body.
/// Note that an inertia tensor with a zero value on its diagonal is interpreted as infinite inertia.
/**
* @param inertiaTensorLocal The 3x3 inertia tensor matrix of the body in local-space
* coordinates
*/
void RigidBody::setInertiaTensorLocal(const Matrix3x3& inertiaTensorLocal) {
void RigidBody::setLocalInertiaTensor(const Matrix3x3& inertiaTensorLocal) {
mUserInertiaTensorLocalInverse = inertiaTensorLocal.getInverse();
mIsInertiaTensorSetByUser = true;
if (mWorld.mRigidBodyComponents.getBodyType(mEntity) != BodyType::DYNAMIC) return;
mWorld.mRigidBodyComponents.setLocalInertiaTensor(mEntity, inertiaTensorLocal);
// 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,
"Body " + std::to_string(mEntity.id) + ": Set inertiaTensorLocal=" + inertiaTensorLocal.to_string());
@ -231,45 +227,18 @@ decimal RigidBody::getAngularDamping() const {
return mWorld.mRigidBodyComponents.getAngularDamping(mEntity);
}
// Set the inverse local inertia tensor of the body (in local-space coordinates)
/// If the inverse inertia tensor is set with this method, it will not be computed
/// using the collision shapes of the body.
// Set the center of mass of the body (in local-space coordinates)
/// This method does not move the rigid body in the world.
/**
* @param inverseInertiaTensorLocal The 3x3 inverse inertia tensor matrix of the body in local-space
* coordinates
* @param centerOfMass The center of mass of the body in local-space coordinates
*/
void RigidBody::setInverseInertiaTensorLocal(const Matrix3x3& inverseInertiaTensorLocal) {
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;
void RigidBody::setLocalCenterOfMass(const Vector3& centerOfMass) {
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
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
Vector3 linearVelocity = mWorld.mRigidBodyComponents.getAngularVelocity(mEntity);
@ -278,26 +247,258 @@ void RigidBody::setCenterOfMassLocal(const Vector3& centerOfMassLocal) {
linearVelocity += angularVelocity.cross(centerOfMassWorld - oldCenterOfMass);
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,
"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
/// Note that a mass of zero is interpreted as infinite mass.
/**
* @param mass The mass (in kilograms) of the body
*/
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)) {
mWorld.mRigidBodyComponents.setMassInverse(mEntity, decimal(1.0) / mWorld.mRigidBodyComponents.getInitMass(mEntity));
if (mWorld.mRigidBodyComponents.getMass(mEntity) > decimal(0.0)) {
mWorld.mRigidBodyComponents.setMassInverse(mEntity, decimal(1.0) / mass);
}
else {
mWorld.mRigidBodyComponents.setInitMass(mEntity, decimal(1.0));
mWorld.mRigidBodyComponents.setMassInverse(mEntity, decimal(1.0));
mWorld.mRigidBodyComponents.setMassInverse(mEntity, decimal(0.0));
}
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 transform The transformation of the collider that transforms the
* 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
*/
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
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
collisionShape->getLocalBounds(localBoundsMin, localBoundsMax);
const Transform localToWorldTransform = mWorld.mTransformComponents.getTransform(mEntity) * transform;
ColliderComponents::ColliderComponent colliderComponent(mEntity, collider,
AABB(localBoundsMin, localBoundsMax),
transform, collisionShape, mass, 0x0001, 0xFFFF, localToWorldTransform);
ColliderComponents::ColliderComponent colliderComponent(mEntity, collider, AABB(localBoundsMin, localBoundsMax),
transform, collisionShape, 0x0001, 0xFFFF, localToWorldTransform);
bool isSleeping = mWorld.mRigidBodyComponents.getIsSleeping(mEntity);
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
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,
"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
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
@ -500,101 +692,6 @@ void RigidBody::setTransform(const Transform& transform) {
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 vector of the body

View File

@ -51,18 +51,6 @@ class RigidBody : public CollisionBody {
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 -------------------- //
/// 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
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.
static const Matrix3x3 getInertiaTensorInverseWorld(PhysicsWorld& world, Entity bodyEntity);
@ -96,6 +90,9 @@ class RigidBody : public CollisionBody {
/// Return the mass of the body
decimal getMass() const;
/// Set the mass of the rigid body
void setMass(decimal mass);
/// Return the linear velocity
Vector3 getLinearVelocity() const;
@ -108,23 +105,29 @@ class RigidBody : public CollisionBody {
/// Set the angular velocity.
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)
void setInertiaTensorLocal(const Matrix3x3& inertiaTensorLocal);
void setLocalInertiaTensor(const Matrix3x3& inertiaTensorLocal);
/// Set the inverse local inertia tensor of the body (in body coordinates)
void setInverseInertiaTensorLocal(const Matrix3x3& inverseInertiaTensorLocal);
/// Return the center of mass of the body (in local-space coordinates)
const Vector3& getLocalCenterOfMass() const;
/// Get the inverse local inertia tensor of the body (in body coordinates)
const Matrix3x3& getInverseInertiaTensorLocal() const;
/// Set the center of mass of the body (in local-space coordinates)
void setLocalCenterOfMass(const Vector3& centerOfMass);
/// Return the inverse of the inertia tensor in world coordinates.
const Matrix3x3 getInertiaTensorInverseWorld() const;
/// Compute and set the local-space center of mass of the body using its colliders
void updateLocalCenterOfMassFromColliders();
/// Set the local center of mass of the body (in local-space coordinates)
void setCenterOfMassLocal(const Vector3& centerOfMassLocal);
/// Compute and set the local-space inertia tensor of the body using its colliders
void updateLocalInertiaTensorFromColliders();
/// Set the mass of the rigid body
void setMass(decimal mass);
/// Compute and set the mass of the body using its colliders
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
BodyType getType() const;
@ -172,17 +175,11 @@ class RigidBody : public CollisionBody {
virtual void setIsActive(bool isActive) override;
/// 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
// 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);
virtual Collider* addCollider(CollisionShape* collisionShape, const Transform& transform) override;
/// Remove a collider from the body
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
/// 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
/**
* @param worldPoint Point to test in world-space coordinates

View File

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

View File

@ -27,6 +27,7 @@
#include "PolyhedronMesh.h"
#include "memory/MemoryManager.h"
#include "collision/PolygonVertexArray.h"
#include <cstdlib>
using namespace reactphysics3d;
@ -153,3 +154,48 @@ void PolyhedronMesh::computeCentroid() {
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
void computeCentroid() ;
/// Compute and return the area of a face
decimal getFaceArea(uint faceIndex) const;
public:
// -------------------- Methods -------------------- //
@ -102,6 +105,9 @@ class PolyhedronMesh {
/// Return the centroid of the polyhedron
Vector3 getCentroid() const;
/// Compute and return the volume of the polyhedron
decimal getVolume() const;
// ---------- Friendship ---------- //
friend class PhysicsCommon;

View File

@ -98,6 +98,9 @@ class BoxShape : public ConvexPolyhedronShape {
/// Return the local inertia tensor of the collision shape
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
virtual uint getNbFaces() const override;
@ -253,6 +256,11 @@ inline Vector3 BoxShape::getCentroid() const {
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
inline std::string BoxShape::to_string() const {
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
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
virtual bool isPolyhedron() const override;
@ -188,6 +191,11 @@ inline void CapsuleShape::getLocalBounds(Vector3& min, Vector3& max) const {
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
inline bool CapsuleShape::isPolyhedron() const {
return false;

View File

@ -30,6 +30,7 @@
#include <cassert>
#include "configuration.h"
#include "utils/Profiler.h"
#include "containers/List.h"
/// ReactPhysics3D namespace
namespace reactphysics3d {
@ -142,6 +143,9 @@ class CollisionShape {
/// Return the local inertia tensor of the collision shapes
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
virtual void computeAABB(AABB& aabb, const Transform& transform) const;

View File

@ -36,3 +36,19 @@ ConcaveShape::ConcaveShape(CollisionShapeName name, MemoryAllocator& allocator,
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,
List<Vector3>& triangleVerticesNormals, List<uint>& shapeIds,
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
@ -155,6 +158,7 @@ inline void ConcaveShape::setScale(const Vector3& scale) {
notifyColliderAboutChangedSize();
}
}
#endif

View File

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

View File

@ -93,6 +93,9 @@ class SphereShape : public ConvexShape {
/// Return the local inertia tensor of the collision shape
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
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);
}
// 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
inline bool SphereShape::testPointInside(const Vector3& localPoint, Collider* collider) const {
return (localPoint.lengthSquare() < mMargin * mMargin);

View File

@ -166,6 +166,9 @@ class TriangleShape : public ConvexPolyhedronShape {
/// Return the centroid of the polyhedron
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
static void computeSmoothTriangleMeshContact(const CollisionShape* shape1, const CollisionShape* shape2,
Vector3& localContactPointShape1, Vector3& localContactPointShape2,
@ -304,6 +307,11 @@ inline std::string TriangleShape::to_string() const {
"v3=" + mPoints[2].to_string() + "}";
}
// Compute and return the volume of the collision shape
inline decimal TriangleShape::getVolume() const {
return decimal(0.0);
}
}
#endif

View File

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

View File

@ -73,9 +73,6 @@ class ColliderComponents : public Components {
/// Pointers to the collision shapes of the colliders
CollisionShape** mCollisionShapes;
/// Masses (in kilogramms) of the colliders
decimal* mMasses;
/// 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
/// shape. This value is one (0x0001) by default. This variable can be used
@ -124,17 +121,16 @@ class ColliderComponents : public Components {
AABB localBounds;
const Transform& localToBodyTransform;
CollisionShape* collisionShape;
decimal mass;
unsigned short collisionCategoryBits;
unsigned short collideWithMaskBits;
const Transform& localToWorldTransform;
/// Constructor
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)
:bodyEntity(bodyEntity), collider(collider), localBounds(localBounds), localToBodyTransform(localToBodyTransform),
collisionShape(collisionShape), mass(mass), collisionCategoryBits(collisionCategoryBits), collideWithMaskBits(collideWithMaskBits),
collisionShape(collisionShape), collisionCategoryBits(collisionCategoryBits), collideWithMaskBits(collideWithMaskBits),
localToWorldTransform(localToWorldTransform) {
}
@ -154,9 +150,6 @@ class ColliderComponents : public Components {
/// Return the body entity of a given collider
Entity getBody(Entity colliderEntity) const;
/// Return the mass of a collider
decimal getMass(Entity colliderEntity) const;
/// Return a pointer to a given collider
Collider* getCollider(Entity colliderEntity) const;
@ -218,14 +211,6 @@ inline Entity ColliderComponents::getBody(Entity colliderEntity) const {
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
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(decimal) + sizeof(decimal) +
sizeof(decimal) + sizeof(decimal) + sizeof(Matrix3x3) +
sizeof(Vector3) + sizeof(Vector3) +
sizeof(Matrix3x3) + sizeof(Vector3) + sizeof(Vector3) +
sizeof(Vector3) + sizeof(Vector3) + sizeof(Vector3) +
sizeof(Quaternion) + sizeof(Vector3) + sizeof(Vector3) +
sizeof(bool) + sizeof(bool) + sizeof(List<Entity>)) {
@ -74,9 +74,10 @@ void RigidBodyComponents::allocate(uint32 nbComponentsToAllocate) {
Vector3* newExternalTorques = reinterpret_cast<Vector3*>(newExternalForces + nbComponentsToAllocate);
decimal* newLinearDampings = reinterpret_cast<decimal*>(newExternalTorques + nbComponentsToAllocate);
decimal* newAngularDampings = reinterpret_cast<decimal*>(newLinearDampings + nbComponentsToAllocate);
decimal* newInitMasses = reinterpret_cast<decimal*>(newAngularDampings + nbComponentsToAllocate);
decimal* newInverseMasses = reinterpret_cast<decimal*>(newInitMasses + nbComponentsToAllocate);
Matrix3x3* newInertiaTensorLocalInverses = reinterpret_cast<Matrix3x3*>(newInverseMasses + nbComponentsToAllocate);
decimal* newMasses = reinterpret_cast<decimal*>(newAngularDampings + nbComponentsToAllocate);
decimal* newInverseMasses = reinterpret_cast<decimal*>(newMasses + nbComponentsToAllocate);
Matrix3x3* newInertiaTensorLocal = reinterpret_cast<Matrix3x3*>(newInverseMasses + nbComponentsToAllocate);
Matrix3x3* newInertiaTensorLocalInverses = reinterpret_cast<Matrix3x3*>(newInertiaTensorLocal + nbComponentsToAllocate);
Vector3* newConstrainedLinearVelocities = reinterpret_cast<Vector3*>(newInertiaTensorLocalInverses + nbComponentsToAllocate);
Vector3* newConstrainedAngularVelocities = reinterpret_cast<Vector3*>(newConstrainedLinearVelocities + nbComponentsToAllocate);
Vector3* newSplitLinearVelocities = reinterpret_cast<Vector3*>(newConstrainedAngularVelocities + nbComponentsToAllocate);
@ -105,8 +106,9 @@ void RigidBodyComponents::allocate(uint32 nbComponentsToAllocate) {
memcpy(newExternalTorques, mExternalTorques, mNbComponents * sizeof(Vector3));
memcpy(newLinearDampings, mLinearDampings, 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(newInertiaTensorLocal, mLocalInertiaTensors, mNbComponents * sizeof(Matrix3x3));
memcpy(newInertiaTensorLocalInverses, mInverseInertiaTensorsLocal, mNbComponents * sizeof(Matrix3x3));
memcpy(newConstrainedLinearVelocities, mConstrainedLinearVelocities, mNbComponents * sizeof(Vector3));
memcpy(newConstrainedAngularVelocities, mConstrainedAngularVelocities, mNbComponents * sizeof(Vector3));
@ -138,8 +140,9 @@ void RigidBodyComponents::allocate(uint32 nbComponentsToAllocate) {
mExternalTorques = newExternalTorques;
mLinearDampings = newLinearDampings;
mAngularDampings = newAngularDampings;
mInitMasses = newInitMasses;
mMasses = newMasses;
mInverseMasses = newInverseMasses;
mLocalInertiaTensors = newInertiaTensorLocal;
mInverseInertiaTensorsLocal = newInertiaTensorLocalInverses;
mConstrainedLinearVelocities = newConstrainedLinearVelocities;
mConstrainedAngularVelocities = newConstrainedAngularVelocities;
@ -173,8 +176,9 @@ void RigidBodyComponents::addComponent(Entity bodyEntity, bool isSleeping, const
new (mExternalTorques + index) Vector3(0, 0, 0);
mLinearDampings[index] = decimal(0.0);
mAngularDampings[index] = decimal(0.0);
mInitMasses[index] = decimal(1.0);
mMasses[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 (mConstrainedLinearVelocities + 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]);
mLinearDampings[destIndex] = mLinearDampings[srcIndex];
mAngularDampings[destIndex] = mAngularDampings[srcIndex];
mInitMasses[destIndex] = mInitMasses[srcIndex];
mMasses[destIndex] = mMasses[srcIndex];
mInverseMasses[destIndex] = mInverseMasses[srcIndex];
new (mLocalInertiaTensors + destIndex) Matrix3x3(mLocalInertiaTensors[srcIndex]);
new (mInverseInertiaTensorsLocal + destIndex) Matrix3x3(mInverseInertiaTensorsLocal[srcIndex]);
new (mConstrainedLinearVelocities + destIndex) Vector3(mConstrainedLinearVelocities[srcIndex]);
new (mConstrainedAngularVelocities + destIndex) Vector3(mConstrainedAngularVelocities[srcIndex]);
@ -258,8 +263,9 @@ void RigidBodyComponents::swapComponents(uint32 index1, uint32 index2) {
Vector3 externalTorque1(mExternalTorques[index1]);
decimal linearDamping1 = mLinearDampings[index1];
decimal angularDamping1 = mAngularDampings[index1];
decimal initMass1 = mInitMasses[index1];
decimal mass1 = mMasses[index1];
decimal inverseMass1 = mInverseMasses[index1];
Matrix3x3 inertiaTensorLocal1 = mLocalInertiaTensors[index1];
Matrix3x3 inertiaTensorLocalInverse1 = mInverseInertiaTensorsLocal[index1];
Vector3 constrainedLinearVelocity1(mConstrainedLinearVelocities[index1]);
Vector3 constrainedAngularVelocity1(mConstrainedAngularVelocities[index1]);
@ -291,8 +297,9 @@ void RigidBodyComponents::swapComponents(uint32 index1, uint32 index2) {
new (mExternalTorques + index2) Vector3(externalTorque1);
mLinearDampings[index2] = linearDamping1;
mAngularDampings[index2] = angularDamping1;
mInitMasses[index2] = initMass1;
mMasses[index2] = mass1;
mInverseMasses[index2] = inverseMass1;
mLocalInertiaTensors[index2] = inertiaTensorLocal1;
mInverseInertiaTensorsLocal[index2] = inertiaTensorLocalInverse1;
new (mConstrainedLinearVelocities + index2) Vector3(constrainedLinearVelocity1);
new (mConstrainedAngularVelocities + index2) Vector3(constrainedAngularVelocity1);
@ -329,6 +336,7 @@ void RigidBodyComponents::destroyComponent(uint32 index) {
mAngularVelocities[index].~Vector3();
mExternalForces[index].~Vector3();
mExternalTorques[index].~Vector3();
mLocalInertiaTensors[index].~Matrix3x3();
mInverseInertiaTensorsLocal[index].~Matrix3x3();
mConstrainedLinearVelocities[index].~Vector3();
mConstrainedAngularVelocities[index].~Vector3();

View File

@ -100,13 +100,17 @@ class RigidBodyComponents : public Components {
/// Array with the angular damping factor of each component
decimal* mAngularDampings;
/// Array with the initial mass of each component
decimal* mInitMasses;
/// Array with the mass of each component
decimal* mMasses;
/// Array with the inverse mass of each component
decimal* mInverseMasses;
/// Array with the inertia tensor of each component
Matrix3x3* mLocalInertiaTensors;
/// 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;
/// 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
decimal getAngularDamping(Entity bodyEntity) const;
/// Return the initial mass of an entity
decimal getInitMass(Entity bodyEntity) const;
/// Return the mass of an entity
decimal getMass(Entity bodyEntity) const;
/// Set the mass of an entity
void setMass(Entity bodyEntity, decimal mass);
/// Return the mass inverse of an entity
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
const Matrix3x3& getInertiaTensorLocalInverse(Entity bodyEntity);
@ -255,12 +271,6 @@ class RigidBodyComponents : public Components {
/// Set the angular damping factor of an entity
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
void setInverseInertiaTensorLocal(Entity bodyEntity, const Matrix3x3& inertiaTensorLocalInverse);
@ -484,12 +494,12 @@ inline decimal RigidBodyComponents::getAngularDamping(Entity bodyEntity) const {
return mAngularDampings[mMapEntityToComponentIndex[bodyEntity]];
}
// Return the initial mass of an entity
inline decimal RigidBodyComponents::getInitMass(Entity bodyEntity) const {
// Return the mass of an entity
inline decimal RigidBodyComponents::getMass(Entity bodyEntity) const {
assert(mMapEntityToComponentIndex.containsKey(bodyEntity));
return mInitMasses[mMapEntityToComponentIndex[bodyEntity]];
return mMasses[mMapEntityToComponentIndex[bodyEntity]];
}
// Return the inverse mass of an entity
@ -540,12 +550,12 @@ inline void RigidBodyComponents::setAngularDamping(Entity bodyEntity, decimal an
mAngularDampings[mMapEntityToComponentIndex[bodyEntity]] = angularDamping;
}
// Set the initial mass of an entity
inline void RigidBodyComponents::setInitMass(Entity bodyEntity, decimal initMass) {
// Set the mass of an entity
inline void RigidBodyComponents::setMass(Entity bodyEntity, decimal mass) {
assert(mMapEntityToComponentIndex.containsKey(bodyEntity));
mInitMasses[mMapEntityToComponentIndex[bodyEntity]] = initMass;
mMasses[mMapEntityToComponentIndex[bodyEntity]] = mass;
}
// Set the mass inverse of an entity
@ -556,6 +566,22 @@ inline void RigidBodyComponents::setMassInverse(Entity bodyEntity, decimal inver
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
inline void RigidBodyComponents::setInverseInertiaTensorLocal(Entity bodyEntity, const Matrix3x3& inertiaTensorLocalInverse) {

View File

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

View File

@ -34,7 +34,7 @@ namespace reactphysics3d {
// 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
* body.
*/
@ -53,10 +53,14 @@ class Material {
/// Bounciness during collisions (between 0 and 1) where 1 is for a very bouncy body
decimal mBounciness;
/// Density of mass used to compute the mass of the collider
decimal mMassDensity;
// -------------------- Methods -------------------- //
/// Constructor
Material(decimal frictionCoefficient, decimal rollingResistance, decimal bounciness);
Material(decimal frictionCoefficient, decimal rollingResistance, decimal bounciness,
decimal massDensity = decimal(1.0));
/// Copy-constructor
Material(const Material& material);
@ -86,6 +90,12 @@ class Material {
/// Set the rolling resistance factor
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
std::string to_string() const;
@ -156,6 +166,19 @@ inline void Material::setRollingResistance(decimal 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
inline std::string Material::to_string() const {

View File

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

View File

@ -167,17 +167,28 @@ class PhysicsCommon {
/// Destroy a triangle mesh
void destroyTriangleMesh(TriangleMesh* triangleMesh);
// If logging is enabled
#ifdef IS_LOGGING_ACTIVE
/// Create and return a new logger
Logger* createLogger();
/// Destroy a logger
void destroyLogger(Logger* logger);
#endif
// If profiling is enabled
#ifdef IS_PROFILING_ACTIVE
/// Create and return a new profiler
Profiler* createProfiler();
/// Destroy a 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");
// Remove all the collision shapes of the body
collisionBody->removeAllCollisionShapes();
collisionBody->removeAllColliders();
mCollisionBodyComponents.removeComponent(collisionBody->getEntity());
mTransformComponents.removeComponent(collisionBody->getEntity());
@ -458,7 +458,7 @@ RigidBody* PhysicsWorld::createRigidBody(const Transform& transform) {
mRigidBodyComponents.addComponent(entity, false, rigidBodyComponent);
// 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
mRigidBodies.add(rigidBody);
@ -488,7 +488,7 @@ void PhysicsWorld::destroyRigidBody(RigidBody* rigidBody) {
"Body " + std::to_string(rigidBody->getEntity().id) + ": rigid body destroyed");
// 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
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());
}
// 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++) {
Transform& transform = mTransformComponents.getTransform(mRigidBodyComponents.mBodiesEntities[i]);
@ -144,7 +144,7 @@ void DynamicsSystem::integrateRigidBodiesVelocities(decimal timeStep) {
// Integrate the gravity force
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
virtual ~TestCollisionWorld() {
mPhysicsCommon.destroyPhysicsWorld(mWorld);
mPhysicsCommon.destroyBoxShape(mBoxShape1);
mPhysicsCommon.destroyBoxShape(mBoxShape2);
@ -486,7 +488,6 @@ class TestCollisionWorld : public Test {
delete mConcaveMeshTriangleVertexArray;
mPhysicsCommon.destroyPhysicsWorld(mWorld);
}
/// Run the tests

View File

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

View File

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

View File

@ -38,7 +38,7 @@ openglframework::VertexArrayObject Box::mVAO;
int Box::totalNbBoxes = 0;
// 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") {
@ -57,58 +57,23 @@ Box::Box(const openglframework::Vector3& size, reactphysics3d::PhysicsCommon& ph
// 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);
if (createRigidBody) {
// 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();
// Create a rigid body in the physics world
rp3d::RigidBody* body = world->createRigidBody(mPreviousTransform);
mCollider = body->addCollider(mBoxShape, rp3d::Transform::identity());
body->updateMassPropertiesFromColliders();
mBody = body;
}
else {
totalNbBoxes++;
mTransformMatrix = mTransformMatrix * mScalingMatrix;
}
// Constructor
Box::Box(const openglframework::Vector3& size, float mass, 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]));
mPreviousTransform = rp3d::Transform::identity();
// Create a rigid body in the physics world
rp3d::RigidBody* body = world->createRigidBody(mPreviousTransform);
// Add the collision shape to the body
mCollider = body->addCollider(mBoxShape, rp3d::Transform::identity(), mass);
mBody = body;
// 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 (totalNbBoxes == 0) {

View File

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

View File

@ -34,7 +34,7 @@ openglframework::VertexArrayObject Capsule::mVAO;
int Capsule::totalNbCapsules = 0;
// 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)
: 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) {
rp3d::RigidBody* body = physicsWorld->createRigidBody(mPreviousTransform);
// Add a collision shape to the body and specify the mass of the shape
mCollider = body->addCollider(mCapsuleShape, rp3d::Transform::identity(), mass);
mCollider = body->addCollider(mCapsuleShape, rp3d::Transform::identity());
body->updateMassPropertiesFromColliders();
mBody = body;
}
else {
// Create a rigid body corresponding in the physics world
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());
}

View File

@ -79,7 +79,7 @@ class Capsule : public PhysicsObject {
// -------------------- Methods -------------------- //
/// 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);
/// Destructor

View File

@ -27,7 +27,7 @@
#include "ConcaveMesh.h"
// 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),
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER),
mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) {
@ -60,7 +60,8 @@ ConcaveMesh::ConcaveMesh(bool createRigidBody, float mass, reactphysics3d::Physi
// Create the body
if (createRigidBody) {
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;
}
else {

View File

@ -73,7 +73,7 @@ class ConcaveMesh : public PhysicsObject {
// -------------------- Methods -------------------- //
/// 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
virtual ~ConcaveMesh() override;

View File

@ -28,7 +28,7 @@
#include <unordered_set>
// 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),
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_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
mPolygonFaces = new rp3d::PolygonVertexArray::PolygonFace[getNbFaces(0)];
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++) {
@ -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
if (createRigidBody) {
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;
}
else {
@ -87,6 +88,7 @@ ConvexMesh::ConvexMesh(bool createRigidBody, float mass, rp3d::PhysicsCommon& ph
mCollider = mBody->addCollider(mConvexShape, rp3d::Transform::identity());
}
// Create the VBOs and VAO
createVBOAndVAO();

View File

@ -86,7 +86,7 @@ class ConvexMesh : public PhysicsObject {
// -------------------- Methods -------------------- //
/// 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
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,
// it is OK if this object is destroyed right after calling RigidBody::addCollisionShape()
const rp3d::decimal radiusSphere = rp3d::decimal(1.5);
const rp3d::decimal massSphere = rp3d::decimal(2.0);
mSphereShape = mPhysicsCommon.createSphereShape(radiusSphere);
// 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()
const rp3d::decimal radiusCapsule = rp3d::decimal(0.5);
const rp3d::decimal heightCapsule = rp3d::decimal(7.0);
const rp3d::decimal massCylinder = rp3d::decimal(1.0);
mCapsuleShape = mPhysicsCommon.createCapsuleShape(radiusCapsule, heightCapsule);
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
if (createRigidBody) {
rp3d::RigidBody* body;
body = physicsWorld->createRigidBody(mPreviousTransform);
// Add the three collision shapes to the body and specify the mass and transform of the shapes
mColliderSphere1 = body->addCollider(mSphereShape, transformSphereShape1, massSphere);
mColliderSphere2 = body->addCollider(mSphereShape, transformSphereShape2, massSphere);
mColliderCapsule = body->addCollider(mCapsuleShape, transformCylinderShape, massCylinder);
rp3d::RigidBody* body = physicsWorld->createRigidBody(mPreviousTransform);
mColliderSphere1 = body->addCollider(mSphereShape, transformSphereShape1);
mColliderSphere2 = body->addCollider(mSphereShape, transformSphereShape2);
mColliderCapsule = body->addCollider(mCapsuleShape, transformCylinderShape);
mColliderSphere1->getMaterial().setMassDensity(2);
mColliderSphere2->getMaterial().setMassDensity(2);
body->updateMassPropertiesFromColliders();
mBody = body;
}
else {
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);
mColliderSphere2 = mBody->addCollider(mSphereShape, transformSphereShape2);
mColliderCapsule = mBody->addCollider(mCapsuleShape, transformCylinderShape);
}
mTransformMatrix = mTransformMatrix * mScalingMatrix;
// Create the VBOs and VAO

View File

@ -28,7 +28,7 @@
#include "PerlinNoise.h"
// 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),
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER),
mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) {
@ -54,7 +54,8 @@ HeightField::HeightField(bool createRigidBody, float mass, reactphysics3d::Physi
// Create a body
if (createRigidBody) {
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;
}
else {
@ -62,6 +63,7 @@ HeightField::HeightField(bool createRigidBody, float mass, reactphysics3d::Physi
mCollider = mBody->addCollider(mHeightFieldShape, rp3d::Transform::identity());
}
// Create the VBOs and VAO
createVBOAndVAO();

View File

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

View File

@ -34,7 +34,7 @@ openglframework::VertexArrayObject Sphere::mVAO;
int Sphere::totalNbSpheres = 0;
// 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) {
@ -48,51 +48,23 @@ Sphere::Sphere(float radius, rp3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWo
// 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);
if (createRigidBody) {
// 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();
// Create a rigid body corresponding to the sphere in the physics world
rp3d::RigidBody* body = world->createRigidBody(mPreviousTransform);
mCollider = body->addCollider(mCollisionShape, rp3d::Transform::identity());
body->updateMassPropertiesFromColliders();
mBody = body;
}
else {
totalNbSpheres++;
}
// Constructor
Sphere::Sphere(float radius, float mass, rp3d::PhysicsCommon& physicsCommon,reactphysics3d::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);
mPreviousTransform = rp3d::Transform::identity();
// Create a rigid body corresponding to the sphere in the physics world
rp3d::RigidBody* body = world->createRigidBody(mPreviousTransform);
// Add a collision shape to the body and specify the mass of the shape
mCollider = body->addCollider(mCollisionShape, rp3d::Transform::identity(), mass);
mBody = body;
// 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;

View File

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

View File

@ -57,7 +57,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine
// ---------- Sphere 1 ---------- //
// 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);
// Set the color
@ -69,7 +69,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine
// ---------- Sphere 2 ---------- //
// 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);
// Set the color
@ -81,7 +81,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine
// ---------- Capsule 1 ---------- //
// 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);
// Set the color
@ -92,7 +92,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine
// ---------- Capsule 2 ---------- //
// 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);
// Set the color
@ -103,7 +103,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine
// ---------- Concave Mesh ---------- //
// 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);
// Set the color
@ -114,7 +114,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine
// ---------- Box 1 ---------- //
// 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);
// Set the color
@ -125,7 +125,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine
// ---------- Box 2 ---------- //
// 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);
// Set the color
@ -136,7 +136,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine
// ---------- Convex Mesh ---------- //
// 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);
// Set the color
@ -147,7 +147,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine
// ---------- Heightfield ---------- //
// 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
mHeightField->setColor(mObjectColorDemo);

View File

@ -79,7 +79,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin
for (int i=0; i<NB_BOXES; i++) {
// 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
box->setColor(mObjectColorDemo);
@ -98,7 +98,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin
for (int i=0; i<NB_SPHERES; i++) {
// 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
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++) {
// 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);
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++) {
// 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
mesh->setColor(mObjectColorDemo);
@ -159,7 +159,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin
// ---------- 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);
// Set the box color

View File

@ -57,12 +57,6 @@ const float CAPSULE_RADIUS = 1.0f;
const float CAPSULE_HEIGHT = 1.0f;
const float DUMBBELL_HEIGHT = 1.0f;
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 : public SceneDemo {

View File

@ -80,7 +80,7 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett
for (int i = 0; i<NB_BOXES; i++) {
// 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
box->setColor(mObjectColorDemo);
@ -99,7 +99,7 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett
for (int i = 0; i<NB_SPHERES; i++) {
// 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
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++) {
// 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);
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++) {
// 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
mesh->setColor(mObjectColorDemo);
@ -160,11 +160,8 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett
// ---------- Create the triangular mesh ---------- //
// Position
rp3d::decimal mass = 1.0;
// 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
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_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 ConcaveMeshScene : public SceneDemo {

View File

@ -34,6 +34,8 @@ using namespace cubesscene;
CubesScene::CubesScene(const std::string& name, EngineSettings& settings)
: SceneDemo(name, settings, true, SCENE_RADIUS) {
iter = 0;
// Compute the radius and the center of the scene
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++) {
// 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
cube->setColor(mObjectColorDemo);
@ -73,7 +75,7 @@ CubesScene::CubesScene(const std::string& name, EngineSettings& settings)
// ------------------------- 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->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 openglframework::Vector3 BOX_SIZE(2, 2, 2); // Box 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 : public SceneDemo {
@ -55,6 +53,8 @@ class CubesScene : public SceneDemo {
/// Box for the floor
Box* mFloor;
uint iter;
public:
// -------------------- Methods -------------------- //

View File

@ -57,7 +57,7 @@ CubeStackScene::CubeStackScene(const std::string& name, EngineSettings& settings
for (int j=0; j<i; j++) {
// 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
cube->setColor(mObjectColorDemo);
@ -76,7 +76,7 @@ CubeStackScene::CubeStackScene(const std::string& name, EngineSettings& settings
// ------------------------- 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->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 openglframework::Vector3 BOX_SIZE(2, 2, 2); // Box 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 : public SceneDemo {

View File

@ -79,7 +79,7 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett
for (int i = 0; i<NB_BOXES; i++) {
// 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
box->setColor(mObjectColorDemo);
@ -98,7 +98,7 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett
for (int i = 0; i<NB_SPHERES; i++) {
// 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
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++) {
// Create a cylinder and a corresponding rigid in the physics world
Capsule* capsule = new Capsule(true, CAPSULE_RADIUS, CAPSULE_HEIGHT, CAPSULE_MASS,
mPhysicsCommon, mPhysicsWorld, meshFolderPath);
Capsule* capsule = new Capsule(true, CAPSULE_RADIUS, CAPSULE_HEIGHT, mPhysicsCommon, mPhysicsWorld, meshFolderPath);
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++) {
// 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
mesh->setColor(mObjectColorDemo);
@ -159,11 +158,8 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett
// ---------- Create the height field ---------- //
// Position
rp3d::decimal mass = 1.0;
// 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
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 DUMBBELL_HEIGHT = 1.0f;
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 : public SceneDemo {

View File

@ -213,8 +213,7 @@ void JointsScene::createBallAndSocketJoints() {
for (int i=0; i<NB_BALLSOCKETJOINT_BOXES; i++) {
// Create a box and a corresponding rigid in the physics world
mBallAndSocketJointChainBoxes[i] = new Box(boxDimension, boxMass,
mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
mBallAndSocketJointChainBoxes[i] = new Box(true, boxDimension, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
mBallAndSocketJointChainBoxes[i]->setTransform(rp3d::Transform(positionBox, rp3d::Quaternion::identity()));
// Set the box color
@ -266,7 +265,7 @@ void JointsScene::createSliderJoint() {
// Create a box and a corresponding rigid in the physics world
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()));
// Set the box color
@ -288,7 +287,7 @@ void JointsScene::createSliderJoint() {
// Create a box and a corresponding rigid in the physics world
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()));
// Set the box color
@ -330,7 +329,7 @@ void JointsScene::createPropellerHingeJoint() {
// Create a box and a corresponding rigid in the physics world
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()));
// Set the box color
@ -371,7 +370,7 @@ void JointsScene::createFixedJoints() {
// Create a box and a corresponding rigid in the physics world
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()));
// Set the box color
@ -389,7 +388,7 @@ void JointsScene::createFixedJoints() {
rp3d::Vector3 positionBox2(-5, 7, 0);
// 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()));
// Set the box color
@ -430,7 +429,7 @@ void JointsScene::createFloor() {
// Create the floor
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
mFloor->setColor(mFloorColorDemo);

View File

@ -38,8 +38,6 @@ namespace jointsscene {
const float SCENE_RADIUS = 30.0f;
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 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_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++) {
// 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
box->setColor(mObjectColorDemo);
@ -96,7 +96,7 @@ PileScene::PileScene(const std::string& name, EngineSettings& settings)
for (int i=0; i<NB_SPHERES; i++) {
// 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
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++) {
// 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);
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++) {
// 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
mesh->setColor(mObjectColorDemo);
@ -161,7 +161,7 @@ PileScene::PileScene(const std::string& name, EngineSettings& settings)
rp3d::decimal mass = 1.0;
// 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
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 DUMBBELL_HEIGHT = 1.0f;
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 : public SceneDemo {

View File

@ -63,7 +63,7 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
// ---------- Box ---------- //
// 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);
// Set the box color
@ -74,7 +74,7 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
// ---------- Sphere ---------- //
// 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
mSphere->setColor(mObjectColorDemo);
@ -85,7 +85,7 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
openglframework::Vector3 position6(0, 0, 0);
// 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
mCapsule->setColor(mObjectColorDemo);
@ -95,7 +95,7 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
// ---------- Convex Mesh ---------- //
// 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
mConvexMesh->setColor(mObjectColorDemo);
@ -105,7 +105,7 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
// ---------- Concave Mesh ---------- //
// 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
mConcaveMesh->setColor(mObjectColorDemo);
@ -115,7 +115,7 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
// ---------- Heightfield ---------- //
// 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
mHeightField->setColor(mObjectColorDemo);