!mCachedTransformOutOfDate on btCompoundShape addChildShape

Post Reply
skosh2
Posts: 5
Joined: Thu Dec 08, 2016 11:46 pm

!mCachedTransformOutOfDate on btCompoundShape addChildShape

Post by skosh2 »

I have built a threaded-componentized game-ish toy (badly, I'm sure). Part of my goals is that any object be able to have dynamically added/removed collidable child objects (say, a spoiler on a car. Eventually I want constraints and springs to control the pair). My current design is to have my PhysicsComponents keep a copy of my MotionState, Shape, and RigidBody. I currently make a btCollisionShape for each physics-cabable object (I use the btOgre OgreMesh-to-BulletShape converter to build the shape). This works perfectly.

The problem is my strategy to attach children to this btCollisionShape. Since I can't attach children btCollisionShapes to, say, a btBoxShape, I have been removing the RigidBody/MotionState. I then try to build a RigidBody with a btCompoundShape, but with the Mass, Friction, LocalInertia, LinearVelocity, and AngularVelocity of the old shape. And then, finally, I try to btCompoundShape::addChildShape() the old shape onto this structure. On that line, I get the error: "Assertion failed! !mCachedTransformOutOfDate"

Code: Select all

bool PhysicsFactory::AddComponentChild( PhysicsComponent *parent_comp, PhysicsComponent *child_comp, btDynamicsWorld *dyn_world ){
	if( !parent_comp || !child_comp || !dyn_world ){ return false; }

	if( !parent_comp->is_compound_shape ){
		// What we want to do is to (a) delete the Rigidbody (copy all data), (b) add the old shape as a child to this new shape (setting compoundshape transform to 0),
		// (c) hang the CompoundShape where the old Shape was, and (d) remake the Rigidbody.  Then have a "bool is_compound_shape" and a pointer to 'shape_child'.
		// We can look for this onDelete().
		parent_comp->is_compound_shape = true;
		parent_comp->shape_child = parent_comp->shape;

		// Backup all data from outgoing RigidBody
		//Mass, Friction, LocalInertia, LinearVelocity, AngularVelocity.
		btTransform old_transform = parent_comp->rbody->getWorldTransform(); // Or getCenterOfMassTransform() ?
		btScalar old_friction = parent_comp->rbody->getFriction();
		btVector3 old_local_inertia = parent_comp->rbody->getLocalInertia();
		btVector3 old_linear_velocity = parent_comp->rbody->getLinearVelocity();
		btVector3 old_angular_factor = parent_comp->rbody->getAngularFactor();
		
		// Delete outgoing RigidBody
		dyn_world->removeRigidBody( parent_comp->rbody );
		delete parent_comp->rbody->getMotionState();
		parent_comp->motion_state = NULL;
		delete parent_comp->rbody;
		parent_comp->rbody = NULL;

		// Recreate incoming RigidBody
		parent_comp->motion_state = CreateMotionState( &old_transform, parent_comp->snode, parent_comp->use_ogremotionstate );
		parent_comp->shape = new btCompoundShape();
		parent_comp->rbody = CreateRigidBody( parent_comp->mass, parent_comp->motion_state, parent_comp->shape, parent_comp->is_kinematic );

		parent_comp->rbody->setUserPointer( parent_comp );

		// Restore old data to incoming RigidBody
		parent_comp->rbody->setFriction( old_friction );
		parent_comp->rbody->setLinearVelocity( old_angular_factor );
		parent_comp->rbody->setAngularFactor( old_angular_factor );
		parent_comp->rbody->setWorldTransform( old_transform );
		//parent_comp->rbody->setLocalInertia( old_local_inertia );	// Needed?

		dyn_world->addRigidBody( parent_comp->rbody );
	}

	btCompoundShape *parent_comp_shape = dynamic_cast<btCompoundShape*>(parent_comp->shape);
	parent_comp_shape->addChildShape( child_comp->transform, child_comp->shape );	// "Assertion failed! !mCachedTransformOutOfDate"
}
What are the likely causes for btCompoundShape::addChildShape() to reliably fail?

Is this even the best way of doing this? Are there other designs that make more sense?

The immediate workaround that came to my mind was to simply make *every* physics-capable object a btCompoundShape object to begin with, with an attached 'main body'. Is this performant? Would it work acceptably well in a scene with 250-300 collidables (all things being equal)?

Thanks for your help.
-skosh
Post Reply