terrain lod control rafactoring

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8249 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
bre..ns 14 years ago
parent 393c67c9b7
commit f6ebb7a262
  1. 33
      engine/src/terrain/com/jme3/terrain/geomipmap/TerrainLodControl.java
  2. 22
      engine/src/terrain/com/jme3/terrain/geomipmap/TerrainQuad.java
  3. 4
      engine/src/terrain/com/jme3/terrain/geomipmap/UpdatedTerrainPatch.java
  4. 30
      engine/src/terrain/com/jme3/terrain/geomipmap/lodcalc/DistanceLodCalculator.java
  5. 4
      engine/src/terrain/com/jme3/terrain/geomipmap/lodcalc/LodCalculator.java
  6. 10
      engine/src/terrain/com/jme3/terrain/geomipmap/lodcalc/PerspectiveLodCalculator.java

@ -68,6 +68,7 @@ public class TerrainLodControl extends AbstractControl {
private List<Camera> cameras; private List<Camera> cameras;
private List<Vector3f> cameraLocations = new ArrayList<Vector3f>(); private List<Vector3f> cameraLocations = new ArrayList<Vector3f>();
private LodCalculator lodCalculator; private LodCalculator lodCalculator;
private boolean hasResetLod = false; // used when enabled is set to false
public TerrainLodControl() { public TerrainLodControl() {
} }
@ -94,10 +95,26 @@ public class TerrainLodControl extends AbstractControl {
protected void controlRender(RenderManager rm, ViewPort vp) { protected void controlRender(RenderManager rm, ViewPort vp) {
} }
@Override
public void update(float tpf) {
controlUpdate(tpf);
}
@Override @Override
protected void controlUpdate(float tpf) { protected void controlUpdate(float tpf) {
//list of cameras for when terrain supports multiple cameras (ie split screen) //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 (cameras != null) {
if (cameraLocations.isEmpty() && !cameras.isEmpty()) { if (cameraLocations.isEmpty() && !cameras.isEmpty()) {
for (Camera c : cameras) // populate them for (Camera c : cameras) // populate them
@ -117,7 +134,9 @@ public class TerrainLodControl extends AbstractControl {
cameraClone.add(c); cameraClone.add(c);
} }
} }
return new TerrainLodControl((Terrain) spatial, cameraClone); TerrainLodControl cloned = new TerrainLodControl((Terrain) spatial, cameraClone);
cloned.setLodCalculator(lodCalculator.clone());
return cloned;
} }
return null; return null;
} }
@ -156,6 +175,17 @@ public class TerrainLodControl extends AbstractControl {
this.lodCalculator = lodCalculator; 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 @Override
public void write(JmeExporter ex) throws IOException { public void write(JmeExporter ex) throws IOException {
@ -172,4 +202,5 @@ public class TerrainLodControl extends AbstractControl {
terrain = (Terrain) ic.readSavable("terrain", null); terrain = (Terrain) ic.readSavable("terrain", null);
lodCalculator = (LodCalculator) ic.readSavable("lodCalculator", new DistanceLodCalculator()); lodCalculator = (LodCalculator) ic.readSavable("lodCalculator", new DistanceLodCalculator());
} }
} }

@ -115,6 +115,7 @@ public class TerrainQuad extends Node implements Terrain {
protected List<Vector3f> lastCameraLocations; // used for LOD calc protected List<Vector3f> lastCameraLocations; // used for LOD calc
private boolean lodCalcRunning = false; private boolean lodCalcRunning = false;
private int lodOffCount = 0;
private int maxLod = -1; private int maxLod = -1;
private HashMap<String,UpdatedTerrainPatch> updatedPatches; private HashMap<String,UpdatedTerrainPatch> updatedPatches;
private final Object updatePatchesLock = new Object(); private final Object updatePatchesLock = new Object();
@ -241,8 +242,17 @@ public class TerrainQuad extends Node implements Terrain {
// update any existing ones that need updating // update any existing ones that need updating
updateQuadLODs(); 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 (lastCameraLocations != null) {
if (lastCameraLocationsTheSame(locations)) if (lastCameraLocationsTheSame(locations) && !lodCalculator.isLodOff())
return; // don't update if in same spot return; // don't update if in same spot
else else
lastCameraLocations = cloneVectorList(locations); lastCameraLocations = cloneVectorList(locations);
@ -426,6 +436,10 @@ public class TerrainQuad extends Node implements Terrain {
} }
} }
public boolean hasPatchesToUpdate() {
return updatedPatches != null && !updatedPatches.isEmpty();
}
protected boolean calculateLod(List<Vector3f> location, HashMap<String,UpdatedTerrainPatch> updates, LodCalculator lodCalculator) { protected boolean calculateLod(List<Vector3f> location, HashMap<String,UpdatedTerrainPatch> updates, LodCalculator lodCalculator) {
boolean lodChanged = false; boolean lodChanged = false;
@ -1680,9 +1694,11 @@ public class TerrainQuad extends Node implements Terrain {
//quadClone.lodCalculatorFactory = lodCalculatorFactory.clone(); //quadClone.lodCalculatorFactory = lodCalculatorFactory.clone();
//quadClone.lodCalculator = lodCalculator.clone(); //quadClone.lodCalculator = lodCalculator.clone();
TerrainLodControl lodControlCloned = this.getControl(TerrainLodControl.class);
TerrainLodControl lodControl = quadClone.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); NormalRecalcControl normalControl = getControl(NormalRecalcControl.class);
if (normalControl != null) if (normalControl != null)

@ -90,9 +90,9 @@ public class UpdatedTerrainPatch {
return newLod; return newLod;
} }
protected void setNewLod(int newLod) { public void setNewLod(int newLod) {
this.newLod = newLod; this.newLod = newLod;
if (this.newLod <= 0) if (this.newLod < 0)
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }

@ -52,6 +52,7 @@ public class DistanceLodCalculator implements LodCalculator {
private int size; // size of a terrain patch private int size; // size of a terrain patch
private float lodMultiplier = 2; private float lodMultiplier = 2;
private boolean turnOffLod = false;
public DistanceLodCalculator() { public DistanceLodCalculator() {
} }
@ -64,6 +65,21 @@ public class DistanceLodCalculator implements LodCalculator {
public boolean calculateLod(TerrainPatch terrainPatch, List<Vector3f> locations, HashMap<String, UpdatedTerrainPatch> updates) { public boolean calculateLod(TerrainPatch terrainPatch, List<Vector3f> locations, HashMap<String, UpdatedTerrainPatch> updates) {
float distance = getCenterLocation(terrainPatch).distance(locations.get(0)); 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 // go through each lod level to find the one we are in
for (int i = 0; i <= terrainPatch.getMaxLod(); i++) { for (int i = 0; i <= terrainPatch.getMaxLod(); i++) {
if (distance < getLodDistanceThreshold() * (i + 1)*terrainPatch.getWorldScale().x || i == terrainPatch.getMaxLod()) { if (distance < getLodDistanceThreshold() * (i + 1)*terrainPatch.getWorldScale().x || i == terrainPatch.getMaxLod()) {
@ -111,8 +127,7 @@ public class DistanceLodCalculator implements LodCalculator {
@Override @Override
public LodCalculator clone() { public LodCalculator clone() {
DistanceLodCalculator clone = new DistanceLodCalculator(); DistanceLodCalculator clone = new DistanceLodCalculator(size, lodMultiplier);
return clone; return clone;
} }
@ -152,5 +167,16 @@ public class DistanceLodCalculator implements LodCalculator {
this.size = size; this.size = size;
} }
public void turnOffLod() {
turnOffLod = true;
}
public boolean isLodOff() {
return turnOffLod;
}
public void turnOnLod() {
turnOffLod = false;
}
} }

@ -51,6 +51,10 @@ public interface LodCalculator extends Savable, Cloneable {
public LodCalculator clone(); public LodCalculator clone();
public void turnOffLod();
public void turnOnLod();
public boolean isLodOff();
/** /**
* If true, then this calculator can cause neighbouring terrain chunks to * If true, then this calculator can cause neighbouring terrain chunks to
* have LOD levels that are greater than 1 apart. * have LOD levels that are greater than 1 apart.

@ -160,6 +160,16 @@ public class PerspectiveLodCalculator implements LodCalculator {
this.cam = cam; this.cam = cam;
} }
public void turnOffLod() {
//TODO
}
public boolean isLodOff() {
return false; //TODO
}
public void turnOnLod() {
//TODO
}
} }

Loading…
Cancel
Save