Recalculate local origin of btCompoundShape?

Post Reply
whitwhoa
Posts: 17
Joined: Tue Jun 11, 2019 7:30 pm

Recalculate local origin of btCompoundShape?

Post by whitwhoa »

Curious if there is a way to recalculate the local origin of a btCompoundShape? I currently have a shape consisting of two spheres and a cylinder, however the origin of the btCompoundShape seems to be the origin of one of it's child shapes and not the origin of the aabb for the compound shape.

Below is an image of the btPairCachingGhostObject which uses the btCompoundShape with it's origin set as follows (where y is up -z forward):

Code: Select all

this->ghostObject->getWorldTransform().setOrigin(btVector3(2, 0, 0));
bbbb.JPG
bbbb.JPG (23.95 KiB) Viewed 4275 times

Below is how the btCompoundShape and btPairCachingGhostObject are being generated:

Code: Select all

btCylinderShape* cyl = new btCylinderShape(btVector3(this->radius, (1.25f / 2.0f), this->radius));
btTransform cylTran;
cylTran.setIdentity();
cylTran.setOrigin(btVector3(0,0,0));


btSphereShape* sphereSmall = new btSphereShape(0.36f);
btTransform sphereSmallTran;
sphereSmallTran.setIdentity();
sphereSmallTran.setOrigin(btVector3(0, -0.77456, 0));


btSphereShape* blendSphere = new btSphereShape(0.4f);
btTransform blendSphereTran;
blendSphereTran.setIdentity();
blendSphereTran.setOrigin(btVector3(0, -0.62507, 0));


btCompoundShape* compoundShape = new btCompoundShape();
compoundShape->addChildShape(cylTran, cyl);
compoundShape->addChildShape(sphereSmallTran, sphereSmall);
compoundShape->addChildShape(blendSphereTran, blendSphere);


this->shape = compoundShape;


this->ghostObject = new btPairCachingGhostObject();
this->ghostObject->setCollisionShape(this->shape);
this->ghostObject->setCollisionFlags(btCollisionObject::CF_NO_CONTACT_RESPONSE);
this->collisionWorld->getDynamicsWorld()->addCollisionObject(this->ghostObject, btBroadphaseProxy::KinematicFilter, btBroadphaseProxy::StaticFilter | btBroadphaseProxy::DefaultFilter);
this->collisionWorld->getDynamicsWorld()->getPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());


this->ghostObject->getWorldTransform().setOrigin(btVector3(2, 0, 0));
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Recalculate local origin of btCompoundShape?

Post by drleviathan »

In the local-frame the origin and center of mass of the base btCollisionShape is always implicitly <0,0,0>. In other words: in the world-frame its center of mass is its position (e.g. its origin transformed by its worldTransform).

With a btCompoundShape what you're supposed to do is: compute the center of mass during the convex decomposition stage: in general it will have a non-identity transform. Then adjust the local-transforms of all the convex parts such that the center of mass is at the origin. For each subshape the math would be:

new_local_transform = inverse_center_of_mass_transform * old_local_transform

Finally, when adding each child to the compound shape you would supply its new_local_transform.

Code: Select all

compound_shape->addChildShape(new_local_transforms[i], sub_shapes[i]);
whitwhoa
Posts: 17
Joined: Tue Jun 11, 2019 7:30 pm

Re: Recalculate local origin of btCompoundShape?

Post by whitwhoa »

Greatly appreciated! Was able to get it worked out. Also came across this gist while researching what you had explained, which helped out as well. :)
Post Reply