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