Fix issue with collision between a CollisionBody and a RigidBody in a DynamicsWorld

This commit is contained in:
Daniel Chappuis 2018-05-29 21:44:56 +02:00
parent 243256db11
commit 6732a8119c
2 changed files with 25 additions and 22 deletions

View File

@ -110,7 +110,7 @@ class CollisionDetection {
void computeNarrowPhase(); void computeNarrowPhase();
/// Add a contact manifold to the linked list of contact manifolds of the two bodies /// Add a contact manifold to the linked list of contact manifolds of the two bodies
/// involed in the corresponding contact. /// involved in the corresponding contact.
void addContactManifoldToBody(OverlappingPair* pair); void addContactManifoldToBody(OverlappingPair* pair);
/// Fill-in the collision detection matrix /// Fill-in the collision detection matrix

View File

@ -359,11 +359,8 @@ void DynamicsWorld::solveContactsAndConstraints() {
// For each island of the world // For each island of the world
for (uint islandIndex = 0; islandIndex < mNbIslands; islandIndex++) { for (uint islandIndex = 0; islandIndex < mNbIslands; islandIndex++) {
// Check if there are contacts and constraints to solve // If there are constraints to solve
bool isConstraintsToSolve = mIslands[islandIndex]->getNbJoints() > 0; if (mIslands[islandIndex]->getNbJoints() > 0) {
// If there are constraints
if (isConstraintsToSolve) {
// Initialize the constraint solver // Initialize the constraint solver
mConstraintSolver.initializeForIsland(mTimeStep, mIslands[islandIndex]); mConstraintSolver.initializeForIsland(mTimeStep, mIslands[islandIndex]);
@ -374,9 +371,10 @@ void DynamicsWorld::solveContactsAndConstraints() {
for (uint i=0; i<mNbVelocitySolverIterations; i++) { for (uint i=0; i<mNbVelocitySolverIterations; i++) {
for (uint islandIndex = 0; islandIndex < mNbIslands; islandIndex++) { for (uint islandIndex = 0; islandIndex < mNbIslands; islandIndex++) {
// Solve the constraints // Solve the constraints
bool isConstraintsToSolve = mIslands[islandIndex]->getNbJoints() > 0; if (mIslands[islandIndex]->getNbJoints() > 0) {
if (isConstraintsToSolve) {
mConstraintSolver.solveVelocityConstraints(mIslands[islandIndex]); mConstraintSolver.solveVelocityConstraints(mIslands[islandIndex]);
} }
} }
@ -724,7 +722,7 @@ void DynamicsWorld::computeIslands() {
RigidBody* bodyToVisit = stackBodiesToVisit[stackIndex]; RigidBody* bodyToVisit = stackBodiesToVisit[stackIndex];
assert(bodyToVisit->isActive()); assert(bodyToVisit->isActive());
// Awake the body if it is slepping // Awake the body if it is sleeping
bodyToVisit->setIsSleeping(false); bodyToVisit->setIsSleeping(false);
// Add the body into the island // Add the body into the island
@ -746,22 +744,27 @@ void DynamicsWorld::computeIslands() {
// Check if the current contact manifold has already been added into an island // Check if the current contact manifold has already been added into an island
if (contactManifold->isAlreadyInIsland()) continue; if (contactManifold->isAlreadyInIsland()) continue;
// Add the contact manifold into the island
mIslands[mNbIslands]->addContactManifold(contactManifold);
contactManifold->mIsAlreadyInIsland = true;
// Get the other body of the contact manifold // Get the other body of the contact manifold
RigidBody* body1 = static_cast<RigidBody*>(contactManifold->getBody1()); RigidBody* body1 = dynamic_cast<RigidBody*>(contactManifold->getBody1());
RigidBody* body2 = static_cast<RigidBody*>(contactManifold->getBody2()); RigidBody* body2 = dynamic_cast<RigidBody*>(contactManifold->getBody2());
RigidBody* otherBody = (body1->getId() == bodyToVisit->getId()) ? body2 : body1;
// Check if the other body has already been added to the island // If the colliding body is a RigidBody (and not a CollisionBody instead)
if (otherBody->mIsAlreadyInIsland) continue; if (body1 != nullptr && body2 != nullptr) {
// Insert the other body into the stack of bodies to visit // Add the contact manifold into the island
stackBodiesToVisit[stackIndex] = otherBody; mIslands[mNbIslands]->addContactManifold(contactManifold);
stackIndex++; contactManifold->mIsAlreadyInIsland = true;
otherBody->mIsAlreadyInIsland = true;
RigidBody* otherBody = (body1->getId() == bodyToVisit->getId()) ? body2 : body1;
// Check if the other body has already been added to the island
if (otherBody->mIsAlreadyInIsland) continue;
// Insert the other body into the stack of bodies to visit
stackBodiesToVisit[stackIndex] = otherBody;
stackIndex++;
otherBody->mIsAlreadyInIsland = true;
}
} }
// For each joint in which the current body is involved // For each joint in which the current body is involved