Correct way to delete constraints if rigid body will be dele

Post Reply
Szepe
Posts: 3
Joined: Fri Jan 16, 2015 2:46 pm

Correct way to delete constraints if rigid body will be dele

Post by Szepe »

I'm looking for a way to delete the associated constraint if the main or target object of the constraint is deleted.
I have done it like Erwin described here in this post. http://www.bulletphysics.org/Bullet/php ... f=9&t=2814

But if I do so the constraint is only deleted if the main object is deleted (object 3).
Joints_3.png
Joints_3.png (2.79 KiB) Viewed 7517 times
If the target object will be deleted the constraint will not be deleted (object 4).
Joints_4.png
Joints_4.png (3.41 KiB) Viewed 7517 times
If a add the reference with addConstraintRef() to the target object, the collisions between linked bodies will be disabled.
1. Is there a simple way, without modifying the bullet source, to delete the constraint if the target object will be deleted?
2. Why the constraint references is used to disable the collisions between linked bodies?

Code: Select all

653
void	btDiscreteDynamicsWorld::addConstraint(btTypedConstraint* constraint,bool disableCollisionsBetweenLinkedBodies)
{
	m_constraints.push_back(constraint);
	if (disableCollisionsBetweenLinkedBodies)
	{
		constraint->getRigidBodyA().addConstraintRef(constraint);
		constraint->getRigidBodyB().addConstraintRef(constraint);
	}
}

320
bool btRigidBody::checkCollideWithOverride(const  btCollisionObject* co) const
{
	const btRigidBody* otherRb = btRigidBody::upcast(co);
	if (!otherRb)
		return true;

	for (int i = 0; i < m_constraintRefs.size(); ++i)
	{
		const btTypedConstraint* c = m_constraintRefs[i];
		if (c->isEnabled())
			if (&c->getRigidBodyA() == otherRb || &c->getRigidBodyB() == otherRb)
				return false;
	}

	return true;
}
lunkhound
Posts: 99
Joined: Thu Nov 21, 2013 8:57 pm

Re: Correct way to delete constraints if rigid body will be

Post by lunkhound »

This is my understanding:
Since the constraint holds pointers to the rigid bodies it constrains, you need to remove the constraint first with

Code: Select all

world->removeConstraint( constraint );
before deleting either of the objects. Otherwise the constraint will have dangling pointers to those objects.
Once the constraint has been removed from the world, then you can delete it and get rid of the objects.
Szepe
Posts: 3
Joined: Fri Jan 16, 2015 2:46 pm

Re: Correct way to delete constraints if rigid body will be

Post by Szepe »

Correct. That is what I am doing.
But to identify and get the correct joint from the rigid body I use the the the constraint reference.
Like Erwin is does. Look at the link in the first post.

Code: Select all

	//also remove constraint
	btRigidBody* body = ctrl->GetRigidBody();
	if (body)
	{
		for (int i = body->getNumConstraintRefs() - 1; i >= 0; i--)
		{
			btTypedConstraint* con = body->getConstraintRef(i);
			m_dynamicsWorld->removeConstraint(con);
			//body->removeConstraintRef(con);
			//delete con; //might be kept by python KX_ConstraintWrapper
		}
		m_dynamicsWorld->removeRigidBody(ctrl->GetRigidBody());
	.
	.
	.
	.
	}
lunkhound
Posts: 99
Joined: Thu Nov 21, 2013 8:57 pm

Re: Correct way to delete constraints if rigid body will be

Post by lunkhound »

Szepe wrote:Correct. That is what I am doing.
But to identify and get the correct joint from the rigid body I use the the the constraint reference.
Like Erwin is does. Look at the link in the first post.
Yes I saw the thread you linked to. Those constraint references only get added to the bodies when you are disabling collision between linked bodies when you create the constraint.
If you want to sometimes have linked bodies that can collide, then you can't use constraint references like that. You'll need to devise another way to keep track of constraints.
Szepe
Posts: 3
Joined: Fri Jan 16, 2015 2:46 pm

Re: Correct way to delete constraints if rigid body will be

Post by Szepe »

Hm. I know. But I'm searching nice clean way to delete the constraints. Storing the constraint references a second time somewhere in the main code is no clean way of programming.

Is there a way to get from the target object the main object constraint?


Side note:
I don't understand why Erwin use the constraint references to disable the collision. Why he not store the state of disableCollisionsBetweenLinkedBodies directly to reference? Then we can use the references to delete the constraints and can enable and disable the linked collision.

I also don't understand why the constraints not automatically delete if the associated objects are deleted. It makes no sense to keep the constraints if the objects are deleted.
And the code he provide only works correct if disableCollisionsBetweenLinkedBodies is true. If it false the deletion is not working or only the half way if I store only one reference.
lunkhound
Posts: 99
Joined: Thu Nov 21, 2013 8:57 pm

Re: Correct way to delete constraints if rigid body will be

Post by lunkhound »

Well it seems to me that Bullet was designed with the assumption that client applications are going to have some type of wrapper-object for each Bullet object. That's why each Bullet object has a user-pointer, to make it very easy to map from the Bullet object to the wrapper class. And it's quite easy for the wrapper class to take care of such bookkeeping.

Personally, I don't want Bullet doing any extra bookkeeping that isn't strictly necessary. Efficiency should take priority over cleanliness of code (to a point).
Post Reply