Fix #101877, rigidbodies & constraints causing frequent crashes. #108399
@ -26,6 +26,7 @@ btTypedConstraint::btTypedConstraint(btTypedConstraintType type, btRigidBody& rb
|
||||
m_breakingImpulseThreshold(SIMD_INFINITY),
|
||||
m_isEnabled(true),
|
||||
m_needsFeedback(false),
|
||||
m_isValid(true),
|
||||
m_overrideNumSolverIterations(-1),
|
||||
m_rbA(rbA),
|
||||
m_rbB(getFixedBody()),
|
||||
@ -42,6 +43,7 @@ btTypedConstraint::btTypedConstraint(btTypedConstraintType type, btRigidBody& rb
|
||||
m_breakingImpulseThreshold(SIMD_INFINITY),
|
||||
m_isEnabled(true),
|
||||
m_needsFeedback(false),
|
||||
m_isValid(true),
|
||||
m_overrideNumSolverIterations(-1),
|
||||
m_rbA(rbA),
|
||||
m_rbB(rbB),
|
||||
|
@ -84,6 +84,7 @@ btTypedConstraint : public btTypedObject
|
||||
btScalar m_breakingImpulseThreshold;
|
||||
bool m_isEnabled;
|
||||
bool m_needsFeedback;
|
||||
bool m_isValid;
|
||||
int m_overrideNumSolverIterations;
|
||||
|
||||
btTypedConstraint& operator=(btTypedConstraint& other)
|
||||
@ -198,6 +199,18 @@ public:
|
||||
m_breakingImpulseThreshold = threshold;
|
||||
}
|
||||
|
||||
bool isValid() const{
|
||||
return m_isValid;
|
||||
}
|
||||
|
||||
void invalidate(){
|
||||
if(isValid()){
|
||||
m_rbA.removeConstraintRef(this);
|
||||
m_rbB.removeConstraintRef(this);
|
||||
m_isValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool isEnabled() const
|
||||
{
|
||||
return m_isEnabled;
|
||||
|
@ -530,6 +530,10 @@ void btDiscreteDynamicsWorld::removeCollisionObject(btCollisionObject* collision
|
||||
|
||||
void btDiscreteDynamicsWorld::removeRigidBody(btRigidBody* body)
|
||||
{
|
||||
for (int i = body->getNumConstraintRefs() - 1; i >= 0; i--) {
|
||||
btTypedConstraint *con=body->getConstraintRef(i);
|
||||
removeConstraint(con);
|
||||
}
|
||||
m_nonStaticRigidBodies.remove(body);
|
||||
btCollisionWorld::removeCollisionObject(body);
|
||||
}
|
||||
@ -644,8 +648,7 @@ void btDiscreteDynamicsWorld::addConstraint(btTypedConstraint* constraint, bool
|
||||
void btDiscreteDynamicsWorld::removeConstraint(btTypedConstraint* constraint)
|
||||
{
|
||||
m_constraints.remove(constraint);
|
||||
constraint->getRigidBodyA().removeConstraintRef(constraint);
|
||||
constraint->getRigidBodyB().removeConstraintRef(constraint);
|
||||
constraint->invalidate();
|
||||
}
|
||||
|
||||
void btDiscreteDynamicsWorld::addAction(btActionInterface* action)
|
||||
|
@ -353,7 +353,7 @@ void RB_body_delete(rbRigidBody *object)
|
||||
* but since we delete everything when the world is rebult, we need to do it manually here */
|
||||
for (int i = body->getNumConstraintRefs() - 1; i >= 0; i--) {
|
||||
btTypedConstraint *con = body->getConstraintRef(i);
|
||||
body->removeConstraintRef(con);
|
||||
con->invalidate();
|
||||
}
|
||||
|
||||
delete body;
|
||||
@ -1124,9 +1124,7 @@ void RB_constraint_delete(rbConstraint *con)
|
||||
/* If the constraint has disabled collisions between the bodies, those bodies
|
||||
* will have a pointer back to the constraint. We need to remove the constraint
|
||||
* from each body to avoid dereferencing the deleted constraint later (#91369) */
|
||||
constraint->getRigidBodyA().removeConstraintRef(constraint);
|
||||
constraint->getRigidBodyB().removeConstraintRef(constraint);
|
||||
|
||||
constraint->invalidate();
|
||||
delete constraint;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user