btCapsuleShape location isn't accurate at all

I’m having troubles with bullet’s rigidbody. I’m using the 3.1 beta1 but this problems were there since before (I’ve tried it on 3.0 with and without jbullet and the problem comes without it).

Well, the problem is that the location of a rigidbody on jbullet is the very point touching the floor while in native bullet there is a little offset so it physics location is never y:0.

Is this being watched to be fixed, or may I workaround it usage? (I would try to fix it myself but the bullet thing is above my current possibilities :S)

Which type of collision shape are you using? Could you provide a test case?

Yes, of course:

package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.control.BetterCharacterControl;
import com.jme3.bullet.objects.PhysicsRigidBody;
import com.jme3.bullet.util.CollisionShapeFactory;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.AbstractControl;
import com.jme3.scene.shape.Box;
import com.jme3.terrain.geomipmap.TerrainQuad;

/**
 * Created by inaki on 27/04/16.
 */
public class TestBetterCharacterCenter extends SimpleApplication {


    private class BC extends BetterCharacterControl {

        public BC(float radius, float height, float mass) {
            super(radius, height, mass);
        }

        protected Vector3f getLoc() {
            return rigidBody.getPhysicsLocation();
        }

        @Override
        protected void updateLocalCoordinateSystem() {

        }
    }

    public static void main(String[] args) {
        new TestBetterCharacterCenter().start();
    }

    @Override
    public void simpleInitApp() {

        flyCam.setMoveSpeed(40);

        Spatial floor = new TerrainQuad("", 256, 257, new float[] {1});
        floor.setLocalTranslation(0, -2, 0);


        BulletAppState bullet = new BulletAppState();
        stateManager.attach(bullet);
        bullet.setDebugEnabled(true);




        final BC character = new BC(0.5f, 1.8f, 60);
        character.setWalkDirection(new Vector3f(0.3f, 0, 0));
        bullet.getPhysicsSpace().add(character);
        bullet.getPhysicsSpace().add(new PhysicsRigidBody(CollisionShapeFactory.createMeshShape(floor), 0));

        rootNode.addControl(new AbstractControl() {
            @Override
            protected void controlUpdate(float tpf) {
                Box b = new Box(0.02f, 0.02f, 0.02f);
                final Geometry geom = new Geometry("Box", b);
                Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
                mat.setColor("Color", ColorRGBA.Green);
                geom.setMaterial(mat);

                geom.setLocalTranslation(character.getLoc());
                System.out.println(character.getLoc());

                rootNode.attachChild(geom);
            }

            @Override
            protected void controlRender(RenderManager rm, ViewPort vp) {

            }
        });
    }

}

I don’t know if this is a bug or the algorithm that works this way, but it’s related to bullet’s btCapsuleShape used internally by the BetterCharacterControl, so it has little to do with jme.

If you need more accuracy, even though i honestly can’t think of a real life situation where you need this, you could use a cylinder shape instead.

Maybe you could explain what you are really trying to achieve.

I think this is a bug. It is not a few invisible thing. It is moving by an offset of 0.07 jme units what is 7 cm on my game. It is just unaffordable to have that offset for visual things. An offset, like I said, that wasn’t present on jbullet version.

https://javadoc.jmonkeyengine.org/com/jme3/bullet/collision/shapes/CollisionShape.html#setMargin(float)

It’s not a margin issue…

Here the capsule and cylinder both have same radius, height and margins.

I just tried to apply that on the code below (to the collision shape used by the character control) and it is not offsetting nothing, just making it behavior strange dependenig on the margin (ie: -1.7f). I tried with positive and negative values but the physics location is always the same and any spatial attached is viewed with the same offset.

Just changed the constructor by:

        public BC(float radius, float height, float mass) {
            super(radius, height, mass);
            
            rigidBody.getCollisionShape().setMargin(-0.7f);
        }

well if you want to adjust it by hand, you can rewrite BetterCharacterControl.getShape() and apply the offset to the y component of addLocation

Yes, I know that solution but I feel that making that I’m leaving there something wrong xD. For example, I’ll have to have that 0.08f in mind every time when trying to get the distance between that object (if using the physics location as reference) and any navigation point. It’s not hard too hard to do but as I said, I think it shouldn’t be like that :S.

Well, I’m not an expert regarding jbullet and native bullet, but it seems strange that there is a difference.

For “strange behavior”: I had to tweak all kinds of parameters of the BulletAppState, the BetterCharacterControl and of my materials until all the strange behavior went away.
Here is what I saw:

  • A monkey with BetterCharacterControl falling from 20 units to the ground - bounced off and went 200 meters into the air (which is physically impossible because, you know, potential energy can not increase).
  • A teapot that was hovering in the air, because restitution or other parameter was wrong - as soon as my walker pushed that teapot, it fell to the ground correctly.
  • A teapot which was oscillating on the ground, slowly slided downwards a sand hill and only got stopped when hitting the surface of the ocean plane.
  • A large quad as earth surface caused the monkey to rebound the ground and fly 1000 meters into the air, sometimes not even returning - had to replace the quad by a mesh of smaller quads to fight this issue.
  • A box which was only 1kg in mass but due to wrong friction, restitution and other stuff could not be tossed around - it always got stuck, sometimes even laying in unnatural orientation (only one corner touched the ground).

So much fun (not). Look at games like Skyrim (the trolls can toss the main character - the “dragon born” flies like a tennis ball, so it must be “ball born” or something like that). Other games have wonderful and annoying anomalies too… There are few (but there are some) games that get physics right (feel right, not exactly right) and also have very good performance.

1 Like

Well, I wasn’t talking about that kind of perfection or missconfiguration. If you try the code I supplied on jbullet you’ll see a standard good result. However, if you execute the exact same code with native bullet it gets an 0.07XXXXX offset, what is too much to afford and too far to start to be “precision optimizations”.

Without making a workaround (ie: the addLocation mentioned by Riccardo), any spatial attached to that looks like it was levitating (it’s almost eight centimeters, what is really appreciable).

And what about this
https://www.youtube.com/watch?v=DoCrgoqiyZ0
https://www.youtube.com/watch?v=AqDOefJc7a4
:chipmunk:

Hahah… those are great.

That’s at least one problem my games won’t have. :slight_smile: (physics and rendering is completely decoupled.)

1 Like

As i said the issue is related to btCapsuleShape (that btw i was referring to with btCollisionShape by mistake in one of my previous replies).

When you build this shape in bullet the height you specify is relative to the cylinder and not the full shape.
To overcome this the BetterCharacterControl removes 2*radius from the height. But in this way it treats the capsule as if it were a cylinder with two spheres at the extremities, that doesn’t seem to be 100% accurate with bullet native.
If you build the capsule by hand with a cylinder and two spheres, the results are accurate.

This is my BetterCharacterControl.getShape i’ve just modified to test this theory:

    protected CollisionShape getShape() {
        float radius= getFinalRadius();
        float height=getFinalHeight();
        float cylinder_height= height- (2.0f * radius) ;
        CylinderCollisionShape cylinder = new CylinderCollisionShape(new Vector3f(radius, cylinder_height/2f,radius)/*NB constructor want half extents*/,1);
        SphereCollisionShape sphere=new SphereCollisionShape(getFinalRadius());        
        CompoundCollisionShape compoundCollisionShape = new CompoundCollisionShape();
        compoundCollisionShape.addChildShape(sphere,new Vector3f(0,
                /*sphere half height*/radius
        ,0)); // bottom sphere
        compoundCollisionShape.addChildShape(cylinder, new Vector3f(0,
                /*half sphere height*/(radius)+
                /*cylinder half height*/(cylinder_height/2.f)
        , 0)); // cylinder, on top of the bottom sphere
        compoundCollisionShape.addChildShape(sphere,new Vector3f(0,
                /*half sphere height*/(radius)+
                /*cylinder height*/(cylinder_height)
        ,0)); // top sphere       
        return compoundCollisionShape;
    }

Note: I’m not sure if it will behave in the same way the capsule shape does.

2 Likes

I tried it and it works just like expected and so, I must say, your theory is just fine. The capsule shape is bugged, but then is a bullet bug on the btCollisionShape?. Shouldn’t it then be reported to the bullet people?.

1 Like

I’m not sure that the version used by jme is the latest release of bullet, though. And i don’t know if there is any particular reason for this behaviour, so i can’t tell if it’s a bug and needs to be reported or not. :thinking:

Maybe we could replace the capsule shape with this handmade compound shape in the charactercontrol, if it works fine. But for many people 7 cm of difference are not so much…

Hm… maybe someone that knows better the engine could say. However, bug or not, it can be reported as a “strange behavior xD”

I don’t know if this isn’t much less efficient than having the bullet version as in the bullet version it seems to make a fusion and be 1 collision shape vs a compound of 3 shapes. For 1 character it could be the same but what about hundred of them?

Well, I can ensure you that this is the difference between walk or levitate :wink:

@NemesisMate Its been a year since you posted this, has the code continued to work as expected?

Pretty nice solution, beats offsetting.

Yes, it work fine for the last 3.1 stable version.