Constraint bug with 2.54

Post Reply
Jacky_J
Posts: 16
Joined: Fri May 11, 2007 7:06 am

Constraint bug with 2.54

Post by Jacky_J »

With the new 2.54, i'm experiencing a new bug when deleting constraints after rigid bodies.

Basically: i'm getting a crash inside VS2005 when i delete a constraint after a rigid body. However, i can't reproduce the crash inside a test crash, or outside debugging inside VS2005. Not very convincing is it?

Well. there's some code that was added in 2.54 with constraints. Something to do with ConstraintRef. I don't know why it's crashing, but hopefully someone else has experienced this, otherwise looks like i'm gonna have to delete constraints AFTER i delete rigidbodies.

Thanks
Proctoid
Posts: 18
Joined: Fri Apr 21, 2006 3:04 pm
Location: uk

Post by Proctoid »

i use the btDiscreteDynamicsWorld::removeConstraint(btTypedConstraint* constraint)
to remove a constraint between two rigid bodies BEFORE removing the rigid bodies and all works fine.
take a look at the function if you are doing something different or are not using a btDiscreteDynamicsWorld
(btDiscreteDynamicsWorld.cpp line 398),
if i were to do it wrong and delete bodies first then call removeConstraint then it would also die horribly
(because removing bodies does not change the constraint objects reference bodies)
Jacky_J
Posts: 16
Joined: Fri May 11, 2007 7:06 am

Post by Jacky_J »

Hey Proctoid.

You're right, i meant to say delete constraints before rigid bodies. (hint: don't post after poker night and drinking)

So i guess the proper way is to delete constraints first. It's weird that it was working (by working i mean not crashing) up until 2.54.

Thanks
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Post by Erwin Coumans »

Can you please provide a callstack at the point of the crash?

Thanks for the report!
Erwin
Jacky_J
Posts: 16
Joined: Fri May 11, 2007 7:06 am

Post by Jacky_J »

Well for some reason my callstack gets corrupted. The IDE gives me the error:

Code: Select all

Windows has triggered a breakpoint in irrlamb.exe.

This may be due to a corruption of the heap, and indicates a bug in irrlamb.exe or any of the DLLs it has loaded.

The output window may have more diagnostic information
Anyway, Proctoid pointed out that the rigidbodies don't update the constraint references. So if you delete a rigidbody, then the constraint, the rigidbody object is invalid when it tries to remove the references. It makes sense to me, and that code was added around SVN #656 (which was after bullet 2.53)

Code: Select all

void	btDiscreteDynamicsWorld::removeConstraint(btTypedConstraint* constraint)
{
	m_constraints.remove(constraint);
	constraint->getRigidBodyA().removeConstraintRef(constraint);
	constraint->getRigidBodyB().removeConstraintRef(constraint);
}
So maybe something like this would fix it?

Code: Select all

void	btDiscreteDynamicsWorld::removeConstraint(btTypedConstraint* constraint)
{
	m_constraints.remove(constraint);
	if(constraint->getRigidBodyA())
		constraint->getRigidBodyA().removeConstraintRef(constraint);
	if(constraint->getRigidBodyB())
		constraint->getRigidBodyB().removeConstraintRef(constraint);
}
thebolt
Posts: 6
Joined: Tue Jun 19, 2007 9:16 am
Location: Sweden

Post by thebolt »

Jacky_J wrote: So maybe something like this would fix it?

Code: Select all

void	btDiscreteDynamicsWorld::removeConstraint(btTypedConstraint* constraint)
{
	m_constraints.remove(constraint);
	if(constraint->getRigidBodyA())
		constraint->getRigidBodyA().removeConstraintRef(constraint);
	if(constraint->getRigidBodyB())
		constraint->getRigidBodyB().removeConstraintRef(constraint);
}
No, it won't. The constraint holds references, not pointers, to the bodies so this won't help.

Fact is that the old code technically was invalid too (the references in the constraint referred to non-existing rigid bodies) however as it never accessed them you wouldn't see the problem. The old code would crash if you removed a rigid body but forgot to remove the constraint, however then it would crash during the stepping routine.

As I see it the only valid solution would be to trigger a removal of the constraint when the bodies are removed.

-Marten
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Post by Erwin Coumans »

The problem should only happen when you delete rigidbodies while constraints exist in the dynamicsworld that point to them. You need to remove the constraints first, before deleting the rigidbody.
thebolt wrote:so the only solution I can see to this is to change constraint to not hold references but pointers (and to zero the pointer on body deletion).
You introduce invalid constraints (between 2 static rigidbodies etc) that way. This also happens with pointers, but also if we would set the rigidbody references to refer to the special 'static rigidbody' that always exists.

Users always need to remove constraints before they delete the rigidbodies they refer to. I'll add an assert to make sure no constraints point to this rigidbody (the ConstraintRef array needs to be empty), in the destructor:

Code: Select all

virtual ~btRigidBody()
        {
                //No constraints should point to this rigidbody: remove constraints from the dynamics world before you delete the related rigidbodies.
                btAssert(m_constraintRefs.size()==0);
        }
Thanks for the feedback!
Erwin
Post Reply