Fix #101877, rigidbodies & constraints causing frequent crashes. #108399

Open
himisa wants to merge 1 commits from himisa/blender:fix_rigid_crash into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
4 changed files with 22 additions and 6 deletions

View File

@ -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),

View File

@ -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;

View File

@ -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)

View File

@ -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;
}