9

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: enter image description here

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?

user30088
  • 497
  • 1
  • 6
  • 14
  • Do your collision blocks overlap on x-axis ? – axelduch Sep 01 '14 at 12:43
  • 1
    does bullet have edge (chain) shapes like box2d? – CodeSmile Sep 01 '14 at 12:55
  • aduch: block 1 right edge = block 2 left edge. So, not really :/ @LearnCocos2D: Nop, but I've tried to replace the Capsule shape with a Box shape and everything is better, it's strange Oo – user30088 Sep 01 '14 at 13:53
  • related: https://stackoverflow.com/questions/26805651/find-a-way-of-fixing-wrong-collision-normals-in-edge-collisions/26995933?noredirect=1#comment83612124_26995933 –  Jan 18 '18 at 06:32

2 Answers2

17

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.

Nico Heidtke
  • 525
  • 4
  • 7
  • 2
    Hey, I know it's been a while, but what exactly is a spring? I mean, is that a class from Bullet or a physics concept? Google wasn't much help – Luke B. Oct 02 '14 at 16:03
  • 1
    An out-of-the-box spring implementation did not exist in Bullet 2.7x when I did this. So I read up on springs physics on Google and did it myself. I needed more control about the details anyway do things like dampening the spring etc. – Nico Heidtke Oct 03 '14 at 14:38
  • This seems like a really convoluted and roundabout way to solve the problem. While it may be a great solution if the effects you listed where the intent, if your intent was to simply fix the issue asked, then it's a poor fit. – Slight Nov 14 '14 at 14:56
  • The problem is that there just wasn't any other solution at the time (there might be in Bullet 3 - which I haven't used yet). I've seen many people ask that question years ago. But there was no way to fix that problem 100%. And since he was specifically asking about a character controller, I just gave him something that elegantly solves a whole bunch of other issues that are typically encountered as development progresses. – Nico Heidtke Nov 17 '14 at 16:58
  • 1
    @NicoHeidtke Why did you use multiple rays? What did it help you accomplish? And how did you use them? (I've got it working with a single ray, and its working quite well, just there are some minor errors) – akaltar Feb 22 '15 at 18:30
  • @akaltar Could you share a bit more about your implementation? I am currently trying this solution with a btGeneric6DofSpringConstraint but I am running into some trouble. Maybe it could be added to this post? – Eejin Feb 23 '15 at 12:37
  • 1
    @Eejin I did a custom spring like the author too. It's too long for a post, so here it is: http://pastebin.com/bjJSNx08 – akaltar Feb 23 '15 at 18:08
  • @akaltar I had to use multiple springs because we had some problems with holes in the floor. Some of our geometry was generated. To prevent the single ray hitting a hole and then have the character sinking into it, I had 3 rays I think. That made all the interaction with the floor little bit more complicated. – Nico Heidtke Feb 24 '15 at 11:54
  • @NicoHeidtke A final question: were the rays parallel to each other and the Z axis? – akaltar Feb 24 '15 at 15:38
  • @akaltar yes. fortunately, there was no need to make it even more complicated ;-) – Nico Heidtke Feb 24 '15 at 16:47
  • 1
    @akaltar I have been trying to implement your solution but it keeps on bobbing up and down. Did I miss something? http://pastebin.com/7HKSxCpe – Eejin Feb 25 '15 at 21:46
  • @Eejin No, Its bobbing for me too, Thats a problem left to solve. (I guess you should play with damping, stiffness and the height...) – akaltar Feb 26 '15 at 06:58
  • @Eejin after almost a decade, was there any solution for the bobbing up and down besides tuning the damping and stiffness? Disabling the spring in the air and reenabling on the ground brings this bobbing in. – Avi Jun 18 '23 at 23:28
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.

MechMK1
  • 3,278
  • 7
  • 37
  • 55