OSDN Git Service

Fix: the new way to add physics to terrainGrid is to use the listener interface,...
authoranthyon@gmail.com <anthyon@gmail.com@75d07b2b-3a1a-0410-a2c5-0572b91ccdca>
Thu, 7 Jul 2011 15:02:08 +0000 (15:02 +0000)
committeranthyon@gmail.com <anthyon@gmail.com@75d07b2b-3a1a-0410-a2c5-0572b91ccdca>
Thu, 7 Jul 2011 15:02:08 +0000 (15:02 +0000)
new heightmaps are provided for TerrainGridTest

git-svn-id: http://jmonkeyengine.googlecode.com/svn/trunk@7836 75d07b2b-3a1a-0410-a2c5-0572b91ccdca

engine/mountains.zip
engine/src/terrain/com/jme3/terrain/geomipmap/TerrainGrid.java
engine/src/test/jme3test/terrain/TerrainFractalGridTest.java
engine/src/test/jme3test/terrain/TerrainGridTest.java

index 76184e0..59b7ce0 100644 (file)
Binary files a/engine/mountains.zip and b/engine/mountains.zip differ
index 0a195dd..bc8567c 100644 (file)
@@ -81,7 +81,7 @@ public class TerrainGrid extends TerrainQuad {
         }
 
         public void run() {
-            
+
             for (int i = 0; i < 4; i++) {
                 for (int j = 0; j < 4; j++) {
                     int quadIdx = i * 4 + j;
@@ -99,13 +99,14 @@ public class TerrainGrid extends TerrainQuad {
                         log.log(Level.FINE, "Loaded TerrainQuad {0}", q.getName());
                     }
                     cache.put(temp, q);
-                    
+
                     if (isCenter(quadIdx)) {
                         // if it should be attached as a child right now, attach it
                         final int quadrant = getQuadrant(quadIdx);
                         final TerrainQuad newQuad = q;
                         // back on the OpenGL thread:
                         getControl(UpdateControl.class).enqueue(new Callable() {
+
                             public Object call() throws Exception {
                                 attachQuadAt(newQuad, quadrant, temp);
                                 return null;
@@ -117,20 +118,21 @@ public class TerrainGrid extends TerrainQuad {
 
         }
     }
-    
+
     private boolean isCenter(int quadIndex) {
         return quadIndex == 9 || quadIndex == 5 || quadIndex == 10 || quadIndex == 6;
     }
-    
+
     private int getQuadrant(int quadIndex) {
-        if (quadIndex == 9)
+        if (quadIndex == 9) {
             return 1;
-        else if (quadIndex == 5)
+        } else if (quadIndex == 5) {
             return 2;
-        else if (quadIndex == 10)
+        } else if (quadIndex == 10) {
             return 3;
-        else if (quadIndex == 6)
+        } else if (quadIndex == 6) {
             return 4;
+        }
         return 0; // error
     }
 
@@ -161,7 +163,7 @@ public class TerrainGrid extends TerrainQuad {
             new Vector3f(-1, 0, 1), new Vector3f(0, 0, 1), new Vector3f(1, 0, 1), new Vector3f(2, 0, 1),
             new Vector3f(-1, 0, 0), new Vector3f(0, 0, 0), new Vector3f(1, 0, 0), new Vector3f(2, 0, 0),
             new Vector3f(-1, 0, -1), new Vector3f(0, 0, -1), new Vector3f(1, 0, -1), new Vector3f(-2, 0, -1)};
-        
+
         addControl(new UpdateControl());
     }
 
@@ -190,6 +192,7 @@ public class TerrainGrid extends TerrainQuad {
         for (TerrainGridListener l : this.listeners.values()) {
             l.gridMoved(camCell);
         }
+        updatePhysics();
     }
 
     @Override
@@ -205,6 +208,7 @@ public class TerrainGrid extends TerrainQuad {
             for (TerrainGridListener l : this.listeners.values()) {
                 l.gridMoved(camCell);
             }
+            updatePhysics();
         }
 
         super.update(locations);
@@ -234,8 +238,8 @@ public class TerrainGrid extends TerrainQuad {
         q.setQuadrant((short) quadrant);
         this.attachChild(q);
 
-        Vector3f loc = cam.mult(this.quadSize-1).subtract(quarterSize, 0, quarterSize);// quadrant location handled TerrainQuad automatically now
-        q.setLocalTranslation(loc );
+        Vector3f loc = cam.mult(this.quadSize - 1).subtract(quarterSize, 0, quarterSize);// quadrant location handled TerrainQuad automatically now
+        q.setLocalTranslation(loc);
 
         if (quadControls != null) {
             quadControls[quadrant - 1].setEnabled(false);
@@ -246,11 +250,11 @@ public class TerrainGrid extends TerrainQuad {
             //quadControls[quadrant - 1].setPhysicsLocation(cam.add(this.quadOrigins[quadrant - 1]));
         } else {
         }
-        
+
         updateModelBound();
     }
 
-    private void updateChildrens(Vector3f cam) {
+    public void updatePhysics() {
         RigidBodyControl control = getControl(RigidBodyControl.class);
         if (control != null) {
             this.space = control.getPhysicsSpace();
@@ -261,22 +265,29 @@ public class TerrainGrid extends TerrainQuad {
             for (int i = 0; i < 4; i++) {
                 int collisionGroupsCollideWith = control.getCollideWithGroups();
                 int collisionGroups = control.getCollisionGroup();
-                quadControls[i] = new RigidBodyControl(new HeightfieldCollisionShape(new float[quadSize * quadSize], getLocalScale()), 0);
+                TerrainQuad q = getQuad(i + 1);
+                quadControls[i] = new RigidBodyControl(new HeightfieldCollisionShape(q == null ? new float[quadSize * quadSize] : q.getHeightMap(), getLocalScale()), 0);
                 quadControls[i].setCollideWithGroups(collisionGroupsCollideWith);
                 quadControls[i].setCollisionGroup(collisionGroups);
                 //quadControls[i].setPhysicsSpace(space);
                 //this.addControl(quadControls[i]);
-                //space.add(quadControls[i]);
+                if (q != null) {
+                    getQuad(i + 1).addControl(quadControls[i]);
+                    space.add(quadControls[i]);
+                }
             }
         }
+    }
 
+    private void updateChildrens(Vector3f cam) {
         //TerrainQuad q1 = cache.get(cam.add(quadIndex[9]));
         //TerrainQuad q2 = cache.get(cam.add(quadIndex[5]));
         //TerrainQuad q3 = cache.get(cam.add(quadIndex[10]));
         //TerrainQuad q4 = cache.get(cam.add(quadIndex[6]));
 
         // ---------------------------------------------------
-        // what does this block do?
+        // LRU cache is used, so elements that need to remain
+        // should be touched.
         // ---------------------------------------------------
         int dx = 0;
         int dy = 0;
@@ -308,26 +319,27 @@ public class TerrainGrid extends TerrainQuad {
         }
         // ---------------------------------------------------
         // ---------------------------------------------------
-        
-        if (executor == null)
+
+        if (executor == null) {
             executor = createExecutorService();
+        }
 
         executor.submit(new UpdateQuadCache(cam));
-        
-/*        if (q1 == null || q2 == null || q3 == null || q4 == null) {
-            try {
-                executor.submit(new UpdateQuadCache(cam, true)).get(); // BLOCKING
-                q1 = cache.get(cam.add(quadIndex[9]));
-                q2 = cache.get(cam.add(quadIndex[5]));
-                q3 = cache.get(cam.add(quadIndex[10]));
-                q4 = cache.get(cam.add(quadIndex[6]));
-            } catch (InterruptedException ex) {
-                Logger.getLogger(TerrainGrid.class.getName()).log(Level.SEVERE, null, ex);
-                return;
-            } catch (ExecutionException ex) {
-                Logger.getLogger(TerrainGrid.class.getName()).log(Level.SEVERE, null, ex);
-                return;
-            }
+
+        /*        if (q1 == null || q2 == null || q3 == null || q4 == null) {
+        try {
+        executor.submit(new UpdateQuadCache(cam, true)).get(); // BLOCKING
+        q1 = cache.get(cam.add(quadIndex[9]));
+        q2 = cache.get(cam.add(quadIndex[5]));
+        q3 = cache.get(cam.add(quadIndex[10]));
+        q4 = cache.get(cam.add(quadIndex[6]));
+        } catch (InterruptedException ex) {
+        Logger.getLogger(TerrainGrid.class.getName()).log(Level.SEVERE, null, ex);
+        return;
+        } catch (ExecutionException ex) {
+        Logger.getLogger(TerrainGrid.class.getName()).log(Level.SEVERE, null, ex);
+        return;
+        }
         }
 
         executor.execute(new UpdateQuadCache(cam));
@@ -342,11 +354,11 @@ public class TerrainGrid extends TerrainQuad {
         attachQuadAt(q2, 2, cam); // quadIndex[5]
         attachQuadAt(q3, 3, cam); // quadIndex[10]
         attachQuadAt(q4, 4, cam); // quadIndex[6]
-*/
+         */
         this.currentCell = cam;
 //        this.updateModelBound();
     }
-    
+
     public void addListener(String id, TerrainGridListener listener) {
         this.listeners.put(id, listener);
     }
@@ -368,15 +380,54 @@ public class TerrainGrid extends TerrainQuad {
     public void setQuadSize(int quadSize) {
         this.quadSize = quadSize;
     }
-    
+
     @Override
     public void adjustHeight(List<Vector2f> xz, List<Float> height) {
-        Vector3f currentGridLocation = getCurrentCell().mult( getLocalScale() ).multLocal( quadSize-1 );
-        for ( Vector2f vect : xz )
-        {
+        Vector3f currentGridLocation = getCurrentCell().mult(getLocalScale()).multLocal(quadSize - 1);
+        for (Vector2f vect : xz) {
             vect.x -= currentGridLocation.x;
             vect.y -= currentGridLocation.z;
         }
-        super.adjustHeight( xz, height );
+        super.adjustHeight(xz, height);
+    }
+
+    @Override
+    protected TerrainQuad findDownQuad() {
+        if (quadrant == 1) {
+            return cache.get(currentCell.add(quadIndex[13]));
+        } else if (quadrant == 3) {
+            return cache.get(currentCell.add(quadIndex[14]));
+        }
+        return null;
+    }
+
+    @Override
+    protected TerrainQuad findLeftQuad() {
+        if (quadrant == 1) {
+            return cache.get(currentCell.add(quadIndex[8]));
+        } else if (quadrant == 2) {
+            return cache.get(currentCell.add(quadIndex[4]));
+        }
+        return null;
+    }
+
+    @Override
+    protected TerrainQuad findRightQuad() {
+        if (quadrant == 3) {
+            return cache.get(currentCell.add(quadIndex[11]));
+        } else if (quadrant == 4) {
+            return cache.get(currentCell.add(quadIndex[7]));
+        }
+        return null;
+    }
+
+    @Override
+    protected TerrainQuad findTopQuad() {
+        if (quadrant == 2) {
+            return cache.get(currentCell.add(quadIndex[1]));
+        } else if (quadrant == 4) {
+            return cache.get(currentCell.add(quadIndex[2]));
+        }
+        return null;
     }
 }
index 84ed5ad..3529aa2 100644 (file)
@@ -15,9 +15,11 @@ import com.jme3.input.controls.ActionListener;
 import com.jme3.input.controls.KeyTrigger;
 import com.jme3.material.Material;
 import com.jme3.math.ColorRGBA;
+import com.jme3.math.Vector2f;
 import com.jme3.math.Vector3f;
 import com.jme3.renderer.Camera;
 import com.jme3.terrain.geomipmap.TerrainGrid;
+import com.jme3.terrain.geomipmap.TerrainGridListener;
 import com.jme3.terrain.geomipmap.TerrainLodControl;
 import com.jme3.terrain.heightmap.FractalHeightMapGrid;
 import com.jme3.texture.Texture;
@@ -39,6 +41,7 @@ public class TerrainFractalGridTest extends SimpleApplication {
     private float dirtScale = 16;
     private float rockScale = 128;
     private boolean usePhysics = true;
+    private boolean physicsAdded = false;
 
     public static void main(final String[] args) {
         TerrainFractalGridTest app = new TerrainFractalGridTest();
@@ -132,12 +135,11 @@ public class TerrainFractalGridTest extends SimpleApplication {
 
         ground.addPreFilter(this.iterate);
 
-        this.terrain = new TerrainGrid("terrain", 65, 257, new FractalHeightMapGrid(ground, null, 256f));
+        this.terrain = new TerrainGrid("terrain", 65, 257, new FractalHeightMapGrid(ground, "D:\\work5\\temp", 256f));
 
         this.terrain.setMaterial(this.mat_terrain);
         this.terrain.setLocalTranslation(0, 0, 0);
         this.terrain.setLocalScale(2f, 1f, 2f);
-        this.terrain.initialize(Vector3f.ZERO);
         this.rootNode.attachChild(this.terrain);
 
         List<Camera> cameras = new ArrayList<Camera>();
@@ -145,28 +147,40 @@ public class TerrainFractalGridTest extends SimpleApplication {
         TerrainLodControl control = new TerrainLodControl(this.terrain, cameras);
         this.terrain.addControl(control);
 
-        BulletAppState bulletAppState = new BulletAppState();
+        final BulletAppState bulletAppState = new BulletAppState();
         stateManager.attach(bulletAppState);
 
 
-        this.getCamera().setLocation(new Vector3f(0, 256, 0));
+        this.getCamera().setLocation(new Vector3f(0, 0, 0));
 
         this.viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f));
 
         if (usePhysics) {
-            RigidBodyControl body = new RigidBodyControl(new HeightfieldCollisionShape(terrain.getHeightMap(), terrain.getLocalScale()), 0);
-            terrain.addControl(body);
-            bulletAppState.getPhysicsSpace().add(terrain);
-            CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(0.5f, 1.8f, 1);
-            this.player3 = new CharacterControl(capsuleShape, 0.5f);
-            this.player3.setJumpSpeed(20);
-            this.player3.setFallSpeed(30);
-            this.player3.setGravity(30);
-
-            this.player3.setPhysicsLocation(new Vector3f(0, 256, 0));
-
-            bulletAppState.getPhysicsSpace().add(this.player3);
+            terrain.addListener("physicsStartListener", new TerrainGridListener() {
+
+                public void gridMoved(Vector3f newCenter) {
+                    terrain.removeListener("physicsStartListener");
+                    RigidBodyControl body = new RigidBodyControl(new HeightfieldCollisionShape(terrain.getHeightMap(), terrain.getLocalScale()), 0);
+                    terrain.addControl(body);
+                    bulletAppState.getPhysicsSpace().add(terrain);
+                    CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(0.5f, 1.8f, 1);
+                    player3 = new CharacterControl(capsuleShape, 0.5f);
+                    player3.setJumpSpeed(20);
+                    player3.setFallSpeed(10);
+                    player3.setGravity(10);
+
+                    player3.setPhysicsLocation(new Vector3f(cam.getLocation().x, 256, cam.getLocation().z));
+
+                    bulletAppState.getPhysicsSpace().add(player3);
+                    physicsAdded = true;
+                }
+
+                public Material tileLoaded(Material material, Vector3f cell) {
+                    return material;
+                }
+            });
         }
+        this.terrain.initialize(cam.getLocation());
         this.initKeys();
     }
 
@@ -183,7 +197,6 @@ public class TerrainFractalGridTest extends SimpleApplication {
         this.inputManager.addListener(this.actionListener, "Downs");
         this.inputManager.addListener(this.actionListener, "Jumps");
     }
-
     private boolean left;
     private boolean right;
     private boolean up;
@@ -225,23 +238,23 @@ public class TerrainFractalGridTest extends SimpleApplication {
 
     @Override
     public void simpleUpdate(final float tpf) {
-        Vector3f camDir = this.cam.getDirection().clone().multLocal(0.6f);
-        Vector3f camLeft = this.cam.getLeft().clone().multLocal(0.4f);
-        this.walkDirection.set(0, 0, 0);
-        if (this.left) {
-            this.walkDirection.addLocal(camLeft);
-        }
-        if (this.right) {
-            this.walkDirection.addLocal(camLeft.negate());
-        }
-        if (this.up) {
-            this.walkDirection.addLocal(camDir);
-        }
-        if (this.down) {
-            this.walkDirection.addLocal(camDir.negate());
-        }
+            Vector3f camDir = this.cam.getDirection().clone().multLocal(0.6f);
+            Vector3f camLeft = this.cam.getLeft().clone().multLocal(0.4f);
+            this.walkDirection.set(0, 0, 0);
+            if (this.left) {
+                this.walkDirection.addLocal(camLeft);
+            }
+            if (this.right) {
+                this.walkDirection.addLocal(camLeft.negate());
+            }
+            if (this.up) {
+                this.walkDirection.addLocal(camDir);
+            }
+            if (this.down) {
+                this.walkDirection.addLocal(camDir.negate());
+            }
 
-        if (usePhysics) {
+        if (usePhysics && physicsAdded) {
             this.player3.setWalkDirection(this.walkDirection);
             this.cam.setLocation(this.player3.getPhysicsLocation());
         }
index 60a4026..7c660a8 100644 (file)
@@ -1,6 +1,5 @@
 package jme3test.terrain;
 
-
 import com.jme3.app.SimpleApplication;
 import com.jme3.app.state.ScreenshotAppState;
 import com.jme3.asset.plugins.HttpZipLocator;
@@ -17,6 +16,7 @@ import com.jme3.material.Material;
 import com.jme3.math.ColorRGBA;
 import com.jme3.math.Vector3f;
 import com.jme3.terrain.geomipmap.TerrainGrid;
+import com.jme3.terrain.geomipmap.TerrainGridListener;
 import com.jme3.terrain.geomipmap.TerrainLodControl;
 import com.jme3.terrain.heightmap.ImageBasedHeightMapGrid;
 import com.jme3.terrain.heightmap.Namer;
@@ -32,6 +32,7 @@ public class TerrainGridTest extends SimpleApplication {
     private float dirtScale = 16;
     private float rockScale = 128;
     private boolean usePhysics = true;
+    private boolean physicsAdded = false;
 
     public static void main(final String[] args) {
         TerrainGridTest app = new TerrainGridTest();
@@ -44,7 +45,7 @@ public class TerrainGridTest extends SimpleApplication {
         File file = new File("mountains.zip");
         if (!file.exists()) {
             assetManager.registerLocator("http://jmonkeyengine.googlecode.com/files/mountains.zip", HttpZipLocator.class);
-        }else{
+        } else {
             assetManager.registerLocator("mountains.zip", ZipLocator.class);
         }
 
@@ -89,24 +90,24 @@ public class TerrainGridTest extends SimpleApplication {
         this.mat_terrain.setTexture("slopeColorMap", rock);
         this.mat_terrain.setFloat("slopeTileFactor", 32);
 
-        this.mat_terrain.setFloat("terrainSize", 513);
+        this.mat_terrain.setFloat("terrainSize", 129);
+
+        this.terrain = new TerrainGrid("terrain", 65, 257, new ImageBasedHeightMapGrid(assetManager, new Namer() {
 
-        this.terrain = new TerrainGrid("terrain", 65, 1025, new ImageBasedHeightMapGrid(assetManager, new Namer() {
             public String getName(int x, int y) {
-                return "Scenes/TerrainMountains/mountains_" + (x * 512) + "_" + (y * 512) + ".png";
+                return "Scenes/TerrainMountains/terrain_" + x + "_" + y + ".png";
             }
         }));
 
         this.terrain.setMaterial(this.mat_terrain);
         this.terrain.setLocalTranslation(0, 0, 0);
         this.terrain.setLocalScale(2f, 1f, 2f);
-        this.terrain.initialize(Vector3f.ZERO);
         this.rootNode.attachChild(this.terrain);
 
         TerrainLodControl control = new TerrainLodControl(this.terrain, getCamera());
         this.terrain.addControl(control);
 
-        BulletAppState bulletAppState = new BulletAppState();
+        final BulletAppState bulletAppState = new BulletAppState();
         stateManager.attach(bulletAppState);
 
         this.getCamera().setLocation(new Vector3f(0, 256, 0));
@@ -114,19 +115,31 @@ public class TerrainGridTest extends SimpleApplication {
         this.viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f));
 
         if (usePhysics) {
-            RigidBodyControl body = new RigidBodyControl(new HeightfieldCollisionShape(terrain.getHeightMap(), terrain.getLocalScale()), 0);
-            terrain.addControl(body);
-            bulletAppState.getPhysicsSpace().add(terrain);
-            CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(0.5f, 1.8f, 1);
-            this.player3 = new CharacterControl(capsuleShape, 0.5f);
-            this.player3.setJumpSpeed(20);
-            this.player3.setFallSpeed(30);
-            this.player3.setGravity(30);
-
-            this.player3.setPhysicsLocation(new Vector3f(0, 256, 0));
-
-            bulletAppState.getPhysicsSpace().add(this.player3);
+            terrain.addListener("physicsStartListener", new TerrainGridListener() {
+
+                public void gridMoved(Vector3f newCenter) {
+                    terrain.removeListener("physicsStartListener");
+                    RigidBodyControl body = new RigidBodyControl(new HeightfieldCollisionShape(terrain.getHeightMap(), terrain.getLocalScale()), 0);
+                    terrain.addControl(body);
+                    bulletAppState.getPhysicsSpace().add(terrain);
+                    CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(0.5f, 1.8f, 1);
+                    player3 = new CharacterControl(capsuleShape, 0.5f);
+                    player3.setJumpSpeed(20);
+                    player3.setFallSpeed(30);
+                    player3.setGravity(30);
+
+                    player3.setPhysicsLocation(new Vector3f(cam.getLocation().x, 256, cam.getLocation().z));
+
+                    bulletAppState.getPhysicsSpace().add(player3);
+                    physicsAdded = true;
+                }
+
+                public Material tileLoaded(Material material, Vector3f cell) {
+                    return material;
+                }
+            });
         }
+        this.terrain.initialize(cam.getLocation());
         this.initKeys();
     }
 
@@ -143,7 +156,6 @@ public class TerrainGridTest extends SimpleApplication {
         this.inputManager.addListener(this.actionListener, "Downs");
         this.inputManager.addListener(this.actionListener, "Jumps");
     }
-
     private boolean left;
     private boolean right;
     private boolean up;
@@ -201,7 +213,7 @@ public class TerrainGridTest extends SimpleApplication {
             this.walkDirection.addLocal(camDir.negate());
         }
 
-        if (usePhysics) {
+        if (usePhysics && physicsAdded) {
             this.player3.setWalkDirection(this.walkDirection);
             this.cam.setLocation(this.player3.getPhysicsLocation());
         }