com.jme3.terrain.geomipmap
Class TerrainGrid

java.lang.Object
  extended by com.jme3.scene.Spatial
      extended by com.jme3.scene.Node
          extended by com.jme3.terrain.geomipmap.TerrainQuad
              extended by com.jme3.terrain.geomipmap.TerrainGrid
All Implemented Interfaces:
CloneableSmartAsset, Collidable, Savable, Terrain, java.lang.Cloneable

public class TerrainGrid
extends TerrainQuad

TerrainGrid itself is an actual TerrainQuad. Its four children are the visible four tiles.

The grid is indexed by cells. Each cell has an integer XZ coordinate originating at 0,0. TerrainGrid will piggyback on the TerrainLodControl so it can use the camera for its updates as well. It does this in the overwritten update() method.

It uses an LRU (Least Recently Used) cache of 16 terrain tiles (full TerrainQuadTrees). The center 4 are the ones that are visible. As the camera moves, it checks what camera cell it is in and will attach the now visible tiles.

The 'quadIndex' variable is a 4x4 array that represents the tiles. The center four (index numbers: 5, 6, 9, 10) are what is visible. Each quadIndex value is an offset vector. The vector contains whole numbers and represents how many tiles in offset this location is from the center of the map. So for example the index 11 [Vector3f(2, 0, 1)] is located 2*terrainSize in X axis and 1*terrainSize in Z axis.

As the camera moves, it tests what cameraCell it is in. Each camera cell covers four quad tiles and is half way inside each one.

 +-------+-------+
 | 1     |     4 |    Four terrainQuads that make up the grid
 |    *..|..*    |    with the cameraCell in the middle, covering
 |----|--|--|----|    all four quads.
 |    *..|..*    |
 | 2     |     3 |
 +-------+-------+
 

This results in the effect of when the camera gets half way across one of the sides of a quad to an empty (non-loaded) area, it will trigger the system to load in the next tiles.

The tile loading is done on a background thread, and once the tile is loaded, then it is attached to the qrid quad tree, back on the OGL thread. It will grab the terrain quad from the LRU cache if it exists. If it does not exist, it will load in the new TerrainQuad tile.

The loading of new tiles triggers events for any TerrainGridListeners. The events are:

These allow physics to update, and other operation (often needed for loading the terrain) to occur at the right time.


Nested Class Summary
protected  class TerrainGrid.UpdateQuadCache
           
 
Nested classes/interfaces inherited from class com.jme3.terrain.geomipmap.TerrainQuad
TerrainQuad.LocationHeight
 
Nested classes/interfaces inherited from class com.jme3.scene.Spatial
Spatial.BatchHint, Spatial.CullHint
 
Field Summary
protected  LRUCache<Vector3f,TerrainQuad> cache
           
protected  java.util.concurrent.ExecutorService cacheExecutor
           
protected  int cellsLoaded
           
protected  Vector3f currentCamCell
           
protected  int[] gridOffset
           
protected  HeightMapGrid heightMapGrid
           
protected  java.util.Set<TerrainGridListener> listeners
           
protected static java.util.logging.Logger log
           
protected  Material material
           
protected  Vector3f[] quadIndex
           
protected  int quadSize
           
protected  int quarterSize
           
protected  boolean runOnce
           
 
Fields inherited from class com.jme3.terrain.geomipmap.TerrainQuad
neighbourFinder, offset, offsetAmount, patchSize, quadrant, size, stepScale, totalSize
 
Fields inherited from class com.jme3.scene.Node
children
 
Fields inherited from class com.jme3.scene.Spatial
batchHint, controls, cullHint, frustrumIntersects, key, localLights, localTransform, name, parent, queueBucket, queueDistance, refreshFlags, RF_BOUND, RF_LIGHTLIST, RF_TRANSFORM, shadowMode, userData, worldBound, worldLights, worldTransform
 
Constructor Summary
TerrainGrid()
           
TerrainGrid(java.lang.String name, int patchSize, int maxVisibleSize, HeightMapGrid heightMapGrid)
          Deprecated. 
TerrainGrid(java.lang.String name, int patchSize, int maxVisibleSize, TerrainGridTileLoader terrainQuadGrid)
           
TerrainGrid(java.lang.String name, int patchSize, int maxVisibleSize, Vector3f scale, HeightMapGrid heightMapGrid)
          Deprecated. 
TerrainGrid(java.lang.String name, int patchSize, int maxVisibleSize, Vector3f scale, HeightMapGrid heightMapGrid, Vector2f offset, float offsetAmount)
          Deprecated. 
TerrainGrid(java.lang.String name, int patchSize, int maxVisibleSize, Vector3f scale, TerrainGridTileLoader terrainQuadGrid)
           
TerrainGrid(java.lang.String name, int patchSize, int maxVisibleSize, Vector3f scale, TerrainGridTileLoader terrainQuadGrid, Vector2f offset, float offsetAmount)
           
 
Method Summary
 void addListener(TerrainGridListener listener)
           
 void adjustHeight(java.util.List<Vector2f> xz, java.util.List<java.lang.Float> height)
          Raise/lower the height at many points.
protected  void attachQuadAt(TerrainQuad q, int quadrant, Vector3f quadCell)
          Runs on the rendering thread
protected  java.util.concurrent.ExecutorService createExecutorService()
           
 Vector3f getCamCell(Vector3f location)
           
 Vector3f getCurrentCell()
           
 TerrainGridTileLoader getGridTileLoader()
           
protected  float getHeightmapHeight(int x, int z)
          This will just get the heightmap value at the supplied point, not an interpolated (actual) height value.
 Material getMaterial(Vector3f worldLocation)
          Returns the material that this terrain uses.
 int getNumMajorSubdivisions()
           
protected  int getQuadrant(int quadIndex)
           
 Vector3f getTileCell(Vector3f location)
          Centered at 0,0.
protected  boolean isCenter(int quadIndex)
           
 void read(JmeImporter im)
           
 void removeListener(TerrainGridListener listener)
           
protected  void removeQuad(int idx)
           
 void setMaterial(Material mat)
          Applies the given material to the Spatial, this will propagate the material down to the geometries in the scene graph.
 void setQuadSize(int quadSize)
           
protected  void updateChildren(Vector3f camCell)
          Called when the camera has moved into a new cell.
 void write(JmeExporter ex)
           
 
Methods inherited from class com.jme3.terrain.geomipmap.TerrainQuad
adjustHeight, attachBoundChildren, cacheTerrainTransforms, calculateLod, clone, clone, collideWith, createHeightSubBlock, createQuad, createQuadPatch, findDownPatch, findDownQuad, findLeftPatch, findLeftQuad, findNeighboursLod, findPick, findRightPatch, findRightQuad, findTopPatch, findTopQuad, fixEdges, fixNormalEdges, fixNormals, generateDebugTangents, generateEntropy, getAllTerrainPatches, getAllTerrainPatchesWithTranslation, getHeight, getHeight, getHeightMap, getHeightmapHeight, getMaterial, getMaxLod, getMeshNormal, getNormal, getNormal, getPatch, getPatchSize, getQuad, getQuadrant, getTerrainSize, getTotalSize, isPointOnTerrain, isRootQuad, needToRecalculateNormals, recalculateAllNormals, reIndexPages, resetCachedNeighbours, setHeight, setHeight, setHeight, setHeight, setLocked, setNeedToRecalculateNormals, setNeighbourFinder, setNormalRecalcNeeded, setQuadrant, split, updateNormals
 
Methods inherited from class com.jme3.scene.Node
attachChild, attachChildAt, breadthFirstTraversal, deepClone, depthFirstTraversal, descendantMatches, descendantMatches, descendantMatches, detachAllChildren, detachChild, detachChildAt, detachChildNamed, getChild, getChild, getChildIndex, getChildren, getQuantity, getTriangleCount, getVertexCount, hasChild, setLightListRefresh, setLodLevel, setModelBound, setTransformRefresh, swapChildren, updateGeometricState, updateLogicalState, updateModelBound, updateWorldBound
 
Methods inherited from class com.jme3.scene.Spatial
addControl, addLight, breadthFirstTraversal, center, checkCulling, getBatchHint, getControl, getControl, getCullHint, getKey, getLastFrustumIntersection, getLocalBatchHint, getLocalCullHint, getLocalLightList, getLocalQueueBucket, getLocalRotation, getLocalScale, getLocalShadowMode, getLocalToWorldMatrix, getLocalTransform, getLocalTranslation, getName, getNumControls, getParent, getQueueBucket, getShadowMode, getUserData, getUserDataKeys, getWorldBound, getWorldLightList, getWorldRotation, getWorldScale, getWorldTransform, getWorldTranslation, hasAncestor, localToWorld, lookAt, matches, move, move, removeControl, removeControl, removeFromParent, removeLight, rotate, rotate, rotateUpTo, runControlRender, scale, scale, setBatchHint, setBoundRefresh, setCullHint, setKey, setLastFrustumIntersection, setLocalRotation, setLocalRotation, setLocalScale, setLocalScale, setLocalScale, setLocalTransform, setLocalTranslation, setLocalTranslation, setName, setParent, setQueueBucket, setShadowMode, setUserData, toString, updateWorldLightList, updateWorldTransforms, worldToLocal
 
Methods inherited from class java.lang.Object
equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

log

protected static final java.util.logging.Logger log

currentCamCell

protected Vector3f currentCamCell

quarterSize

protected int quarterSize

quadSize

protected int quadSize

heightMapGrid

protected HeightMapGrid heightMapGrid

quadIndex

protected Vector3f[] quadIndex

listeners

protected java.util.Set<TerrainGridListener> listeners

material

protected Material material

cache

protected LRUCache<Vector3f,TerrainQuad> cache

cellsLoaded

protected int cellsLoaded

gridOffset

protected int[] gridOffset

runOnce

protected boolean runOnce

cacheExecutor

protected java.util.concurrent.ExecutorService cacheExecutor
Constructor Detail

TerrainGrid

public TerrainGrid(java.lang.String name,
                   int patchSize,
                   int maxVisibleSize,
                   Vector3f scale,
                   TerrainGridTileLoader terrainQuadGrid,
                   Vector2f offset,
                   float offsetAmount)

TerrainGrid

public TerrainGrid(java.lang.String name,
                   int patchSize,
                   int maxVisibleSize,
                   Vector3f scale,
                   TerrainGridTileLoader terrainQuadGrid)

TerrainGrid

public TerrainGrid(java.lang.String name,
                   int patchSize,
                   int maxVisibleSize,
                   TerrainGridTileLoader terrainQuadGrid)

TerrainGrid

@Deprecated
public TerrainGrid(java.lang.String name,
                              int patchSize,
                              int maxVisibleSize,
                              Vector3f scale,
                              HeightMapGrid heightMapGrid,
                              Vector2f offset,
                              float offsetAmount)
Deprecated. 


TerrainGrid

@Deprecated
public TerrainGrid(java.lang.String name,
                              int patchSize,
                              int maxVisibleSize,
                              Vector3f scale,
                              HeightMapGrid heightMapGrid)
Deprecated. 


TerrainGrid

@Deprecated
public TerrainGrid(java.lang.String name,
                              int patchSize,
                              int maxVisibleSize,
                              HeightMapGrid heightMapGrid)
Deprecated. 


TerrainGrid

public TerrainGrid()
Method Detail

isCenter

protected boolean isCenter(int quadIndex)

getQuadrant

protected int getQuadrant(int quadIndex)

getCamCell

public Vector3f getCamCell(Vector3f location)

getTileCell

public Vector3f getTileCell(Vector3f location)
Centered at 0,0. Get the tile index location in integer form:

Parameters:
location - world coordinate

getGridTileLoader

public TerrainGridTileLoader getGridTileLoader()

removeQuad

protected void removeQuad(int idx)

attachQuadAt

protected void attachQuadAt(TerrainQuad q,
                            int quadrant,
                            Vector3f quadCell)
Runs on the rendering thread


updateChildren

protected void updateChildren(Vector3f camCell)
Called when the camera has moved into a new cell. We need to update what quads are in the scene now. Step 1: touch cache LRU cache is used, so elements that need to remain should be touched. Step 2: load new quads in background thread if the camera has moved into a new cell, we load in new quads

Parameters:
camCell - the cell the camera is in

addListener

public void addListener(TerrainGridListener listener)

getCurrentCell

public Vector3f getCurrentCell()

removeListener

public void removeListener(TerrainGridListener listener)

setMaterial

public void setMaterial(Material mat)
Description copied from class: Spatial
Applies the given material to the Spatial, this will propagate the material down to the geometries in the scene graph.

Overrides:
setMaterial in class Node
Parameters:
mat - The material to set.

setQuadSize

public void setQuadSize(int quadSize)

adjustHeight

public void adjustHeight(java.util.List<Vector2f> xz,
                         java.util.List<java.lang.Float> height)
Description copied from interface: Terrain
Raise/lower the height at many points. The two lists must be the same size. Each xz coordinate entry matches to a height entry, 1 for 1. So the first coordinate matches to the first height value, the last to the last etc.

Specified by:
adjustHeight in interface Terrain
Overrides:
adjustHeight in class TerrainQuad
Parameters:
xz - a list of coordinates where the hight will be adjusted
height - +- value to adjust the height by, that matches the xz coordinates

getHeightmapHeight

protected float getHeightmapHeight(int x,
                                   int z)
Description copied from class: TerrainQuad
This will just get the heightmap value at the supplied point, not an interpolated (actual) height value.

Overrides:
getHeightmapHeight in class TerrainQuad

getNumMajorSubdivisions

public int getNumMajorSubdivisions()
Specified by:
getNumMajorSubdivisions in interface Terrain
Overrides:
getNumMajorSubdivisions in class TerrainQuad

getMaterial

public Material getMaterial(Vector3f worldLocation)
Description copied from interface: Terrain
Returns the material that this terrain uses. Terrain can have different materials in different locations. In general, the TerrainQuad will only have one material. But TerrainGrid will have a different material per tile. It could be possible to pass in null for the location, some Terrain implementations might just have the one material and not care where you are looking. So implementations must handle null being supplied.

Specified by:
getMaterial in interface Terrain
Overrides:
getMaterial in class TerrainQuad
Parameters:
worldLocation - the location, in world coordinates, of where we are interested in the underlying texture.

createExecutorService

protected java.util.concurrent.ExecutorService createExecutorService()

read

public void read(JmeImporter im)
          throws java.io.IOException
Specified by:
read in interface Savable
Overrides:
read in class TerrainQuad
Throws:
java.io.IOException

write

public void write(JmeExporter ex)
           throws java.io.IOException
Specified by:
write in interface Savable
Overrides:
write in class TerrainQuad
Throws:
java.io.IOException