I have reduced the problem down so it can be demonstrated (I used one of the demos that came with the bullet source code). Basically:

* I have a box that is part of a node tree. This box is implemented as a btBoxShape inside a btCompoundShape with its own transform.

* If I use the child shape transform to include the parent node transform, the box appears in the expected place (using the debug drawer). But I wish to animate this box, so having the node transform baked into the child shape is not going to work.

* If I move the node transform to the btRigidBody, the box appears somewhere else. The expectation was box1 and box2 would be in the same position/rotation.

Clearly I'm misunderstanding something. Would anyone know why the transforms behave this way?

Code: Select all

```
// node12 transform
btVector3 v0(0.0, 18.7639, 1.66574);
btMatrix3x3 m0(-0.0000, -0.0000, -1.0000, -0.9989, 0.0630, 0.0000, 0.0639, 0.9989, -0.0000);
btTransform tNode12(m0, v0);
// bhkRigidBodyT local transform
btVector3 vr(1.6761*7, 0.0000*7, 0.0000*7);
btQuaternion qr;
btTransform tLocal(qr.getIdentity(), vr); // no rotation
// correct position of collision shape
btBoxShape *box1 = new btBoxShape(btVector3(1.6761*7, 0.3929*7, 1.7485*7));
btCompoundShape* p1 = new btCompoundShape();
p1->addChildShape(tNode12 * tLocal, box1);
btRigidBody::btRigidBodyConstructionInfo rbInfo1(/*mass*/0.f, /*MotionState*/0, p1, btVector3(0.f, 0.f, 0.f));
btRigidBody *body1 = new btRigidBody(rbInfo1);
btTransform tOrigin;
tOrigin.setIdentity();
body1->setWorldTransform(tOrigin);
m_dynamicsWorld->addRigidBody(body1);
// collision shape in unexpected place
btBoxShape *box2 = new btBoxShape(btVector3(1.6761*7, 0.3929*7, 1.7485*7)); // exactly the same as box1
btCompoundShape* p2 = new btCompoundShape();
p1->addChildShape(tLocal, box2); // <----- node transform taken out of child shape transform
btRigidBody::btRigidBodyConstructionInfo rbInfo2(/*mass*/0.f, /*MotionState*/0, p2, btVector3(0.f, 0.f, 0.f));
btRigidBody *body2 = new btRigidBody(rbInfo2);
body2->setWorldTransform(tOrigin * tNode12); // <----- node transform is now here as part of world transform
m_dynamicsWorld->addRigidBody(body2);
```