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
Constraint bug with 2.54
-
- Posts: 18
- Joined: Fri Apr 21, 2006 3:04 pm
- Location: uk
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)
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)
-
- Posts: 16
- Joined: Fri May 11, 2007 7:06 am
-
- Site Admin
- Posts: 4221
- Joined: Sun Jun 26, 2005 6:43 pm
- Location: California, USA
-
- Posts: 16
- Joined: Fri May 11, 2007 7:06 am
Well for some reason my callstack gets corrupted. The IDE gives me the error:
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)
So maybe something like this would fix it?
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
Code: Select all
void btDiscreteDynamicsWorld::removeConstraint(btTypedConstraint* constraint)
{
m_constraints.remove(constraint);
constraint->getRigidBodyA().removeConstraintRef(constraint);
constraint->getRigidBodyB().removeConstraintRef(constraint);
}
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);
}
-
- Posts: 6
- Joined: Tue Jun 19, 2007 9:16 am
- Location: Sweden
No, it won't. The constraint holds references, not pointers, to the bodies so this won't help.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); }
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
-
- Site Admin
- Posts: 4221
- Joined: Sun Jun 26, 2005 6:43 pm
- Location: California, USA
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.
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:
Thanks for the feedback!
Erwin
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.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).
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);
}
Erwin