Collisions problem with a model

Hi. It’s me again !

I’m now trying to add the collision to my terrain.
I’ve started from the tutorial Hello-Collision, and have changed the first-person camera to an object showing a robot. Everything is working, except that the robot is floating in the air like a bird, whatever the dimensions of the capsule shape can be…

I’ve tried changing a lot of things, and didn’t managed to get it work. For example I’ve tried with a box shape instead of a capsule, but the rendered was really bad. I’ve tried with a blue unshaded box : this worked already better, but instead of moving right on the floor it always went up, then a step in the right direction, then down. Sorry if I’m not clear, feel free to ask me to rephrase.

Please find my code below.

Many thanks by advance.

[java]
public class HelloCollision extends SimpleApplication
implements ActionListener {

private Spatial sceneModel;
private BulletAppState bulletAppState;
private RigidBodyControl landscape;
private CharacterControl player;
private Vector3f walkDirection = new Vector3f();
private boolean left = false, right = false, up = false, down = false;

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

public void simpleInitApp() {
/** Set up Physics */
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
//bulletAppState.getPhysicsSpace().enableDebug(assetManager);

// We re-use the flyby camera for rotation, while positioning is handled by physics
viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f));
flyCam.setMoveSpeed(100);
setUpKeys();
setUpLight();

assetManager.registerLoader(BlenderModelLoader.class, "blend");
Spatial robot = assetManager.loadModel("Models/robotV3.blend");
rootNode.attachChild(robot);


// We load the scene from the zip file and adjust its size.
assetManager.registerLocator("town.zip", ZipLocator.class);
sceneModel = assetManager.loadModel("main.scene");
sceneModel.setLocalScale(2f);

// We set up collision detection for the scene by creating a
// compound collision shape and a static RigidBodyControl with mass zero.
CollisionShape sceneShape =
        CollisionShapeFactory.createMeshShape((Node) sceneModel);
landscape = new RigidBodyControl(sceneShape, 0);
sceneModel.addControl(landscape);

//BoxCollisionShape capsuleShape = new BoxCollisionShape(new Vector3f(2,2,2));
BoundingBox box = ((BoundingBox)robot.getWorldBound());
float xHalfExtent     = box.getXExtent();
float yHalfExtent    = box.getYExtent();
float zHalfExtent     = box.getZExtent();
float radius = Math.max(xHalfExtent, zHalfExtent);
float height = yHalfExtent;
System.out.println( "Height : " + height );
CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape( radius, height, 1);
player = new CharacterControl(capsuleShape, 0.05f);
player.setJumpSpeed(20);
player.setFallSpeed(30);
player.setGravity(30);
robot.setLocalTranslation(0, 20, 0);
//player.setPhysicsLocation(new Vector3f(0, -100, 0));
robot.addControl(player);

// We attach the scene and the player to the rootNode and the physics space,
// to make them appear in the game world.
rootNode.attachChild(sceneModel);
bulletAppState.getPhysicsSpace().add(landscape);
bulletAppState.getPhysicsSpace().add(player);

}

private void setUpLight() {
// We add light so we see the scene
AmbientLight al = new AmbientLight();
al.setColor(ColorRGBA.White.mult(1.3f));
rootNode.addLight(al);

DirectionalLight dl = new DirectionalLight();
dl.setColor(ColorRGBA.White);
dl.setDirection(new Vector3f(2.8f, -2.8f, -2.8f).normalizeLocal());
rootNode.addLight(dl);

}

/** We over-write some navigational key mappings here, so we can

  • add physics-controlled walking and jumping: */
    private void setUpKeys() {
    inputManager.addMapping(“Left”, new KeyTrigger(KeyInput.KEY_J));
    inputManager.addMapping(“Right”, new KeyTrigger(KeyInput.KEY_L));
    inputManager.addMapping(“Up”, new KeyTrigger(KeyInput.KEY_I));
    inputManager.addMapping(“Down”, new KeyTrigger(KeyInput.KEY_K));
    inputManager.addMapping(“Jump”, new KeyTrigger(KeyInput.KEY_SPACE));
    inputManager.addListener(this, “Left”);
    inputManager.addListener(this, “Right”);
    inputManager.addListener(this, “Up”);
    inputManager.addListener(this, “Down”);
    inputManager.addListener(this, “Jump”);
    }

/** These are our custom actions triggered by key presses.

  • We do not walk yet, we just keep track of the direction the user pressed. */
    public void onAction(String binding, boolean value, float tpf) {
    if (binding.equals(“Left”)) {
    left = value;
    } else if (binding.equals(“Right”)) {
    right = value;
    } else if (binding.equals(“Up”)) {
    up = value;
    } else if (binding.equals(“Down”)) {
    down = value;
    } else if (binding.equals(“Jump”)) {
    player.jump();
    }
    }

/**

  • This is the main event loop–walking happens here.
  • We check in which direction the player is walking by interpreting
  • the camera direction forward (camDir) and to the side (camLeft).
  • The setWalkDirection() command is what lets a physics-controlled player walk.
  • We also make sure here that the camera moves with player.
    */
    @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()); }
    player.setWalkDirection(walkDirection);
    //cam.setLocation(player.getPhysicsLocation());
    }
    }
    [/java]
@Quentin54 said: Everything is working, except that the robot is floating in the air like a bird, whatever the dimensions of the capsule shape can be...

The CollisionShapes “extend” out from the origin of the model mesh. You can either move the origin of the model in blender to the center, or you can create a new Node, attach the robot to it, translate the robot, and then attach the CharacterControl to the Node instead.