Engine v3.4.0 beta testing

Test Issue Physics Terrain

hi everyone,
I was updating some projects to the new version of jmonkey 3.4.0. I have noticed that using the jme3-jbullet libraries, the debug physical form of the terrain is not displayed when physical debugging is enabled. Am I doing something wrong or is there some problem?

below a test case:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.test;

import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.collision.shapes.BoxCollisionShape;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.collision.shapes.HeightfieldCollisionShape;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.util.CollisionShapeFactory;
import com.jme3.light.AmbientLight;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import com.jme3.terrain.geomipmap.TerrainLodControl;
import com.jme3.terrain.geomipmap.TerrainQuad;
import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator;
import com.jme3.terrain.heightmap.AbstractHeightMap;
import com.jme3.terrain.heightmap.ImageBasedHeightMap;
import com.jme3.texture.Texture;

/**
 *
 * @author capdevon
 */
public class Test_IssuePhysicsTerrain extends SimpleApplication {
    
    private BulletAppState physics;
    private float grassScale = 64;
    private float dirtScale = 16;
    private float rockScale = 128;

    /**
     * 
     * @param args 
     */
    public static void main(String[] args) {
        Test_IssuePhysicsTerrain app = new Test_IssuePhysicsTerrain();
        app.start();
    }

    @Override
    public void simpleInitApp() {
        flyCam.setMoveSpeed(25f);
        viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f));
        
        initPhysics();
        initLights();
        initTerrain();

        cam.setLocation(new Vector3f(0, 10, -10));
        cam.lookAtDirection(new Vector3f(0, -1.5f, -1).normalizeLocal(), Vector3f.UNIT_Y);
     
        for (int i = 0; i < 25; i++) {
            float halfExtent = 1f;
            Box mesh = new Box(halfExtent, halfExtent, halfExtent);
            Geometry body = new Geometry("Cube.GeoMesh." + i, mesh);
            Material mat = new Material(getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
            mat.setColor("Color", ColorRGBA.Red);
            body.setMaterial(mat);
            body.setLocalTranslation(getRandomSpawnPoint(10, 0));
            rootNode.attachChild(body);
            
            BoxCollisionShape collShape = new BoxCollisionShape(new Vector3f(halfExtent, halfExtent, halfExtent));
            RigidBodyControl rb = new RigidBodyControl(collShape, 5f);
            body.addControl(rb);
            physics.getPhysicsSpace().add(rb);
        }
    }
    
    private Vector3f getRandomSpawnPoint(int radius, int height) {
        float x = FastMath.nextRandomInt(-radius, radius);
        float z = FastMath.nextRandomInt(-radius, radius);
        return new Vector3f(x, height, z);
    }
        
    /**
     * Initialize the physics simulation
     */
    private void initPhysics() {
        physics = new BulletAppState();
        physics.setDebugEnabled(true);
        stateManager.attach(physics);
    }

    private void initLights() {
        DirectionalLight light = new DirectionalLight();
        light.setDirection((new Vector3f(-0.5f, -1f, -0.5f)).normalize());
        rootNode.addLight(light);

        AmbientLight ambient = new AmbientLight();
        ambient.setColor(ColorRGBA.White.mult(1.3f));
        rootNode.addLight(ambient);
    }
    
    private void initTerrain() {
        // First, we load up our textures and the heightmap texture for the terrain

        // TERRAIN TEXTURE material
        Material matRock = new Material(assetManager, "Common/MatDefs/Terrain/Terrain.j3md");
        matRock.setBoolean("useTriPlanarMapping", false);

        // ALPHA map (for splat textures)
        matRock.setTexture("Alpha", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png"));

        // HEIGHTMAP image (for the terrain heightmap)
        Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png");

        // GRASS texture
        Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg");
        grass.setWrap(Texture.WrapMode.Repeat);
        matRock.setTexture("Tex1", grass);
        matRock.setFloat("Tex1Scale", grassScale);

        // DIRT texture
        Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg");
        dirt.setWrap(Texture.WrapMode.Repeat);
        matRock.setTexture("Tex2", dirt);
        matRock.setFloat("Tex2Scale", dirtScale);

        // ROCK texture
        Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg");
        rock.setWrap(Texture.WrapMode.Repeat);
        matRock.setTexture("Tex3", rock);
        matRock.setFloat("Tex3Scale", rockScale);

        // WIREFRAME material
        Material matWire = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        matWire.getAdditionalRenderState().setWireframe(true);
        matWire.setColor("Color", ColorRGBA.Green);

        // CREATE HEIGHTMAP
        AbstractHeightMap heightmap = null;
        try {
            //heightmap = new HillHeightMap(1025, 1000, 50, 100, (byte) 3);

            heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 1f);
            heightmap.load();

        } catch (Exception e) {
            e.printStackTrace();
        }

        /*
         * Here we create the actual terrain. The tiles will be 65x65, and the total size of the
         * terrain will be 513x513. It uses the heightmap we created to generate the height values.
         */
        /**
         * Optimal terrain patch size is 65 (64x64).
         * The total size is up to you. At 1025 it ran fine for me (200+FPS), however at
         * size=2049, it got really slow. But that is a jump from 2 million to 8 million triangles...
         */
        TerrainQuad terrain = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap());
        TerrainLodControl control = new TerrainLodControl(terrain, getCamera());
        control.setLodCalculator( new DistanceLodCalculator(65, 2.7f) ); // patch size, and a multiplier
        terrain.addControl(control);
        terrain.setMaterial(matRock);
        terrain.setLocalTranslation(0, -100, 0);
        terrain.setLocalScale(2f, 0.5f, 2f);
        rootNode.attachChild(terrain);
        
        /**
         * We set up collision detection for the scene by creating a compound
         * collision shape and a static RigidBodyControl with mass zero.
         */
        CollisionShape collShape = CollisionShapeFactory.createMeshShape(terrain);
        //CollisionShape collShape = new HeightfieldCollisionShape(terrain.getHeightMap(), terrain.getLocalScale());

        /**
         * A mesh-accurate shape optimized for static terrains. This shape is
         * much faster than other mesh-accurate shapes.
         */
//        CollisionShape collShape = new HeightfieldCollisionShape(heightMap.getHeightMap(), terrain.getLocalScale());
        RigidBodyControl rgb = new RigidBodyControl(collShape, 0);
        terrain.addControl(rgb);

        // We attach the scene and the player to the rootnode and the physics space,
        // to make them appear in the game world.
        physics.getPhysicsSpace().add(terrain);
    }

}

the libraries used in the classpath:

gson.jar
j-ogg-all.jar
jbullet.jar
jinput-natives-all.jar
jinput.jar
jme3-core.jar
jme3-desktop.jar
jme3-effects.jar
jme3-jbullet.jar
jme3-jogg.jar
jme3-lwjgl.jar
jme3-niftygui.jar
jme3-plugins.jar
jme3-terrain.jar
jme3-testdata.jar
jmf.jar
jsr305.jar
lwjgl-platform-natives-windows.jar
lwjgl.jar
nifty-default-controls.jar
nifty-examples.jar
nifty-style-black.jar
nifty.jar
stack-alloc.jar
vecmath.jar
xpp3.jar
2 Likes

Thanks for participating in beta testing!
I think you’ve re-discovered issue 1129

JMonkeyEngine v3.4.0-beta3 was released today!

It should fix the following bugs:

  • LWJGL context restart issues (PR #1526, issues #844 and #1445)
  • AnimEvent.onStop() kills prior event on the same layer (PR #1537)
  • failed assertion in TestAnimMigration (issue #1533, PR #1534)
  • crashes in TransformTrack.getTranslations() and getRotations() (PR #1532)
  • jme3-jbullet depends on unavailable Maven artifacts (PR #1541)

I haven’t made much progress in my beta testing. I plan to crank through jme3-examples a few times this weekend.

7 Likes

JMonkeyEngine v3.4.0-beta4 was released today!

It should fix the following bugs:

  • MorphControl doesn’t override JmeCloneable/Savable methods (issue #1548, PR #1549)
  • diagnostic messages from TestMusicPlayer (issue #1544, PR #1547)
  • crash in TestManyLocators (issue #1543, PR #1546)
  • crash in TestAppStates (issue #1542, PR #1545)
9 Likes

I’ve just broken ground on a Kotlin-based project initially using 3.3.2. I’ve updated to 3.4.0-beta4 and no issues so far.

I’m not using the SDK, I’m using IDEA community + gradle (Kotlin scripting), so any issues I do encounter will likely be on my end, but I’ll update here.

4 Likes

Thanks, @tsalaroth … and welcome to JMonkeyEngine!

I’ve completed the testing I promised on 13 April. I’ll turn my attention to the Wiki now.

4 Likes

thanks, myself i didnt seen issues so far, tho didnt had time to check all things.

1 Like

Hmm, our game roughly doubled the FPS when upgraded from 3.3.2 → 3.4 beta 4. Running without VSYNC. And the FPS is taken from the StatsAppState. Even looking at the detailed stats, I’m really unsure what could have caused this and is this real life or just fantasy. I’m using LWJGL 3.

I don’t entirely understand the math behind the detailed view. It is not just adding up CPU + GPU time.

With jME 3.3.2:

With jME 3.4 beta 4:

Edit: Investigating this a bit more. With LWJGL 3 I have gotten lower FPS for a long time (many jME revisions) compared to LWJGL 2. And this jME 3.4 just seems to boost the FPS to levels I’ve experienced with LWJGL 2. So this might be true life and I know that some frame render stuff was changed on jME 3.4 LWJGL 3 side… Good job and thanks if this is the case then!

6 Likes

Thanks for the report.

I didn’t expect JME v3.4 to be any more efficient than v3.3. My guess would be the FPS increase is a side-effect of fixing issue 1455. It’s strange, though, since I thought the fix would only have an impact when VSync was enabled, and you’re saying it was disabled in both tests.

Were you aware that VSync is enabled by default in v3.4?

2 Likes

I wonder if it could be related to the GLFW_REFRESH_RATE changes:

It doesn’t really explain why in those stats SSAO was a lot faster, etc…

Either way, it sounds to me like 3.3 had an lwjgl3 bug that is now fixed in 3.4.

2 Likes

Yes, setFrameRate on lwjgl3 leads to too slow frame rate · Issue #1455 · jMonkeyEngine/jmonkeyengine · GitHub. It is this one. I have VSYNC off and the frame rate limited to 200.

1 Like

That makes sense, then. Thanks.

I believe that’s because the GPU operates in parallel with the CPU.

1 Like

If anyone is still actively testing v3.4, let me know. I’d like to cut a “stable” release.

3 Likes

I have been doing some testing today. Just bumped from beta1 to beta4 on Outside. The lwjgl3 context restart fix is working great. I am not seeing any regressions yet.

I think a release would be great at this point.

2 Likes

The lwjgl3 context restart fix is working great.

So, can we close issue 1445?

3 Likes

Yep, closed.

3 Likes