1. Recursively transform the compound tree by calculating the principal transform for the compound, transforming the compound by the principal transform and then transforming the children by the inverse of the principal transform. Where the compound is the root collision shape in the tree, the rigid body is transformed by the principal transform instead.
2. Set the m_localInertia property in the btRigidBodyConstructionInfo struct and create the rigid body.
The relevant code is provided below:
Code: Select all
static btTransform RigidBody_TransformCompoundRecursive(btCompoundShape* compound, btScalar mass)
{
btTransform principalTransform;
btScalar* masses = RigidBody_CalculateMasses(compound, mass);
btVector3 principalInertia;
compound->calculatePrincipalAxisTransform(masses, principalTransform, principalInertia);
for (int i = 0; i < compound->getNumChildShapes(); ++i)
{
btCollisionShape* childShape = compound->getChildShape(i);
btTransform childTransform = principalTransform.inverse() * compound->getChildTransform(i);
compound->updateChildTransform(i, childTransform);
if (childShape->isCompound())
{
btTransform childPrincipalTransform = RigidBody_TransformCompoundRecursive(static_cast<btCompoundShape*>(childShape), masses[i]);
compound->updateChildTransform(i, childTransform * childPrincipalTransform);
}
}
delete[] masses;
return principalTransform;
}
static btRigidBody* RigidBody_CreateRigidBody(btRigidBody::btRigidBodyConstructionInfo* constructionInfo)
{
btCollisionShape* collisionShape = constructionInfo->m_collisionShape;
const bool isCompound = collisionShape->isCompound();
btTransform principalTransform;
if (isCompound)
{
btCompoundShape* compound = static_cast<btCompoundShape*>(collisionShape);
principalTransform = RigidBody_TransformCompoundRecursive(compound, constructionInfo->m_mass);
}
constructionInfo->m_collisionShape->calculateLocalInertia(native->m_mass, constructionInfo->m_localInertia);
btRigidBody* body = new btRigidBody(*constructionInfo);
if (isCompound)
{
body->setWorldTransform(body->getWorldTransform() * principalTransform);
}
return body;
}
Code: Select all
- Compound
- Compound at local position (0, 0, 0)
- Box Shape at local position (2, 2, 0)
As you can see, the box appears to be balancing in mid-air on its side.
However, if I configure the tree differently, then I get the result that I expected:
Code: Select all
- Compound
- Compound at local position (2, 2, 0)
- Box Shape at local position (0, 0, 0)
Any ideas as to where I have gone wrong?