Class TerrainQuad

java.lang.Object
com.jme3.scene.Spatial
com.jme3.scene.Node
com.jme3.terrain.geomipmap.TerrainQuad
All Implemented Interfaces:
HasLocalTransform, CloneableSmartAsset, Collidable, Savable, Terrain, JmeCloneable, Cloneable
Direct Known Subclasses:
TerrainGrid

public class TerrainQuad extends Node implements Terrain

TerrainQuad is a heightfield-based terrain system. Heightfield terrain is fast and can render large areas, and allows for easy Level of Detail control. However it does not permit caves easily. TerrainQuad is a quad tree, meaning that the root quad has four children, and each of those children have four children. All the way down until you reach the bottom, the actual geometry, the TerrainPatches. If you look at a TerrainQuad in wireframe mode with the TerrainLODControl attached, you will see blocks that change their LOD level together; these are the TerrainPatches. The TerrainQuad is just an organizational structure for the TerrainPatches so patches that are not in the view frustum get culled quickly. TerrainQuads size are a power of 2, plus 1. So 513x513, or 1025x1025 etc. Each point in the terrain is one unit apart from its neighbour. So a 513x513 terrain will be 513 units wide and 513 units long. Patch size can be specified on the terrain. This sets how large each geometry (TerrainPatch) is. It also must be a power of 2 plus 1 so the terrain can be subdivided equally.

The height of the terrain can be modified at runtime using setHeight()

A terrain quad is a node in the quad tree of the terrain system. The root terrain quad will be the only one that receives the update() call every frame and it will determine if there has been any LOD change.

The leaves of the terrain quad tree are Terrain Patches. These have the real geometry mesh.

Heightmap coordinates start from the bottom left of the world and work towards the top right.

  +x
  ^
  | ......N = length of heightmap
  | :     :
  | :     :
  | 0.....:
  +---------> +z
 (world coordinates)
 
  • Field Details

    • offset

      protected Vector2f offset
    • totalSize

      protected int totalSize
    • size

      protected int size
    • patchSize

      protected int patchSize
    • stepScale

      protected Vector3f stepScale
    • offsetAmount

      protected float offsetAmount
    • quadrant

      protected int quadrant
    • neighbourFinder

      protected NeighbourFinder neighbourFinder
  • Constructor Details

    • TerrainQuad

      public TerrainQuad()
    • TerrainQuad

      public TerrainQuad(String name, int patchSize, int totalSize, float[] heightMap)
      Creates a terrain with:
      • the total, real-world, size of the terrain
      • the patchSize, or the size of each geometry tile of the terrain
      • the heightmap that defines the height of the terrain

      A TerrainQuad of totalSize 513x513 will be 513 units wide and 513 units long. PatchSize is just used to subdivide the terrain into tiles that can be culled.

      Parameters:
      name - the name of the scene element. This is required for identification and comparison purposes.
      patchSize - size of the individual patches (geometry). Power of 2 plus 1, must be smaller than totalSize. (e.g. 33, 65...)
      totalSize - the size of this entire terrain (on one side). Power of 2 plus 1 (e.g. 513, 1025, 2049...)
      heightMap - The height map to generate the terrain from (a flat height map will be generated if this is null). The size of one side of the heightmap must match the totalSize. So a 513x513 heightmap is needed for a terrain with totalSize of 513.
    • TerrainQuad

      @Deprecated public TerrainQuad(String name, int patchSize, int size, Vector3f scale, float[] heightMap)
      Deprecated.
      Parameters:
      name - the name of the scene element. This is required for identification and comparison purposes.
      patchSize - size of the individual patches
      size - size of this quad, can be between totalSize and patchSize
      scale -
      heightMap - The height map to generate the terrain from (a flat height map will be generated if this is null)
    • TerrainQuad

      @Deprecated public TerrainQuad(String name, int patchSize, int totalSize, int quadSize, Vector3f scale, float[] heightMap)
      Deprecated.
      Parameters:
      name - the name of the scene element. This is required for identification and comparison purposes.
      patchSize - size of the individual patches
      totalSize - the size of this entire terrain tree (on one side)
      quadSize -
      scale -
      heightMap - The height map to generate the terrain from (a flat height map will be generated if this is null)
    • TerrainQuad

      protected TerrainQuad(String name, int patchSize, int quadSize, Vector3f scale, float[] heightMap, int totalSize, Vector2f offset, float offsetAmount)
  • Method Details

    • setNeighbourFinder

      public void setNeighbourFinder(NeighbourFinder neighbourFinder)
    • recalculateAllNormals

      public void recalculateAllNormals()
      Forces the recalculation of all normals on the terrain.
    • updateNormals

      protected void updateNormals()
      update the normals if there were any height changes recently. Should only be called on the root quad
    • cacheTerrainTransforms

      protected void cacheTerrainTransforms()
      Caches the transforms (except rotation) so the LOD calculator, which runs on a separate thread, can access them safely.
    • generateEntropy

      public void generateEntropy(ProgressMonitor progressMonitor)
      Generate the entropy values for the terrain for the "perspective" LOD calculator. This routine can take a long time to run!
      Specified by:
      generateEntropy in interface Terrain
      Parameters:
      progressMonitor - optional
    • isRootQuad

      protected boolean isRootQuad()
    • getMaterial

      public Material getMaterial()
      Description copied from interface: Terrain
      Returns the material that this terrain uses. If it uses many materials, just return the one you think is best. For TerrainQuads this is sufficient. For TerrainGrid you want to call getMaterial(Vector3f) instead.
      Specified by:
      getMaterial in interface Terrain
    • 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
      Parameters:
      worldLocation - the location, in world coordinates, of where we are interested in the underlying texture.
    • getNumMajorSubdivisions

      public int getNumMajorSubdivisions()
      Specified by:
      getNumMajorSubdivisions in interface Terrain
    • calculateLod

      protected boolean calculateLod(List<Vector3f> location, HashMap<String,UpdatedTerrainPatch> updates, LodCalculator lodCalculator)
    • findNeighboursLod

      protected void findNeighboursLod(HashMap<String,UpdatedTerrainPatch> updated)
    • resetCachedNeighbours

      public void resetCachedNeighbours()
      Reset the cached references of neighbours. TerrainQuad caches neighbours for faster LOD checks. Sometimes you might want to reset this cache (for instance in TerrainGrid)
    • fixEdges

      protected void fixEdges(HashMap<String,UpdatedTerrainPatch> updated)
      Find any neighbours that should have their edges seamed because another neighbour changed its LOD to a greater value (less detailed)
    • reIndexPages

      protected void reIndexPages(HashMap<String,UpdatedTerrainPatch> updated, boolean usesVariableLod)
    • split

      protected void split(int blockSize, float[] heightMap)
      split divides the heightmap data for four children. The children are either quads or patches. This is dependent on the size of the children. If the child's size is less than or equal to the set block size, then patches are created, otherwise, quads are created.
      Parameters:
      blockSize - the blocks size to test against.
      heightMap - the height data.
    • createQuad

      protected void createQuad(int blockSize, float[] heightMap)
      Quadrants, world coordinates, and heightmap coordinates (Y-up): -z -u | -v 1|3 -x ----+---- x 2|4 u | v z createQuad generates four new quads from this quad. The heightmap's top left (0,0) coordinate is at the bottom, -x,-z coordinate of the terrain, so it grows in the positive x.z direction.
    • generateDebugTangents

      public void generateDebugTangents(Material mat)
    • createQuadPatch

      protected void createQuadPatch(float[] heightMap)
      createQuadPatch creates four child patches from this quad.
    • createHeightSubBlock

      public float[] createHeightSubBlock(float[] heightMap, int x, int y, int side)
    • attachBoundChildren

      public void attachBoundChildren(Node parent)
      A handy method that will attach all bounding boxes of this terrain to the node you supply. Useful to visualize the bounding boxes when debugging.
      Parameters:
      parent - that will get the bounding box shapes of the terrain attached to
    • setNormalRecalcNeeded

      protected void setNormalRecalcNeeded(Vector2f changedPoint)
      Signal if the normal vectors for the terrain need to be recalculated. Does this by looking at the affectedAreaBBox bounding box. If the bbox exists already, then it will grow the box to fit the new changedPoint. If the affectedAreaBBox is null, then it will create one of unit size.
      Parameters:
      changedPoint - a location to include
    • needToRecalculateNormals

      protected boolean needToRecalculateNormals()
    • setNeedToRecalculateNormals

      protected void setNeedToRecalculateNormals()
      This will cause all normals for this terrain quad to be recalculated
    • getHeightmapHeight

      public float getHeightmapHeight(Vector2f xz)
      Description copied from interface: Terrain
      Get the heightmap height at the specified X-Z coordinate. This does not count scaling and snaps the XZ coordinate to the nearest (rounded) heightmap grid point.
      Specified by:
      getHeightmapHeight in interface Terrain
      Parameters:
      xz - world coordinate
      Returns:
      the height, unscaled and uninterpolated
    • getHeightmapHeight

      protected float getHeightmapHeight(int x, int z)
      This will just get the heightmap value at the supplied point, not an interpolated (actual) height value.
    • getMeshNormal

      protected Vector3f getMeshNormal(int x, int z)
    • getHeight

      public float getHeight(Vector2f xz)
      Get the interpolated height of the terrain at the specified point.
      Specified by:
      getHeight in interface Terrain
      Parameters:
      xz - the location to get the height for
      Returns:
      Float.NAN if the value does not exist, or the coordinates lie outside the terrain
    • getHeight

      protected float getHeight(int x, int z, float xm, float zm)
      gets an interpolated value at the specified point
    • getNormal

      public Vector3f getNormal(Vector2f xz)
      Description copied from interface: Terrain
      Get the normal vector for the surface of the terrain at the specified X-Z coordinate. This normal vector can be a close approximation. It does not take into account any normal maps on the material.
      Specified by:
      getNormal in interface Terrain
      Parameters:
      xz - the X-Z world coordinate
      Returns:
      the normal vector at the given point
    • getNormal

      protected Vector3f getNormal(float x, float z, Vector2f xz)
    • setHeight

      public void setHeight(Vector2f xz, float height)
      Description copied from interface: Terrain
      Set the height at the specified X-Z coordinate. To set the height of the terrain and see it, you will have to unlock the terrain meshes by calling terrain.setLocked(false) before you call setHeight().
      Specified by:
      setHeight in interface Terrain
      Parameters:
      xz - coordinate to set the height
      height - that will be set at the coordinate
    • adjustHeight

      public void adjustHeight(Vector2f xz, float delta)
      Description copied from interface: Terrain
      Raise/lower the height in one call (instead of getHeight then setHeight).
      Specified by:
      adjustHeight in interface Terrain
      Parameters:
      xz - world coordinate to adjust the terrain height
      delta - +- value to adjust the height by
    • setHeight

      public void setHeight(List<Vector2f> xz, List<Float> height)
      Description copied from interface: Terrain
      Set 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:
      setHeight in interface Terrain
      Parameters:
      xz - a list of coordinates where the height will be set
      height - the heights that match the xz coordinates
    • adjustHeight

      public void adjustHeight(List<Vector2f> xz, List<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
      Parameters:
      xz - a list of coordinates where the height will be adjusted
      height - +- value to adjust the height by, that matches the xz coordinates
    • setHeight

      protected void setHeight(List<Vector2f> xz, List<Float> height, boolean overrideHeight)
    • setHeight

      protected void setHeight(List<TerrainQuad.LocationHeight> locations, boolean overrideHeight)
    • isPointOnTerrain

      protected boolean isPointOnTerrain(int x, int z)
    • getTerrainSize

      public int getTerrainSize()
      Description copied from interface: Terrain
      Used for painting to get the number of vertices along the edge of the terrain. This is an un-scaled size, and should represent the vertex count (i.e. the texture coord count) along an edge of a square terrain. In the standard TerrainQuad default implementation, this will return the "totalSize" of the terrain (512 or so).
      Specified by:
      getTerrainSize in interface Terrain
    • setLocked

      public void setLocked(boolean locked)
      lock or unlock the meshes of this terrain. Locked meshes are uneditable but have better performance.
      Specified by:
      setLocked in interface Terrain
      Parameters:
      locked - or unlocked
    • getQuadrant

      public int getQuadrant()
    • setQuadrant

      public void setQuadrant(short quadrant)
    • getPatch

      protected TerrainPatch getPatch(int quad)
    • getQuad

      protected TerrainQuad getQuad(int quad)
    • findRightPatch

      protected TerrainPatch findRightPatch(TerrainPatch tp)
    • findDownPatch

      protected TerrainPatch findDownPatch(TerrainPatch tp)
    • findTopPatch

      protected TerrainPatch findTopPatch(TerrainPatch tp)
    • findLeftPatch

      protected TerrainPatch findLeftPatch(TerrainPatch tp)
    • findRightQuad

      protected TerrainQuad findRightQuad()
    • findDownQuad

      protected TerrainQuad findDownQuad()
    • findTopQuad

      protected TerrainQuad findTopQuad()
    • findLeftQuad

      protected TerrainQuad findLeftQuad()
    • fixNormals

      public void fixNormals(BoundingBox affectedArea)
      Find what terrain patches need normal recalculations and update their normals;
    • fixNormalEdges

      public void fixNormalEdges(BoundingBox affectedArea)
      fix the normals on the edge of the terrain patches.
    • collideWith

      public int collideWith(Collidable other, CollisionResults results)
      Description copied from interface: Collidable
      Check collision with another Collidable.
      Specified by:
      collideWith in interface Collidable
      Overrides:
      collideWith in class Node
      Parameters:
      other - The object to check collision against
      results - Will contain the list of CollisionResults.
      Returns:
      how many collisions were found between this and other
    • findPick

      public void findPick(Ray toTest, List<TerrainPickData> results)
      Gather the terrain patches that intersect the given ray (toTest). This only tests the bounding boxes
      Parameters:
      toTest -
      results -
    • getAllTerrainPatches

      public void getAllTerrainPatches(List<TerrainPatch> holder)
      Retrieve all Terrain Patches from all children and store them in the 'holder' list
      Parameters:
      holder - must not be null, will be populated when returns
    • getAllTerrainPatchesWithTranslation

      public void getAllTerrainPatchesWithTranslation(Map<TerrainPatch,Vector3f> holder, Vector3f translation)
    • read

      public void read(JmeImporter importer) throws IOException
      Specified by:
      read in interface Savable
      Overrides:
      read in class Node
      Throws:
      IOException
    • write

      public void write(JmeExporter e) throws IOException
      Specified by:
      write in interface Savable
      Overrides:
      write in class Node
      Throws:
      IOException
    • clone

      public TerrainQuad clone()
      Description copied from interface: CloneableSmartAsset
      Creates a clone of the asset. Please see Object.clone() for more info on how this method should be implemented.
      Specified by:
      clone in interface CloneableSmartAsset
      Overrides:
      clone in class Spatial
      Returns:
      A clone of this Spatial, the scene graph in its entirety is cloned and can be altered independently of the original scene graph. Note that meshes of geometries are not cloned explicitly, they are shared if static, or specially cloned if animated.
      See Also:
    • clone

      public TerrainQuad clone(boolean cloneMaterials)
      Overrides:
      clone in class Node
      Parameters:
      cloneMaterials - true to clone materials, false to share them
      Returns:
      A clone of this Spatial, the scene graph in its entirety is cloned and can be altered independently of the original scene graph. Note that meshes of geometries are not cloned explicitly, they are shared if static, or specially cloned if animated.
      See Also:
    • cloneFields

      public void cloneFields(Cloner cloner, Object original)
      Called internally by com.jme3.util.clone.Cloner. Do not call directly.
      Specified by:
      cloneFields in interface JmeCloneable
      Overrides:
      cloneFields in class Node
      Parameters:
      cloner - The cloner that is performing the cloning operation. The cloneFields method can call back into the cloner to make clones of its subordinate fields.
      original - The original object from which this object was cloned. This is provided for the very rare case that this object needs to refer to its original for some reason. In general, all of the relevant values should have been transferred during the shallow clone, and this object need only clone what it wants.
    • setParent

      protected void setParent(Node parent)
      Description copied from class: Spatial
      Called by Node.attachChild(Spatial) and Node.detachChild(Spatial) - don't call directly. setParent sets the parent of this node.
      Overrides:
      setParent in class Node
      Parameters:
      parent - the parent of this node.
    • clearCaches

      public void clearCaches()
      Removes any cached references this terrain is holding, in particular the TerrainPatch's neighbour references. This is called automatically when the root terrainQuad is detached from its parent or if setParent(null) is called.
    • getMaxLod

      public int getMaxLod()
      Description copied from interface: Terrain
      This is calculated by the specific LOD algorithm. A value of one means that the terrain is showing full detail. The higher the value, the more the terrain has been generalized and the less detailed it will be.
      Specified by:
      getMaxLod in interface Terrain
    • getPatchSize

      public int getPatchSize()
    • getTotalSize

      public int getTotalSize()
    • getHeightMap

      public float[] getHeightMap()
      Description copied from interface: Terrain
      Get the heightmap of the entire terrain. This can return null if that terrain object does not store the height data. Infinite or "paged" terrains will not be able to support this, so use with caution.
      Specified by:
      getHeightMap in interface Terrain
    • setSupportMultipleCollisions

      public void setSupportMultipleCollisions(boolean set)
      When colliding with this terrain, is a report of all collisions wanted or only the closest collision?
      If only the closest collision is required, the collision calculation will be faster.
      Note: If no collision happens, it takes as long as a collision with multipleCollisions on would take.
      Parameters:
      set - Whether to support multiple collisions or not