Avoid ground collision with Bullet

2019-01-22 05:07发布

问题:

I'm trying to use Bullet physic engine to create a 3D world.

I've got my character with a Capsule shape on his body and my ground his made of some static blocs stick together, here is a schema to illustrate my words:

The problem is present when my character run from one block to another: Bullet detect a collision and my character start to jump a little bit on y-axis.

How can I avoid the problem?

回答1:

What I did to overcome this issue is the following:

Instead of have the capsule slide on the ground, I had a dynamic capsule ride on top of a spring. I implemented the spring as several ray casts originating from bottom of the capsule. The length of the spring was like half a meter or less and it would pull and push the capsule to and from the ground. The grip/pull is important so the character wouldn't jump unexpectedly. The springs stiffness controls how much bobbing you have.

This had the following effects

  • No unwanted collision with edge of geometry on the floor, since the capsule floats
  • Walking up stairs and slopes implemented implicitly. The spring would just "step" onto the stair's step and push the character capsule up.
  • Implementation of jumping was just matter of releasing the grip on the ground the spring had and giving the body an impulse.
  • A landing character after a jump or fall automatically displayed "knee-bending" as you would expect
  • Pleasant smoothing of vertical movements in general. Like on elevator platforms etc.
  • Due to the grip/pull to the ground, even when running downhill the character would not start to "fly" as you experience in some games (I find that annoying typically).
  • Ducking character = decrease the length of the spring and/or the capsule.
  • Sliding downhill? You can fully control it by checking the angles of the floor area the ray cast of the spring hit.

I had to play around a lot with the stiffness of the spring, the length of the spring, the length of the grip etc. but in the end I was very happy about how simple yet well this worked.



回答2:

Your problem caller "Internal Edge Collision". I just found the solution few our hour ago. If you are using btHeightfieldTerrainShapefor your world then you must use btBvhTriangleMeshShape to slove this problem.

Here is the answer.

Add this callback:

static bool CustomMaterialCombinerCallback(btManifoldPoint& cp,const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1)
{
   btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1);
   return true;
}

extern ContactAddedCallback gContactAddedCallback;

Afterwards create the btBvhTriangleMeshShape and add this code where pGround is your btBvhTriangleMeshShape:

// Enable custom material callback
pGround->setCollisionFlags(pGround->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);

btTriangleInfoMap* triangleInfoMap = new btTriangleInfoMap();
btGenerateInternalEdgeInfo(pGroundShape, triangleInfoMap);

Or you can open the InternalEdgeDemo example in Bullet to see how to implement it in detail.