jMonkeyEngine / jmonkeyengine

A complete 3-D game development suite written in Java.
http://jmonkeyengine.org
BSD 3-Clause "New" or "Revised" License
3.74k stars 1.12k forks source link

HeightfieldCollisionShape is invisible in jme3-jbullet with setDebugEnabled() #1129

Open stephengold opened 5 years ago

stephengold commented 5 years ago

Physics debug visualization works for HeightfieldCollisionShape in jme3-bullet but not in jme3-jbullet.

To demonstrate this issue, modify jme3test.terrain.TerrainGridAlphaMapTest as follows:

@@ -47,7 +47,7 @@
     private float grassScale = 64;
     private float dirtScale = 16;
     private float rockScale = 128;
-    private boolean usePhysics = false;
+    private boolean usePhysics = true;

     public static void main(final String[] args) {
         TerrainGridAlphaMapTest app = new TerrainGridAlphaMapTest();
@@ -161,6 +161,7 @@
         this.terrain.addControl(control);

         final BulletAppState bulletAppState = new BulletAppState();
+        bulletAppState.setDebugEnabled(true);
         stateManager.attach(bulletAppState);

With jme3-bullet, the HeightfieldCollisionShape is visualized as blue wireframe, overlaid on the grass/dirt/rock. With jme3-jbullet, only the grass/dirt/rock is visible.

mr-universe-guy commented 5 years ago

The problem appears to be with HeightfieldTerrainShape.processAllTriangles() in com.bulletphysics.dom I tried adding my own triangle callback to the debug shape factory to count the triangles, and I can confirm that my callback is added but processTriangle() is never called. in jme3-jbullet com.jme3.bullet.util.DebugShapeFactory

public static Mesh getDebugMesh(CollisionShape shape) {
        Mesh mesh = null;
        if (shape.getCShape() instanceof ConvexShape) {
            mesh = new Mesh();
            mesh.setBuffer(Type.Position, 3, getVertices((ConvexShape) shape.getCShape()));
            mesh.getFloatBuffer(Type.Position).clear();
        } else if (shape.getCShape() instanceof ConcaveShape) {
            mesh = new Mesh();
            mesh.setBuffer(Type.Position, 3, getVertices((ConcaveShape) shape.getCShape()));
            mesh.getFloatBuffer(Type.Position).clear();
        }
        if(shape instanceof HeightfieldCollisionShape){
            HeightfieldTerrainShape hts = (HeightfieldTerrainShape)shape.getCShape();
            System.out.println("Heightfield "+shape+" is being processed");
            hts.processAllTriangles(new TriangleCallback(){
                int count = 0;
                @Override
                public void processTriangle(Vector3f[] vctrfs, int i, int i1) {
                    System.out.println(count++);
                }
            }, aabbMin, aabbMax);
        }
        return mesh;
    }

This prints the following when run with @stephengold 's changes (truncated for clarification)

...
Jun 23, 2019 10:58:51 AM com.jme3.terrain.noise.filter.PerturbFilter filter
INFO: Found origSize : 147 and offset: 17 for workSize : 181 and magnitude : 0.119
Heightfield com.jme3.bullet.collision.shapes.HeightfieldCollisionShape@5f6a6954 is being processed
Heightfield com.jme3.bullet.collision.shapes.HeightfieldCollisionShape@7ae4f5d2 is being processed
Jun 23, 2019 10:58:51 AM com.jme3.terrain.noise.filter.PerturbFilter filter
INFO: Found origSize : 147 and offset: 17 for workSize : 181 and magnitude : 0.119
Jun 23, 2019 10:58:51 AM com.jme3.terrain.noise.filter.PerturbFilter filter
INFO: Found origSize : 147 and offset: 17 for workSize : 181 and magnitude : 0.119
Heightfield com.jme3.bullet.collision.shapes.HeightfieldCollisionShape@ff3be6c is being processed
Jun 23, 2019 10:58:51 AM com.jme3.terrain.noise.filter.PerturbFilter filter
INFO: Found origSize : 147 and offset: 17 for workSize : 181 and magnitude : 0.119
Heightfield com.jme3.bullet.collision.shapes.HeightfieldCollisionShape@68389924 is being processed
Jun 23, 2019 10:58:51 AM com.jme3.terrain.noise.filter.PerturbFilter filter
INFO: Found origSize : 147 and offset: 17 for workSize : 181 and magnitude : 0.119
...