I keep falling through the floor?

I am trying to add physics to the TerrainFractalGridTest, and I seem to have succeeded - my player falls to the floor. The trouble is, she keeps falling until she is right through the floor, and eventually stop when the camera is at grass level. And then I can’t move around, I seem stuck.

I am trying to merge the hello collision tutorial with the TerrainFractalGridTest, but I seem to have done something wrong.

[JAVA]
//Agnes add - physics
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);

CollisionShape sceneShape =
CollisionShapeFactory.createMeshShape((Node) terrain);
landscape = new RigidBodyControl(sceneShape, 0);
terrain.addControl(landscape);

    CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(1.5f, 6f, 1);
    player = new CharacterControl(capsuleShape, 0.3f);
    player.setJumpSpeed(20);
    player.setFallSpeed(30);
    player.setGravity(30);
    player.setPhysicsLocation(new Vector3f(0, 200, 0));


    //this.getCamera().setLocation(new Vector3f(0, 300, 0));
    bulletAppState.getPhysicsSpace().add(landscape);
    bulletAppState.getPhysicsSpace().add(player);

[/JAVA]

Here is my whole init method…

[JAVA]
@Override
public void simpleInitApp() {
bulletAppState = new BulletAppState();
bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL);
stateManager.attach(bulletAppState);
this.flyCam.setMoveSpeed(100f);

    grassTexture();
    dirtTexture();
    rockTexture();
    setBase();
    FilteredBasis ground = getFilteredBasis();

    ground.addPreFilter(this.iterate);

    this.terrain = new TerrainGrid("terrain", 33, 129, new FractalTileLoader(ground, 256f));

    this.terrain.setMaterial(this.mat_terrain);
    this.terrain.setLocalTranslation(0, 0, 0);
    this.terrain.setLocalScale(5f, 1f, 5f);
    this.rootNode.attachChild(this.terrain);

    TerrainLodControl control = new TerrainGridLodControl(this.terrain, this.getCamera());
    control.setLodCalculator(new DistanceLodCalculator(33, 2.7f)); // patch size, and a multiplier
    this.terrain.addControl(control);

    CollisionShape sceneShape =
            CollisionShapeFactory.createMeshShape((Node) terrain);
    landscape = new RigidBodyControl(sceneShape, 0);
    terrain.addControl(landscape);

    CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(1.5f, 6f, 1);
    player = new CharacterControl(capsuleShape, 0.3f);
    player.setJumpSpeed(20);
    player.setFallSpeed(30);
    player.setGravity(30);
    player.setPhysicsLocation(new Vector3f(0, 200, 0));

    //this.getCamera().setLocation(new Vector3f(0, 300, 0));
    bulletAppState.getPhysicsSpace().add(landscape);
    bulletAppState.getPhysicsSpace().add(player);

    this.viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f));
}

[/JAVA]

OK, so it would help if I remembered to map the input keys. So now I can move and jump, although I am underground. Definite progress!

I successfully added physics to the HelloTerrain sample, so I think the problem lies in how I am adding the physics controls to the terrain grid. I seem to be adding physics to the bottom of the terrain grid, not the top, if that makes any sense.

Adding this didn’t help:

[JAVA]
terrain.addListener(new TerrainGridListener() {
@Override
public void gridMoved(Vector3f newCenter) {
//To change body of implemented methods use File | Settings | File Templates.
}

        @Override
        public void tileAttached(Vector3f cell, TerrainQuad quad) {
            quad.addControl(new RigidBodyControl(0));
            bulletAppState.getPhysicsSpace().addAll(quad);
        }

        @Override
        public void tileDetached(Vector3f cell, TerrainQuad quad) {
            bulletAppState.getPhysicsSpace().removeAll(quad);
        }
    });

[/JAVA]

I’m sorry, this is turning into a bit of a personal diary, but i thought I should post back with my partial solution. This code seems to have it working:

[JAVA]
terrain.addListener(new TerrainGridListener() {
@Override
public void gridMoved(Vector3f newCenter) {
//To change body of implemented methods use File | Settings | File Templates.
}

        @Override
        public void tileAttached(Vector3f cell, TerrainQuad quad) {
            System.out.println("########################Adding Quad###############################");
            CollisionShape quadShape = CollisionShapeFactory.createMeshShape(terrain);
            RigidBodyControl rbc = new RigidBodyControl(quadShape,  0);
            quad.addControl(rbc);
            bulletAppState.getPhysicsSpace().addAll(quad);
        }

        @Override
        public void tileDetached(Vector3f cell, TerrainQuad quad) {
            quad.removeControl(RigidBodyControl.class);
            bulletAppState.getPhysicsSpace().removeAll(quad);
        }
    });

[/JAVA]

My only problems now are sometimes slipping through the terrain, and getting stuck in hollows. This seems to be because the physics shape seems to get out of synch with the geometry.

Hi ags1, as you’ve pretty much solved your own problem (which is always good) this is a little late, but you’re more likely to get help if you post a complete bare minimum example; something people can copy, paste and run. For example I wanted to check your actual x,y,z co-ordinate movement (sometimes you think you’re in one place but really you’re in annother, reading off your true position can solve more problems than you imagine) or if you’ve connected your camera with an offset. Without a full working example I can’t know any of that or experience the problems you’re having.

Just for my two cents (and I’m probably wrong, I’m far from an expert) bullet physics can get upset if you do things outside the physics tick, As I understand it bullet runs at its own internal frame rate seperate from JMEs and so if you place a call to it at the wrong phase in its own cycle it can ignore it . Anyway read this and see if it applys to you: https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:physics_listeners

Thanks for the advice. I will post complete code next time. I gave up on the physics for now - I worry that it might not be fast enough when i have a hundred creatures running around, and I think bullet must have a lot of calculating to do each time the terrain tiles get loaded… I got nice performance using picking - just dropping a line from the sky and finding the floor. It might be the best thing to do or it might not be, but I have got my game running at least.

1 Like

Are you using the nightly build of JME? Try not to scale the terrain, and see if you have the same issue. I noticed a some regressions when scaling spatials and using them for collision shapes (Although I never checked if there was an issue with terrain, as they use a special collision shape, so it might be fine)

Another advice… USE the JAVA tags.

+90% of people will simply disregard posts containing code that isn’t tagged. Untagged code is a mess to follow and most of us that have that much time or the inclination if the problem isn’t a personal issue, isn’t something we’ve committed, closely worked on, or is a notably difficult class to work with.

In short, if it’s run-of-the-mill we’ll just skip right along as we did here.

Since your problem doesn’t fit the special cases and it’s a basic problem (which gets posted often) that’s why you didn’t get much replies I’m sorry to announce.

Anyway, I don’t want to sound like a sourpuss. But that’s how it is. :slight_smile:

Good point madjack… I added Java tags but it looks like forum software has created a train-crash with HTML tags. Maybe adding the Java tags on post creation will work better - I will remember next time.

Wezrule - I am scaling the terrain. When I have a bit more time I will try again without scaling.

This is partly to test if I understand the JAVA tags as suggested by madjack, and also to put a bit more info in the thread if it is ever googled by some unfortunate person.

Rather than using picking to get the height, this is probably more efficient:

    private float getHeight(Camera camera) {
        Vector3f location = camera.getLocation();
        for (TerrainQuad q : terrainQuads) {
            float f = q.getHeight(new Vector2f(location.getX(), location.getZ()));
            if (!Float.isNaN(f)) return f;
        }
        if (!terrainQuads.isEmpty()) throw new RuntimeException("At least one of the quads should have given a height...?");
        return 0f;
    }

All I need to figure out is how to get the current quad I’m on, there must be a way, something like terrainGrid.getCurrentQuad(Vector2f xz)

And to get nicely formatted code use HTML pre.