Bullet physics – something wrong with collision

I have encounter two problems with using the Bullet physics collision thing:



First, when the player walk on the ground, the whole screen begin to shake on some place. It seems that you be moved upwards by something, then fall down, moved upwards again and so on…



Second, if you jump against the boxes standing on eachother you can jump very high - walljump.



Here is the code:

Code:
package bloxjava;

import com.jme3.app.SimpleBulletApplication;
import com.jme3.bullet.collision.shapes.BoxCollisionShape;
import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
import com.jme3.bullet.nodes.PhysicsCharacterNode;
import com.jme3.bullet.nodes.PhysicsNode;
import com.jme3.font.BitmapText;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Matrix3f;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Box;

public class HelloCollision extends SimpleBulletApplication
{
PhysicsCharacterNode hero;

private Vector3f walkDirection = new Vector3f();
private boolean left = false, right = false, up = false, down = false;

BitmapText zomg;

Node pickup;

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

@Override
public void simpleInitApp()
{
    //Camera
    viewPort.setBackgroundColor(new ColorRGBA(0.6f, 0.3f, 0.3f, 1f));
    flyCam.setMoveSpeed(50);
    cam.setAxes(new Quaternion(0, 0.5f, 0, 0.9f));

    //Sun
    DirectionalLight sun = new DirectionalLight();
    sun.setColor(ColorRGBA.White.clone().multLocal(2));
    sun.setDirection(new Vector3f(2.8f, -2.8f, -2.8f).normalize());
    rootNode.addLight(sun);

    createFloor();
    //Create the bottom standing box
    createBox("Wall", new Vector3f(8, 0, 8), new Vector3f(1, 5, 1), ColorRGBA.Blue);
    //Create the top standing box
    createBox("Wall", new Vector3f(8, 5, 8), new Vector3f(1, 5, 1), ColorRGBA.Green);

    //Hero
    hero = new PhysicsCharacterNode(new CapsuleCollisionShape(1.5f, 6f, 1), 0.5f);
    hero.setJumpSpeed(14);
    hero.setFallSpeed(30);
    hero.setGravity(30);
    hero.setLocalTranslation(new Vector3f(0, 10, 0));
    hero.updateGeometricState();

    rootNode.attachChild(hero);
    rootNode.updateGeometricState();
    getPhysicsSpace().add(hero);

    initKeys();
}

private void initKeys()
{
    inputManager.addMapping("Up",     new KeyTrigger(KeyInput.KEY_W));
    inputManager.addMapping("Left",   new KeyTrigger(KeyInput.KEY_A));
    inputManager.addMapping("Down",   new KeyTrigger(KeyInput.KEY_S));
    inputManager.addMapping("Right",  new KeyTrigger(KeyInput.KEY_D));
    inputManager.addMapping("Jump", new KeyTrigger(KeyInput.KEY_SPACE));

    inputManager.addListener(actionListener, new String[]{"Up", "Left", "Down", "Right", "Jump"});
}

private ActionListener actionListener = new ActionListener()
{
    @Override
    public void onAction(String binding, boolean value, float tpf)
    {
       if (binding.equals("Left"))
       {
          if (value) { left = true; } else { left = false; }
       }
       else if (binding.equals("Right"))
       {
          if (value) { right = true; } else { right = false; }
       }
       else if (binding.equals("Up"))
       {
          if (value) { up = true; }    else { up = false; }
       }
       else if (binding.equals("Down"))
       {
          if (value) { down = true; }  else { down = false; }
       }
       else if (binding.equals("Jump"))
       {
          hero.jump();
       }
    }
};

//Make the player to move
@Override
public void simpleUpdate(float tpf)
{
    Vector3f camDir = cam.getDirection().clone().multLocal(0.6f);
    Vector3f camLeft = cam.getLeft().clone().multLocal(0.4f);
    walkDirection.set(0, 0, 0);

    if (left)  { walkDirection.addLocal(camLeft); }
    if (right) { walkDirection.addLocal(camLeft.negate()); }
    if (up)    { walkDirection.addLocal(camDir); }
    if (down)  { walkDirection.addLocal(camDir.negate()); }

    hero.setWalkDirection(walkDirection);
    cam.setLocation(hero.getLocalTranslation());
}

void createFloor()
{
    createBox("the Floor", new Vector3f(0, -0.1f, 0), new Vector3f(15, 0.2f, 15), ColorRGBA.Gray);
}

//Make a box with a default size
void createBox(String name, Vector3f pos, ColorRGBA color)
{
    createBox(name, pos, new Vector3f(1, 1, 1), color);
}

//Make a box with a custom size
void createBox(String name, Vector3f pos, Vector3f size, ColorRGBA color)
{
    Box b = new Box(Vector3f.ZERO, size);
    Geometry geom = new Geometry(name, b);
    Material mat = new Material(assetManager, "Common/MatDefs/Misc/SolidColor.j3md");
    mat.setColor("m_Color", color);
    geom.setMaterial(mat);

    //Used for collision
    PhysicsNode pn = new PhysicsNode(geom, new BoxCollisionShape(size), 0);
    pn.setLocalTranslation(pos);
    pn.updateGeometricState();
    rootNode.attachChild(pn);
    getPhysicsSpace().add(pn);
}

}


How can I fix the problems?

Improve the bullet source code :stuck_out_tongue:

The character node is a very basic attempt at a character in bullet, it is not using “real” physics but does a faster simulation. The shaking issues can be solved by using more dense meshes and the jumping issue has to resolution atm. You could use PhysicsSpace.rayTest() to check if the player is still on the ground.

Cheers,

Normen

Thank you, I don’t exactly know what you mean with using more dense meshes. I guess I better use something more simple collision detection instead of using Bullet physics.