Collision shape replacement

User avatar
frca
Posts: 39
Joined: Sat May 02, 2009 9:38 am

Collision shape replacement

Post by frca »

Hello!
Is it possible to replace a collision shape for a given rigid body? Let's say I've created a rigid body and passed a box collision shape in its constructor. Now I want to throw that shape away and assign a sphere shape. Is that possible?
Thanks
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Re: Collision shape replacement

Post by Erwin Coumans »

There are a few steps to do this:

1) remove the object from the world
2) assign the new shape using object->setCollisionShape(newShape)
3) recompute the inertia tensor for dynamic objects (mass>0) using newShape->calcLocalInertia(...) and use body->setMassProps
4) add the body to the world

Thanks,
Erwin
tomacpace
Posts: 3
Joined: Sun Apr 11, 2010 7:07 pm

Re: Collision shape replacement

Post by tomacpace »

Hi
I have a question very similar.

A couple months ago I posted about this and somehow I found the solution as Erwin Coumans posted above.

The difference in my case, is I'm removing two rigidbodies, each with a box shape, and combining them into a compound shape and adding them back to the world.


Basically this:

Code: Select all

softRigidDynamicsWorld->removeRigidBody(collisionBox1->_btRigidBody);
softRigidDynamicsWorld->removeRigidBody(collisionBox2->_btRigidBody);

btCompoundShape *_btCompoundShape = new btCompoundShape();
_btCompoundShape->addChildShape(  collisionBox1->_btRigidBody->getWorldTransform(), collisionBox1->_btRigidBody->getCollisionShape() );
_btCompoundShape->addChildShape(  collisionBox2->_btRigidBody->getWorldTransform(), collisionBox2->_btRigidBody->getCollisionShape() );

// assorted memory management lines...

collisionBox1->_btRigidBody->setCollisionShape( _btCompoundShape);

softRigidDynamicsWorld->addRigidBody( collisionBox1->_btRigidBody);

The problem is, after this is done, only one of the collision boxes gets hit (100%). Projectiles can pass through the second collision box and about 90% of the time there is no collision. It seems random, but about 10% of the projectiles will collide.

How could this make sense? I don't know what I could be missing. The projectiles also have only a box collision shape.


Update
Problem solved! Similar to my first problem message on the forum, this turns out to not to be a Bullet issue, but rather a difficult-to-debug discrepancy between the object's physics representation and the graphics representation. The problematic box-collisionShape in the btCompoundShape was VERY tiny, thus only a few large objects passing through would hit the object. I solved it by just throwing many of projectiles randomly at the graphical object, and identified a place where projectiles made 100% collisions. But the collisions were at a very small specific spot in the entire graphical body.

The graphics engine I am using is a third-party package, with the Bullet library as a component. The engine also has a minimum of wrapper functions for bullet, enough for people to survive without touching bullet. So I have had to start learning bullet after a lot of insulated usage of the library. Sort of skipped the "Hello world" introduction and was thrown head-first into the wonderful giant physics machine.
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Re: Collision shape replacement

Post by Erwin Coumans »

Good. It looks like the child transform passed in the btCompoundShape is wrong: it should be a local offset relative to the rigid body, not a world transform.

btCompoundShape *_btCompoundShape = new btCompoundShape();
_btCompoundShape->addChildShape( collisionBox1->_btRigidBody->getWorldTransform(), collisionBox1->_btRigidBody->getCollisionShape() );

Thanks,
Erwin