diff --git a/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainGrid.java b/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainGrid.java index bc8567c62..7c647e991 100644 --- a/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainGrid.java +++ b/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainGrid.java @@ -32,7 +32,6 @@ package com.jme3.terrain.geomipmap; import com.jme3.scene.control.UpdateControl; -import com.jme3.app.Application; import com.jme3.bullet.PhysicsSpace; import com.jme3.bullet.collision.shapes.HeightfieldCollisionShape; import com.jme3.bullet.control.RigidBodyControl; @@ -40,7 +39,6 @@ import com.jme3.terrain.heightmap.HeightMap; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.ExecutionException; import java.util.logging.Level; import java.util.logging.Logger; @@ -48,7 +46,6 @@ import com.jme3.material.Material; import com.jme3.math.FastMath; import com.jme3.math.Vector2f; import com.jme3.math.Vector3f; -import com.jme3.renderer.Camera; import com.jme3.terrain.geomipmap.lodcalc.LodCalculatorFactory; import com.jme3.terrain.geomipmap.lodcalc.LodDistanceCalculatorFactory; import com.jme3.terrain.heightmap.HeightMapGrid; @@ -153,11 +150,6 @@ public class TerrainGrid extends TerrainQuad { if (lodCalculatorFactory == null) { lodCalculatorFactory = new LodDistanceCalculatorFactory(); } -// this.quadOrigins = new Vector3f[]{ -// new Vector3f(-this.quarterSize, 0, -this.quarterSize).mult(this.stepScale), -// new Vector3f(-this.quarterSize, 0, this.quarterSize).mult(this.stepScale), -// new Vector3f(this.quarterSize, 0, -this.quarterSize).mult(this.stepScale), -// new Vector3f(this.quarterSize, 0, this.quarterSize).mult(this.stepScale)}; this.quadIndex = new Vector3f[]{ new Vector3f(-1, 0, 2), new Vector3f(0, 0, 2), new Vector3f(1, 0, 2), new Vector3f(2, 0, 2), new Vector3f(-1, 0, 1), new Vector3f(0, 0, 1), new Vector3f(1, 0, 1), new Vector3f(2, 0, 1), @@ -192,7 +184,6 @@ public class TerrainGrid extends TerrainQuad { for (TerrainGridListener l : this.listeners.values()) { l.gridMoved(camCell); } - updatePhysics(); } @Override @@ -208,14 +199,13 @@ public class TerrainGrid extends TerrainQuad { for (TerrainGridListener l : this.listeners.values()) { l.gridMoved(camCell); } - updatePhysics(); } super.update(locations); } public Vector3f getCell(Vector3f location) { - final Vector3f v = location.clone().divideLocal(this.getLocalScale().mult(this.quadSize-1)).add(0.5f, 0, 0.5f); + final Vector3f v = location.clone().divideLocal(this.getLocalScale().mult(this.quadSize - 1)).add(0.5f, 0, 0.5f); return new Vector3f(FastMath.floor(v.x), 0, FastMath.floor(v.z)); } @@ -224,8 +214,12 @@ public class TerrainGrid extends TerrainQuad { if (quadControls != null) { this.getQuad(idx).removeControl(RigidBodyControl.class); } + for (TerrainGridListener l : listeners.values()) { + l.tileDetached(getCell(this.getQuad(idx).getWorldTranslation()), this.getQuad(idx)); + } this.detachChild(this.getQuad(idx)); } + } /** @@ -241,50 +235,14 @@ public class TerrainGrid extends TerrainQuad { 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); - quadControls[quadrant - 1].setCollisionShape(new HeightfieldCollisionShape(q.getHeightMap(), getLocalScale())); - q.addControl(quadControls[quadrant - 1]); - space.addAll(q); - quadControls[quadrant - 1].setEnabled(true); - //quadControls[quadrant - 1].setPhysicsLocation(cam.add(this.quadOrigins[quadrant - 1])); - } else { + for (TerrainGridListener l : listeners.values()) { + l.tileAttached(cam, q); } updateModelBound(); } - public void updatePhysics() { - RigidBodyControl control = getControl(RigidBodyControl.class); - if (control != null) { - this.space = control.getPhysicsSpace(); - space.remove(this); - this.removeControl(control); - this.quadControls = new RigidBodyControl[4]; - - for (int i = 0; i < 4; i++) { - int collisionGroupsCollideWith = control.getCollideWithGroups(); - int collisionGroups = control.getCollisionGroup(); - 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]); - 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])); - // --------------------------------------------------- // LRU cache is used, so elements that need to remain // should be touched. @@ -326,37 +284,7 @@ public class TerrainGrid extends TerrainQuad { 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; - } - } - - executor.execute(new UpdateQuadCache(cam)); - - - this.removeQuad(1); - this.removeQuad(2); - this.removeQuad(3); - this.removeQuad(4); - - attachQuadAt(q1, 1, cam); // quadIndex[9] - 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) { diff --git a/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainGridListener.java b/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainGridListener.java index 64544c97a..593e5052a 100644 --- a/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainGridListener.java +++ b/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainGridListener.java @@ -44,4 +44,7 @@ public interface TerrainGridListener { public Material tileLoaded(Material material, Vector3f cell); + public void tileAttached( Vector3f cell, TerrainQuad quad ); + + public void tileDetached( Vector3f cell, TerrainQuad quad ); } diff --git a/engine/src/test/jme3test/terrain/TerrainFractalGridTest.java b/engine/src/test/jme3test/terrain/TerrainFractalGridTest.java index 0a862d8a9..5dd2e6373 100644 --- a/engine/src/test/jme3test/terrain/TerrainFractalGridTest.java +++ b/engine/src/test/jme3test/terrain/TerrainFractalGridTest.java @@ -1,5 +1,6 @@ package jme3test.terrain; +import com.jme3.terrain.geomipmap.TerrainQuad; import java.util.ArrayList; import java.util.List; @@ -77,13 +78,13 @@ public class TerrainFractalGridTest extends SimpleApplication { Texture grass = this.assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); grass.setWrap(WrapMode.Repeat); this.mat_terrain.setTexture("region1ColorMap", grass); - this.mat_terrain.setVector3("region1", new Vector3f(88, 200, this.grassScale)); + this.mat_terrain.setVector3("region1", new Vector3f(15, 200, this.grassScale)); // DIRT texture Texture dirt = this.assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); dirt.setWrap(WrapMode.Repeat); this.mat_terrain.setTexture("region2ColorMap", dirt); - this.mat_terrain.setVector3("region2", new Vector3f(0, 90, this.dirtScale)); + this.mat_terrain.setVector3("region2", new Vector3f(0, 20, this.dirtScale)); // ROCK texture Texture rock = this.assetManager.loadTexture("Textures/Terrain/Rock2/rock.jpg"); @@ -156,28 +157,35 @@ public class TerrainFractalGridTest extends SimpleApplication { this.viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f)); if (usePhysics) { + 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); + 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; } + + public void tileAttached(Vector3f cell, TerrainQuad quad) { + quad.addControl(new RigidBodyControl(new HeightfieldCollisionShape(quad.getHeightMap(), terrain.getLocalScale()), 0)); + bulletAppState.getPhysicsSpace().add(quad); + } + + public void tileDetached(Vector3f cell, TerrainQuad quad) { + bulletAppState.getPhysicsSpace().remove(quad); + quad.removeControl(RigidBodyControl.class); + } + }); } this.terrain.initialize(cam.getLocation()); @@ -254,7 +262,7 @@ public class TerrainFractalGridTest extends SimpleApplication { this.walkDirection.addLocal(camDir.negate()); } - if (usePhysics && physicsAdded) { + if (usePhysics) { this.player3.setWalkDirection(this.walkDirection); this.cam.setLocation(this.player3.getPhysicsLocation()); } diff --git a/engine/src/test/jme3test/terrain/TerrainGridAlphaMapTest.java b/engine/src/test/jme3test/terrain/TerrainGridAlphaMapTest.java index 437114ca9..b6473cda5 100644 --- a/engine/src/test/jme3test/terrain/TerrainGridAlphaMapTest.java +++ b/engine/src/test/jme3test/terrain/TerrainGridAlphaMapTest.java @@ -22,6 +22,7 @@ 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.geomipmap.TerrainQuad; import com.jme3.terrain.heightmap.ImageBasedHeightMapGrid; import com.jme3.terrain.heightmap.Namer; import com.jme3.texture.Texture; @@ -65,7 +66,7 @@ public class TerrainGridAlphaMapTest extends SimpleApplication { }else{ assetManager.registerLocator("mountains.zip", ZipLocator.class); } - + this.flyCam.setMoveSpeed(100f); ScreenshotAppState state = new ScreenshotAppState(); this.stateManager.attach(state); @@ -140,22 +141,8 @@ public class TerrainGridAlphaMapTest extends SimpleApplication { })); this.terrain.setMaterial(this.matRock); - this.terrain.addListener("alphaListener", new TerrainGridListener() { - - public void gridMoved(Vector3f newCenter) { - } - - public Material tileLoaded(Material material, Vector3f cell) { - int x = (int)Math.abs(512 * (cell.x % 2)); - int z = (int)Math.abs(512 * (cell.z % 2)); - material.setTexture("Alpha", assetManager.loadTexture("Scenes/TerrainAlphaTest/alphamap_" + x + "_" + z + ".png")); - return material; - } - }); - this.terrain.setLocalTranslation(0, 0, 0); this.terrain.setLocalScale(2f, 1f, 2f); - this.terrain.initialize(Vector3f.ZERO); this.rootNode.attachChild(this.terrain); List cameras = new ArrayList(); @@ -163,7 +150,7 @@ public class TerrainGridAlphaMapTest 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); @@ -172,19 +159,38 @@ public class TerrainGridAlphaMapTest 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); + 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); - this.player3.setPhysicsLocation(new Vector3f(0, 256, 0)); + terrain.addListener("physicsStartListener", new TerrainGridListener() { + + public void gridMoved(Vector3f newCenter) { + } + + public Material tileLoaded(Material material, Vector3f cell) { + return material; + } + + public void tileAttached(Vector3f cell, TerrainQuad quad) { + quad.addControl(new RigidBodyControl(new HeightfieldCollisionShape(quad.getHeightMap(), terrain.getLocalScale()), 0)); + bulletAppState.getPhysicsSpace().add(quad); + } + + public void tileDetached(Vector3f cell, TerrainQuad quad) { + bulletAppState.getPhysicsSpace().remove(quad); + quad.removeControl(RigidBodyControl.class); + } - bulletAppState.getPhysicsSpace().add(this.player3); + }); } + this.terrain.initialize(cam.getLocation()); this.initKeys(); } diff --git a/engine/src/test/jme3test/terrain/TerrainGridTest.java b/engine/src/test/jme3test/terrain/TerrainGridTest.java index 7c660a8e8..2fb47d977 100644 --- a/engine/src/test/jme3test/terrain/TerrainGridTest.java +++ b/engine/src/test/jme3test/terrain/TerrainGridTest.java @@ -18,6 +18,7 @@ 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.geomipmap.TerrainQuad; import com.jme3.terrain.heightmap.ImageBasedHeightMapGrid; import com.jme3.terrain.heightmap.Namer; import com.jme3.texture.Texture; @@ -115,28 +116,35 @@ public class TerrainGridTest extends SimpleApplication { this.viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f)); if (usePhysics) { + 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); + 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; } + + public void tileAttached(Vector3f cell, TerrainQuad quad) { + quad.addControl(new RigidBodyControl(new HeightfieldCollisionShape(quad.getHeightMap(), terrain.getLocalScale()), 0)); + bulletAppState.getPhysicsSpace().add(quad); + } + + public void tileDetached(Vector3f cell, TerrainQuad quad) { + bulletAppState.getPhysicsSpace().remove(quad); + quad.removeControl(RigidBodyControl.class); + } + }); } this.terrain.initialize(cam.getLocation()); @@ -213,7 +221,7 @@ public class TerrainGridTest extends SimpleApplication { this.walkDirection.addLocal(camDir.negate()); } - if (usePhysics && physicsAdded) { + if (usePhysics) { this.player3.setWalkDirection(this.walkDirection); this.cam.setLocation(this.player3.getPhysicsLocation()); }