Browse Source

terrain lod control rafactoring

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8249 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
bre..ns 14 years ago
parent
commit
f6ebb7a262

+ 32 - 1
engine/src/terrain/com/jme3/terrain/geomipmap/TerrainLodControl.java

@@ -68,6 +68,7 @@ public class TerrainLodControl extends AbstractControl {
     private List<Camera> cameras;
     private List<Vector3f> cameraLocations = new ArrayList<Vector3f>();
     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());
     }
+
 }

+ 19 - 3
engine/src/terrain/com/jme3/terrain/geomipmap/TerrainQuad.java

@@ -115,6 +115,7 @@ public class TerrainQuad extends Node implements Terrain {
     
     protected List<Vector3f> lastCameraLocations; // used for LOD calc
     private boolean lodCalcRunning = false;
+    private int lodOffCount = 0;
     private int maxLod = -1;
     private HashMap<String,UpdatedTerrainPatch> 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<Vector3f> location, HashMap<String,UpdatedTerrainPatch> 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)

+ 2 - 2
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();
 	}
 

+ 28 - 2
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<Vector3f> locations, HashMap<String, UpdatedTerrainPatch> 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;
+    }
     
 }

+ 4 - 0
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<Vector3f> locations, HashMap<String,UpdatedTerrainPatch> updates);
     
     public LodCalculator clone();
+    
+    public void turnOffLod();
+    public void turnOnLod();
+    public boolean isLodOff();
 
     /**
      * If true, then this calculator can cause neighbouring terrain chunks to 

+ 10 - 0
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
+    }
     
 }