Avoid ground collision with Bullet
Asked Answered
E

2

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?

Equiponderance answered 1/9, 2014 at 12:15 Comment(4)
Do your collision blocks overlap on x-axis ?Gregarine
does bullet have edge (chain) shapes like box2d?Ipsambul
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 OoEquiponderance
related: #26806151Tagliatelle
F
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.

Forebear answered 8/9, 2014 at 13:33 Comment(15)
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 helpMelanism
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.Forebear
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.Allover
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.Forebear
@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)Amazonas
@Amazonas 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?Lacilacie
@Lacilacie I did a custom spring like the author too. It's too long for a post, so here it is: pastebin.com/bjJSNx08Amazonas
@Amazonas 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.Forebear
@NicoHeidtke A final question: were the rays parallel to each other and the Z axis?Amazonas
@Amazonas yes. fortunately, there was no need to make it even more complicated ;-)Forebear
@Amazonas I have been trying to implement your solution but it keeps on bobbing up and down. Did I miss something? pastebin.com/7HKSxCpeLacilacie
@Lacilacie No, Its bobbing for me too, Thats a problem left to solve. (I guess you should play with damping, stiffness and the height...)Amazonas
@Lacilacie 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.Virology
@Virology No, unfortunately I never managed to figure it outLacilacie
@Lacilacie thanks! my workaround was to introduce ray cast, so the body is 5cm floating above the ground, works like a charmVirology
M
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.

Myrtie answered 26/11, 2017 at 18:5 Comment(3)
How to extend this solution to a more generic case (besides btBvhTriangleMeshShape)?Exurb
No, you can't. It only work with btBvhTriangleMeshShape.Porterhouse
This should be the true solution. It works for me. Some intersting link github.com/godotengine/godot/issues/…Englis

© 2022 - 2024 — McMap. All rights reserved.