diff --git a/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainLodControl.java b/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainLodControl.java index bfc62754d..79a8b373d 100644 --- a/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainLodControl.java +++ b/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainLodControl.java @@ -68,6 +68,7 @@ public class TerrainLodControl extends AbstractControl { private List cameras; private List cameraLocations = new ArrayList(); private LodCalculator lodCalculator; + private boolean hasResetLod = false; // used when enabled is set to false public TerrainLodControl() { } @@ -94,10 +95,26 @@ public class TerrainLodControl extends AbstractControl { protected void controlRender(RenderManager rm, ViewPort vp) { } + @Override + public void update(float tpf) { + controlUpdate(tpf); + } + @Override protected void controlUpdate(float tpf) { //list of cameras for when terrain supports multiple cameras (ie split screen) + if (lodCalculator == null) + return; + + if (!enabled) { + if (!hasResetLod) { + // this will get run once + hasResetLod = true; + lodCalculator.turnOffLod(); + } + } + if (cameras != null) { if (cameraLocations.isEmpty() && !cameras.isEmpty()) { for (Camera c : cameras) // populate them @@ -117,7 +134,9 @@ public class TerrainLodControl extends AbstractControl { cameraClone.add(c); } } - return new TerrainLodControl((Terrain) spatial, cameraClone); + TerrainLodControl cloned = new TerrainLodControl((Terrain) spatial, cameraClone); + cloned.setLodCalculator(lodCalculator.clone()); + return cloned; } return null; } @@ -156,6 +175,17 @@ public class TerrainLodControl extends AbstractControl { this.lodCalculator = lodCalculator; } + @Override + public void setEnabled(boolean enabled) { + this.enabled = enabled; + if (!enabled) { + // reset the lod levels to max detail for the terrain + hasResetLod = false; + } else { + hasResetLod = true; + lodCalculator.turnOnLod(); + } + } @Override public void write(JmeExporter ex) throws IOException { @@ -172,4 +202,5 @@ public class TerrainLodControl extends AbstractControl { terrain = (Terrain) ic.readSavable("terrain", null); lodCalculator = (LodCalculator) ic.readSavable("lodCalculator", new DistanceLodCalculator()); } + } diff --git a/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainQuad.java b/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainQuad.java index c14f41c2a..043f862ca 100644 --- a/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainQuad.java +++ b/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainQuad.java @@ -115,6 +115,7 @@ public class TerrainQuad extends Node implements Terrain { protected List lastCameraLocations; // used for LOD calc private boolean lodCalcRunning = false; + private int lodOffCount = 0; private int maxLod = -1; private HashMap updatedPatches; private final Object updatePatchesLock = new Object(); @@ -241,8 +242,17 @@ public class TerrainQuad extends Node implements Terrain { // update any existing ones that need updating updateQuadLODs(); + if (lodCalculator.isLodOff()) { + // we want to calculate the base lod at least once + if (lodOffCount == 1) + return; + else + lodOffCount++; + } else + lodOffCount = 0; + if (lastCameraLocations != null) { - if (lastCameraLocationsTheSame(locations)) + if (lastCameraLocationsTheSame(locations) && !lodCalculator.isLodOff()) return; // don't update if in same spot else lastCameraLocations = cloneVectorList(locations); @@ -425,6 +435,10 @@ public class TerrainQuad extends Node implements Terrain { updatedPatches.clear(); } } + + public boolean hasPatchesToUpdate() { + return updatedPatches != null && !updatedPatches.isEmpty(); + } protected boolean calculateLod(List location, HashMap updates, LodCalculator lodCalculator) { @@ -1680,9 +1694,11 @@ public class TerrainQuad extends Node implements Terrain { //quadClone.lodCalculatorFactory = lodCalculatorFactory.clone(); //quadClone.lodCalculator = lodCalculator.clone(); + TerrainLodControl lodControlCloned = this.getControl(TerrainLodControl.class); TerrainLodControl lodControl = quadClone.getControl(TerrainLodControl.class); - if (lodControl != null && !(getParent() instanceof TerrainQuad)) { - lodControl.setTerrain(quadClone); // set println in controller update to see if it is updating + + if (lodControlCloned != null && !(getParent() instanceof TerrainQuad)) { + //lodControlCloned.setLodCalculator(lodControl.getLodCalculator().clone()); } NormalRecalcControl normalControl = getControl(NormalRecalcControl.class); if (normalControl != null) diff --git a/engine/src/terrain/com/jme3/terrain/geomipmap/UpdatedTerrainPatch.java b/engine/src/terrain/com/jme3/terrain/geomipmap/UpdatedTerrainPatch.java index 1d2cc3bee..1f3b1fcad 100644 --- a/engine/src/terrain/com/jme3/terrain/geomipmap/UpdatedTerrainPatch.java +++ b/engine/src/terrain/com/jme3/terrain/geomipmap/UpdatedTerrainPatch.java @@ -90,9 +90,9 @@ public class UpdatedTerrainPatch { return newLod; } - protected void setNewLod(int newLod) { + public void setNewLod(int newLod) { this.newLod = newLod; - if (this.newLod <= 0) + if (this.newLod < 0) throw new IllegalArgumentException(); } diff --git a/engine/src/terrain/com/jme3/terrain/geomipmap/lodcalc/DistanceLodCalculator.java b/engine/src/terrain/com/jme3/terrain/geomipmap/lodcalc/DistanceLodCalculator.java index 6ffb5771a..3ab34c971 100644 --- a/engine/src/terrain/com/jme3/terrain/geomipmap/lodcalc/DistanceLodCalculator.java +++ b/engine/src/terrain/com/jme3/terrain/geomipmap/lodcalc/DistanceLodCalculator.java @@ -52,6 +52,7 @@ public class DistanceLodCalculator implements LodCalculator { private int size; // size of a terrain patch private float lodMultiplier = 2; + private boolean turnOffLod = false; public DistanceLodCalculator() { } @@ -64,6 +65,21 @@ public class DistanceLodCalculator implements LodCalculator { public boolean calculateLod(TerrainPatch terrainPatch, List locations, HashMap updates) { float distance = getCenterLocation(terrainPatch).distance(locations.get(0)); + + if (turnOffLod) { + // set to full detail + int prevLOD = terrainPatch.getLod(); + UpdatedTerrainPatch utp = updates.get(terrainPatch.getName()); + if (utp == null) { + utp = new UpdatedTerrainPatch(terrainPatch, 0); + updates.put(utp.getName(), utp); + } + utp.setNewLod(0); + utp.setPreviousLod(prevLOD); + utp.setReIndexNeeded(true); + return true; + } + // go through each lod level to find the one we are in for (int i = 0; i <= terrainPatch.getMaxLod(); i++) { if (distance < getLodDistanceThreshold() * (i + 1)*terrainPatch.getWorldScale().x || i == terrainPatch.getMaxLod()) { @@ -111,8 +127,7 @@ public class DistanceLodCalculator implements LodCalculator { @Override public LodCalculator clone() { - DistanceLodCalculator clone = new DistanceLodCalculator(); - + DistanceLodCalculator clone = new DistanceLodCalculator(size, lodMultiplier); return clone; } @@ -151,6 +166,17 @@ public class DistanceLodCalculator implements LodCalculator { public void setSize(int size) { this.size = size; } + + public void turnOffLod() { + turnOffLod = true; + } + + public boolean isLodOff() { + return turnOffLod; + } + public void turnOnLod() { + turnOffLod = false; + } } diff --git a/engine/src/terrain/com/jme3/terrain/geomipmap/lodcalc/LodCalculator.java b/engine/src/terrain/com/jme3/terrain/geomipmap/lodcalc/LodCalculator.java index 7372b0466..2d6c3647e 100644 --- a/engine/src/terrain/com/jme3/terrain/geomipmap/lodcalc/LodCalculator.java +++ b/engine/src/terrain/com/jme3/terrain/geomipmap/lodcalc/LodCalculator.java @@ -50,6 +50,10 @@ public interface LodCalculator extends Savable, Cloneable { public boolean calculateLod(TerrainPatch terrainPatch, List locations, HashMap updates); public LodCalculator clone(); + + public void turnOffLod(); + public void turnOnLod(); + public boolean isLodOff(); /** * If true, then this calculator can cause neighbouring terrain chunks to diff --git a/engine/src/terrain/com/jme3/terrain/geomipmap/lodcalc/PerspectiveLodCalculator.java b/engine/src/terrain/com/jme3/terrain/geomipmap/lodcalc/PerspectiveLodCalculator.java index ceb999b0c..312b17d7f 100644 --- a/engine/src/terrain/com/jme3/terrain/geomipmap/lodcalc/PerspectiveLodCalculator.java +++ b/engine/src/terrain/com/jme3/terrain/geomipmap/lodcalc/PerspectiveLodCalculator.java @@ -160,6 +160,16 @@ public class PerspectiveLodCalculator implements LodCalculator { this.cam = cam; } + public void turnOffLod() { + //TODO + } + + public boolean isLodOff() { + return false; //TODO + } + public void turnOnLod() { + //TODO + } }