// Update the broad-phase state for this body (because it has moved for instance) void CollisionBody::updateBroadPhaseState() const { // For all the proxy collision shapes of the body for (ProxyShape* shape = mProxyCollisionShapes; shape != NULL; shape = shape->mNext) { // Recompute the world-space AABB of the collision shape AABB aabb; shape->getCollisionShape()->computeAABB(aabb, mTransform *shape->getLocalToBodyTransform()); // Update the broad-phase state for the proxy collision shape mWorld.mCollisionDetection.updateProxyCollisionShape(shape, aabb); } }
/** * @return The axis-aligned bounding box (AABB) of the body in world-space coordinates */ AABB CollisionBody::getAABB() const { AABB bodyAABB; if (mProxyCollisionShapes == NULL) return bodyAABB; mProxyCollisionShapes->getCollisionShape()->computeAABB(bodyAABB, mTransform * mProxyCollisionShapes->getLocalToBodyTransform()); // For each proxy shape of the body for (ProxyShape* shape = mProxyCollisionShapes->mNext; shape != NULL; shape = shape->mNext) { // Compute the world-space AABB of the collision shape AABB aabb; shape->getCollisionShape()->computeAABB(aabb, mTransform * shape->getLocalToBodyTransform()); // Merge the proxy shape AABB with the current body AABB bodyAABB.mergeWithAABB(aabb); } return bodyAABB; }
// Update the broad-phase state for this body (because it has moved for instance) void RigidBody::updateBroadPhaseState() const { RP3D_PROFILE("RigidBody::updateBroadPhaseState()", mProfiler); DynamicsWorld& world = static_cast<DynamicsWorld&>(mWorld); const Vector3 displacement = world.mTimeStep * mLinearVelocity; // For all the proxy collision shapes of the body for (ProxyShape* shape = mProxyCollisionShapes; shape != nullptr; shape = shape->mNext) { // If the proxy-shape shape is still part of the broad-phase if (shape->getBroadPhaseId() != -1) { // Recompute the world-space AABB of the collision shape AABB aabb; shape->getCollisionShape()->computeAABB(aabb, mTransform * shape->getLocalToBodyTransform()); // Update the broad-phase state for the proxy collision shape mWorld.mCollisionDetection.updateProxyCollisionShape(shape, aabb, displacement); } } }
// 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() { mInitMass = decimal(0.0); mMassInverse = decimal(0.0); if (!mIsInertiaTensorSetByUser) mInertiaTensorLocalInverse.setToZero(); if (!mIsInertiaTensorSetByUser) mInertiaTensorInverseWorld.setToZero(); if (!mIsCenterOfMassSetByUser) mCenterOfMassLocal.setToZero(); Matrix3x3 inertiaTensorLocal; inertiaTensorLocal.setToZero(); // If it is a STATIC or a KINEMATIC body if (mType == BodyType::STATIC || mType == BodyType::KINEMATIC) { mCenterOfMassWorld = mTransform.getPosition(); return; } assert(mType == BodyType::DYNAMIC); // Compute the total mass of the body for (ProxyShape* shape = mProxyCollisionShapes; shape != nullptr; shape = shape->mNext) { mInitMass += shape->getMass(); if (!mIsCenterOfMassSetByUser) { mCenterOfMassLocal += shape->getLocalToBodyTransform().getPosition() * shape->getMass(); } } if (mInitMass > decimal(0.0)) { mMassInverse = decimal(1.0) / mInitMass; } else { mCenterOfMassWorld = mTransform.getPosition(); return; } // Compute the center of mass const Vector3 oldCenterOfMass = mCenterOfMassWorld; if (!mIsCenterOfMassSetByUser) { mCenterOfMassLocal *= mMassInverse; } mCenterOfMassWorld = mTransform * mCenterOfMassLocal; if (!mIsInertiaTensorSetByUser) { // Compute the inertia tensor using all the collision shapes for (ProxyShape* shape = mProxyCollisionShapes; shape != nullptr; shape = shape->mNext) { // Get the inertia tensor of the collision shape in its local-space Matrix3x3 inertiaTensor; shape->getCollisionShape()->computeLocalInertiaTensor(inertiaTensor, shape->getMass()); // Convert the collision shape inertia tensor into the local-space of the body const Transform& shapeTransform = shape->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 collision shape // center into a inertia tensor w.r.t to the body origin. Vector3 offset = shapeTransform.getPosition() - mCenterOfMassLocal; 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 *= shape->getMass(); inertiaTensorLocal += inertiaTensor + offsetMatrix; } // Compute the local inverse inertia tensor mInertiaTensorLocalInverse = inertiaTensorLocal.getInverse(); } // Update the world inverse inertia tensor updateInertiaTensorInverseWorld(); // Update the linear velocity of the center of mass mLinearVelocity += mAngularVelocity.cross(mCenterOfMassWorld - oldCenterOfMass); }