Skip to content

Commit

Permalink
UPBGE: Fix character collision detection. (#866)
Browse files Browse the repository at this point in the history
Chracter controller is using a ghost object and in particular
a ghost object caching collision pairs named btPairCachingGhostObject.
But with the recent update of bullet, we realized after some bug
reported around character that the caching of collision is not
anymore supported in a safe way.

Instead of fixing the caching mechanism, it was choose to replace
btPairCachingGhostObject by btGhostObject.

The btGhostObject is already maintaining a cache of object overlapping
the only step added is asking the pair cache in the world dispatcher
for the character ghost and one of its overlapping objects.
By this way the character is just reading and not managing duplication
or deletion of manifold in its own cache which is the safest solution.

In the same time the function btSequentialImpulseConstraintSolver::getOrInitSolverBody
is not handling ghost object but only soft, rigid, kinematic and multibody.
An assert is disabled with the adjonction of ghost type check.

Fix issue #838.
  • Loading branch information
panzergame authored Oct 5, 2018
1 parent ad24de4 commit 8d97bab
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ btVector3 btKinematicCharacterController::perpindicularComponent (const btVector
return direction - parallelComponent(direction, normal);
}

btKinematicCharacterController::btKinematicCharacterController (btPairCachingGhostObject* ghostObject,btConvexShape* convexShape,btScalar stepHeight, const btVector3& up)
btKinematicCharacterController::btKinematicCharacterController (btGhostObject* ghostObject,btConvexShape* convexShape,btScalar stepHeight, const btVector3& up)
{
m_ghostObject = ghostObject;
m_up.setValue(0.0f, 0.0f, 1.0f);
Expand Down Expand Up @@ -170,7 +170,7 @@ btKinematicCharacterController::~btKinematicCharacterController ()
{
}

btPairCachingGhostObject* btKinematicCharacterController::getGhostObject()
btGhostObject* btKinematicCharacterController::getGhostObject()
{
return m_ghostObject;
}
Expand All @@ -194,26 +194,32 @@ bool btKinematicCharacterController::recoverFromPenetration ( btCollisionWorld*

bool penetration = false;

collisionWorld->getDispatcher()->dispatchAllCollisionPairs(m_ghostObject->getOverlappingPairCache(), collisionWorld->getDispatchInfo(), collisionWorld->getDispatcher());

m_currentPosition = m_ghostObject->getWorldTransform().getOrigin();


btOverlappingPairCache *pairCache = collisionWorld->getPairCache();
const unsigned int numPairs = m_ghostObject->getNumOverlappingObjects();

// btScalar maxPen = btScalar(0.0);
for (int i = 0; i < m_ghostObject->getOverlappingPairCache()->getNumOverlappingPairs(); i++)
for (int i = 0; i < numPairs; i++)
{
m_manifoldArray.resize(0);
btCollisionObject *obj0 = m_ghostObject;
btCollisionObject *obj1 = m_ghostObject->getOverlappingObject(i);

btBroadphasePair* collisionPair = &m_ghostObject->getOverlappingPairCache()->getOverlappingPairArray()[i];
btBroadphaseProxy *proxy0 = obj0->getBroadphaseHandle();
btBroadphaseProxy *proxy1 = obj1->getBroadphaseHandle();

btCollisionObject* obj0 = static_cast<btCollisionObject*>(collisionPair->m_pProxy0->m_clientObject);
btCollisionObject* obj1 = static_cast<btCollisionObject*>(collisionPair->m_pProxy1->m_clientObject);
btBroadphasePair* collisionPair = pairCache->findPair(proxy0, proxy1);

btAssert(collisionPair);

if ((obj0 && !obj0->hasContactResponse()) || (obj1 && !obj1->hasContactResponse()))
continue;

if (!needsCollision(obj0, obj1))
continue;


m_manifoldArray.resize(0);

if (collisionPair->m_algorithm)
collisionPair->m_algorithm->getAllContactManifolds(m_manifoldArray);

Expand Down Expand Up @@ -688,11 +694,11 @@ void btKinematicCharacterController::reset ( btCollisionWorld* collisionWorld )
m_velocityTimeInterval = 0.0;

//clear pair cache
btHashedOverlappingPairCache *cache = m_ghostObject->getOverlappingPairCache();
/*btHashedOverlappingPairCache *cache = m_ghostObject->getOverlappingPairCache();
while (cache->getOverlappingPairArray().size() > 0)
{
cache->removeOverlappingPair(cache->getOverlappingPairArray()[0].m_pProxy0, cache->getOverlappingPairArray()[0].m_pProxy1, collisionWorld->getDispatcher());
}
}*/
}

void btKinematicCharacterController::warp (const btVector3& origin)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class btConvexShape;
class btRigidBody;
class btCollisionWorld;
class btCollisionDispatcher;
class btPairCachingGhostObject;
class btGhostObject;

///btKinematicCharacterController is an object that supports a sliding motion in a world.
///It uses a ghost object and convex sweep test to test for upcoming collisions. This is combined with discrete collision detection to recover from penetrations.
Expand All @@ -40,7 +40,7 @@ ATTRIBUTE_ALIGNED16(class) btKinematicCharacterController : public btCharacterCo

btScalar m_halfHeight;

btPairCachingGhostObject* m_ghostObject;
btGhostObject* m_ghostObject;
btConvexShape* m_convexShape;//is also in m_ghostObject, but it needs to be convex, so we store it here to avoid upcast

btScalar m_maxPenetrationDepth;
Expand Down Expand Up @@ -117,7 +117,7 @@ ATTRIBUTE_ALIGNED16(class) btKinematicCharacterController : public btCharacterCo

BT_DECLARE_ALIGNED_ALLOCATOR();

btKinematicCharacterController (btPairCachingGhostObject* ghostObject,btConvexShape* convexShape,btScalar stepHeight, const btVector3& up = btVector3(1.0,0.0,0.0));
btKinematicCharacterController (btGhostObject* ghostObject,btConvexShape* convexShape,btScalar stepHeight, const btVector3& up = btVector3(1.0,0.0,0.0));
~btKinematicCharacterController ();


Expand Down Expand Up @@ -191,7 +191,7 @@ ATTRIBUTE_ALIGNED16(class) btKinematicCharacterController : public btCharacterCo
void setMaxPenetrationDepth(btScalar d);
btScalar getMaxPenetrationDepth() const;

btPairCachingGhostObject* getGhostObject();
btGhostObject* getGhostObject();
void setUseGhostSweepTest(bool useGhostObjectSweepTest)
{
m_useGhostObjectSweepTest = useGhostObjectSweepTest;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -785,8 +785,9 @@ int btSequentialImpulseConstraintSolver::getOrInitSolverBody(btCollisionObject&
else
{
bool isMultiBodyType = (body.getInternalType()&btCollisionObject::CO_FEATHERSTONE_LINK);
const bool isGhostType = (body.getInternalType() & btCollisionObject::CO_GHOST_OBJECT);
// Incorrectly set collision object flags can degrade performance in various ways.
if (!isMultiBodyType)
if (!isMultiBodyType && !isGhostType)
{
btAssert( body.isStaticOrKinematicObject() );
}
Expand Down
6 changes: 3 additions & 3 deletions source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ float gLinearSleepingTreshold;
float gAngularSleepingTreshold;

CcdCharacter::CcdCharacter(CcdPhysicsController *ctrl, btMotionState *motionState,
btPairCachingGhostObject *ghost, btConvexShape *shape, float stepHeight)
btGhostObject *ghost, btConvexShape *shape, float stepHeight)
:btKinematicCharacterController(ghost, shape, stepHeight, btVector3(0.0f, 0.0f, 1.0f)),
m_ctrl(ctrl),
m_motionState(motionState),
Expand Down Expand Up @@ -510,15 +510,15 @@ bool CcdPhysicsController::CreateCharacterController()
return false;
}

m_object = new btPairCachingGhostObject();
m_object = new btGhostObject();
m_object->setCollisionShape(m_collisionShape);
m_object->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT);

btTransform trans;
m_bulletMotionState->getWorldTransform(trans);
m_object->setWorldTransform(trans);

m_characterController = new CcdCharacter(this, m_bulletMotionState, (btPairCachingGhostObject *)m_object,
m_characterController = new CcdCharacter(this, m_bulletMotionState, (btGhostObject *)m_object,
(btConvexShape *)m_collisionShape, m_cci.m_stepHeight);

m_characterController->setJumpSpeed(m_cci.m_jumpSpeed);
Expand Down
4 changes: 2 additions & 2 deletions source/gameengine/Physics/Bullet/CcdPhysicsController.h
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ struct CcdConstructionInfo {
class btRigidBody;
class btCollisionObject;
class btSoftBody;
class btPairCachingGhostObject;
class btGhostObject;

class CcdCharacter : public btKinematicCharacterController, public PHY_ICharacter
{
Expand All @@ -449,7 +449,7 @@ class CcdCharacter : public btKinematicCharacterController, public PHY_ICharacte
unsigned char m_maxJumps;

public:
CcdCharacter(CcdPhysicsController *ctrl, btMotionState *motionState, btPairCachingGhostObject *ghost, btConvexShape *shape, float stepHeight);
CcdCharacter(CcdPhysicsController *ctrl, btMotionState *motionState, btGhostObject *ghost, btConvexShape *shape, float stepHeight);

virtual void updateAction(btCollisionWorld *collisionWorld, btScalar dt);

Expand Down

0 comments on commit 8d97bab

Please sign in to comment.