fixed an issue with TerrainGrid not having a large enough cache of tiles. Properly hooked in the tileDetached event

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9772 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
bre..om 12 years ago
parent 8efd28da76
commit c4574bff13
  1. 42
      engine/src/terrain/com/jme3/terrain/geomipmap/TerrainGrid.java
  2. 16
      engine/src/terrain/com/jme3/terrain/geomipmap/TerrainGridListener.java
  3. 4
      engine/src/test/jme3test/terrain/TerrainGridSerializationTest.java
  4. 7
      engine/src/test/jme3test/terrain/TerrainGridTest.java
  5. 4
      engine/src/test/jme3test/terrain/TerrainGridTileLoaderTest.java

@ -114,7 +114,8 @@ public class TerrainGrid extends TerrainQuad {
protected Vector3f[] quadIndex; protected Vector3f[] quadIndex;
protected Set<TerrainGridListener> listeners = new HashSet<TerrainGridListener>(); protected Set<TerrainGridListener> listeners = new HashSet<TerrainGridListener>();
protected Material material; protected Material material;
protected LRUCache<Vector3f, TerrainQuad> cache = new LRUCache<Vector3f, TerrainQuad>(16); //cache needs to be 1 row (4 cells) larger than what we care is cached
protected LRUCache<Vector3f, TerrainQuad> cache = new LRUCache<Vector3f, TerrainQuad>(20);
protected int cellsLoaded = 0; protected int cellsLoaded = 0;
protected int[] gridOffset; protected int[] gridOffset;
protected boolean runOnce = false; protected boolean runOnce = false;
@ -159,16 +160,28 @@ public class TerrainGrid extends TerrainQuad {
} }
cache.put(quadCell, q); cache.put(quadCell, q);
if (isCenter(quadIdx)) {
// if it should be attached as a child right now, attach it
final int quadrant = getQuadrant(quadIdx); final int quadrant = getQuadrant(quadIdx);
final TerrainQuad newQuad = q; final TerrainQuad newQuad = q;
if (isCenter(quadIdx)) {
// if it should be attached as a child right now, attach it
getControl(UpdateControl.class).enqueue(new Callable() {
// back on the OpenGL thread: // back on the OpenGL thread:
public Object call() throws Exception {
if (newQuad.getParent() != null) {
attachQuadAt(newQuad, quadrant, quadCell, true);
}
else {
attachQuadAt(newQuad, quadrant, quadCell, false);
}
return null;
}
});
} else {
getControl(UpdateControl.class).enqueue(new Callable() { getControl(UpdateControl.class).enqueue(new Callable() {
public Object call() throws Exception { public Object call() throws Exception {
attachQuadAt(newQuad, quadrant, quadCell); removeQuad(newQuad);
//newQuad.resetCachedNeighbours();
return null; return null;
} }
}); });
@ -292,31 +305,35 @@ public class TerrainGrid extends TerrainQuad {
return gridTileLoader; return gridTileLoader;
} }
protected void removeQuad(int idx) { protected void removeQuad(TerrainQuad q) {
if (this.getQuad(idx) != null) { if (q != null && ( (q.getQuadrant() > 0 && q.getQuadrant()<5) || q.getParent() != null) ) {
for (TerrainGridListener l : listeners) { for (TerrainGridListener l : listeners) {
l.tileDetached(getTileCell(this.getQuad(idx).getWorldTranslation()), this.getQuad(idx)); l.tileDetached(getTileCell(q.getWorldTranslation()), q);
} }
this.detachChild(this.getQuad(idx)); q.setQuadrant((short)0);
this.detachChild(q);
cellsLoaded++; // For gridoffset calc., maybe the run() method is a better location for this. cellsLoaded++; // For gridoffset calc., maybe the run() method is a better location for this.
} }
} }
/** /**
* Runs on the rendering thread * Runs on the rendering thread
* @param shifted quads are still attached to the parent and don't need to re-load
*/ */
protected void attachQuadAt(TerrainQuad q, int quadrant, Vector3f quadCell) { protected void attachQuadAt(TerrainQuad q, int quadrant, Vector3f quadCell, boolean shifted) {
this.removeQuad(quadrant);
q.setQuadrant((short) quadrant); q.setQuadrant((short) quadrant);
if (!shifted)
this.attachChild(q); this.attachChild(q);
Vector3f loc = quadCell.mult(this.quadSize - 1).subtract(quarterSize, 0, quarterSize);// quadrant location handled TerrainQuad automatically now Vector3f loc = quadCell.mult(this.quadSize - 1).subtract(quarterSize, 0, quarterSize);// quadrant location handled TerrainQuad automatically now
q.setLocalTranslation(loc); q.setLocalTranslation(loc);
if (!shifted) {
for (TerrainGridListener l : listeners) { for (TerrainGridListener l : listeners) {
l.tileAttached(quadCell, q); l.tileAttached(quadCell, q);
} }
}
updateModelBound(); updateModelBound();
for (Spatial s : getChildren()) { for (Spatial s : getChildren()) {
@ -374,6 +391,7 @@ public class TerrainGrid extends TerrainQuad {
cache.get(camCell.add(quadIndex[i * 4 + j])); cache.get(camCell.add(quadIndex[i * 4 + j]));
} }
} }
// --------------------------------------------------- // ---------------------------------------------------
// --------------------------------------------------- // ---------------------------------------------------

@ -34,14 +34,28 @@ package com.jme3.terrain.geomipmap;
import com.jme3.math.Vector3f; import com.jme3.math.Vector3f;
/** /**
* * Notifies the user of grid change events, such as moving to new grid cells.
* @author Anthyon * @author Anthyon
*/ */
public interface TerrainGridListener { public interface TerrainGridListener {
/**
* Called whenever the camera has moved full grid cells. This triggers new tiles to load.
* @param newCenter
*/
public void gridMoved(Vector3f newCenter); public void gridMoved(Vector3f newCenter);
/**
* Called when a TerrainQuad is attached to the scene and is visible (attached to the root TerrainGrid)
* @param cell the cell that is moved into
* @param quad the quad that was just attached
*/
public void tileAttached( Vector3f cell, TerrainQuad quad ); public void tileAttached( Vector3f cell, TerrainQuad quad );
/**
* Called when a TerrainQuad is detached from its TerrainGrid parent: it is no longer on the scene graph.
* @param cell the cell that is moved into
* @param quad the quad that was just detached
*/
public void tileDetached( Vector3f cell, TerrainQuad quad ); public void tileDetached( Vector3f cell, TerrainQuad quad );
} }

@ -78,10 +78,6 @@ public class TerrainGridSerializationTest extends SimpleApplication {
public void gridMoved(Vector3f newCenter) { public void gridMoved(Vector3f newCenter) {
} }
public Material tileLoaded(Material material, Vector3f cell) {
return material;
}
public void tileAttached(Vector3f cell, TerrainQuad quad) { public void tileAttached(Vector3f cell, TerrainQuad quad) {
//workaround for bugged test j3o's //workaround for bugged test j3o's
while(quad.getControl(RigidBodyControl.class)!=null){ while(quad.getControl(RigidBodyControl.class)!=null){

@ -115,7 +115,8 @@ public class TerrainGridTest extends SimpleApplication {
final BulletAppState bulletAppState = new BulletAppState(); final BulletAppState bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState); stateManager.attach(bulletAppState);
this.getCamera().setLocation(new Vector3f(0, 200, 0)); this.getCamera().setLocation(new Vector3f(0, 400, 0));
this.getCamera().lookAt(new Vector3f(0,0,0), Vector3f.UNIT_Y);
this.viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f)); this.viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f));
@ -139,10 +140,6 @@ public class TerrainGridTest extends SimpleApplication {
public void gridMoved(Vector3f newCenter) { public void gridMoved(Vector3f newCenter) {
} }
public Material tileLoaded(Material material, Vector3f cell) {
return material;
}
public void tileAttached(Vector3f cell, TerrainQuad quad) { public void tileAttached(Vector3f cell, TerrainQuad quad) {
while(quad.getControl(RigidBodyControl.class)!=null){ while(quad.getControl(RigidBodyControl.class)!=null){
quad.removeControl(RigidBodyControl.class); quad.removeControl(RigidBodyControl.class);

@ -136,10 +136,6 @@ public class TerrainGridTileLoaderTest extends SimpleApplication {
public void gridMoved(Vector3f newCenter) { public void gridMoved(Vector3f newCenter) {
} }
public Material tileLoaded(Material material, Vector3f cell) {
return material;
}
public void tileAttached(Vector3f cell, TerrainQuad quad) { public void tileAttached(Vector3f cell, TerrainQuad quad) {
while(quad.getControl(RigidBodyControl.class)!=null){ while(quad.getControl(RigidBodyControl.class)!=null){
quad.removeControl(RigidBodyControl.class); quad.removeControl(RigidBodyControl.class);

Loading…
Cancel
Save