Player not colliding with terrain

Hi!
I’ve a problem with my first game.
I’ve created a simple map and I imported in the game using a png heightmap, then I’ve transformed it in a spatial. The problem is: the player doesn’t collide with the map but if I enable BulletAppState debug mode the collision works. Why?
There is the code:

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

//Temporary vectors used on each frame.
//They here to avoid instanciating new vectors on each frame
private Vector3f camDir = new Vector3f();
private Vector3f camLeft = new Vector3f();

public Main(){
    init();
}

private void init(){
}

public static void main(String[] args) {
    Main app = new Main();
    app.start();
}
private TerrainQuad terrain;

@Override
public void simpleInitApp() {
    flyCam.setMoveSpeed(5000);
    
    bulletAppState = new BulletAppState();
    stateManager.attach(bulletAppState);
    bulletAppState.setDebugEnabled(true);
    
    viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f));
    flyCam.setMoveSpeed(100);
    setUpKeys();
    setUpLight();

    AbstractHeightMap heightmap = null;
    Texture heightMapImage = assetManager.loadTexture("Textures/image.png");
    heightmap = new ImageBasedHeightMap(heightMapImage.getImage());
    heightmap.load();
    
    Material mat_terrain = new Material(assetManager, "Common/MatDefs/Terrain/Terrain.j3md");
    
    mat_terrain.setTexture("Alpha", assetManager.loadTexture("Textures/textile.png"));
    
    int patchSize = 65;
    terrain = new TerrainQuad("my terrain", patchSize, 1025, heightmap.getHeightMap());
    
    CollisionShape csh = CollisionShapeFactory.createMeshShape(terrain);
    landscape = new RigidBodyControl(csh, 0);
    terrain.addControl(landscape);
    
    TerrainLodControl control = new TerrainLodControl(terrain, getCamera());
    terrain.addControl(control);
    
    CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(1.5f, 6f, 1);
    player = new CharacterControl(capsuleShape, 0.05f);
    player.setJumpSpeed(20);
    player.setFallSpeed(30);
    player.setGravity(new Vector3f(0,-30f,0));
    player.setPhysicsLocation(new Vector3f(0, 550, 250));
    
    terrain.setMaterial(mat_terrain);
    terrain.setLocalTranslation(0, -100, 0);
    terrain.setLocalScale(10f, 5f, 10f);
    rootNode.attachChild(terrain);
    
    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_A));
    inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_D));
    inputManager.addMapping("Up", new KeyTrigger(KeyInput.KEY_W));
    inputManager.addMapping("Down", new KeyTrigger(KeyInput.KEY_S));
    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");
}

@Override
public void simpleUpdate(float tpf){
    camDir.set(cam.getDirection()).multLocal(0.6f);
    camLeft.set(cam.getLeft()).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());
}

@Override
public void simpleRender(RenderManager rm) {
}

@Override
public void onAction(String name, boolean isPressed, float tpf) {
    switch (name) {
        case "Left":
            left = isPressed;
            break;
        case "Right":
            right= isPressed;
            break;
        case "Up":
            up = isPressed;
            break;
        case "Down":
            down = isPressed;
            break;
        case "Jump":
            if (isPressed) {
                player.jump(new Vector3f(0,10,0));
            }
            break;
        default:
            break;
    }
}

Thanks for the reply.

Do you see the same behavior with both JME 3.1 and 3.2 ?

Is it possible the gravity is way too much and make the tic be skip and the collision listener doesn’t get the time to calculate the collision and cause the collision to go through the ground?

Normally the gravity is set to (0,-9,0)

One fix, try to increase the tic rate of the physic to around 60. If it doesn’t work maybe it s something else.
Edit: try removing the gravity line and test for me.

Edit2: maybe you spawn at the terrain Level too, if that happen you will glitch through it. So increasing your Character Height vs the Height at your position could be a fix too.