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

Open
himisa wants to merge 5 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 3 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

@ -352,7 +352,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;
@ -1119,6 +1119,7 @@ rbConstraint *RB_constraint_new_motor(float pivot[3],
void RB_constraint_delete(rbConstraint *con)
{
btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint *>(con);
constraint->invalidate();
delete constraint;
}