Class TerrainQuad
- All Implemented Interfaces:
HasLocalTransform
,CloneableSmartAsset
,Collidable
,Savable
,Terrain
,JmeCloneable
,Cloneable
- Direct Known Subclasses:
TerrainGrid
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)
-
Nested Class Summary
Nested classes/interfaces inherited from class com.jme3.scene.Spatial
Spatial.BatchHint, Spatial.CullHint, Spatial.DFSMode
-
Field Summary
Modifier and TypeFieldDescriptionprotected NeighbourFinder
protected Vector2f
protected float
protected int
protected int
protected int
protected Vector3f
protected int
Fields inherited from class com.jme3.scene.Spatial
batchHint, controls, cullHint, frustrumIntersects, key, localLights, localOverrides, localTransform, name, parent, queueBucket, queueDistance, refreshFlags, RF_BOUND, RF_CHILD_LIGHTLIST, RF_LIGHTLIST, RF_MATPARAM_OVERRIDE, RF_TRANSFORM, shadowMode, userData, worldBound, worldLights, worldOverrides, worldTransform
-
Constructor Summary
ModifierConstructorDescriptionTerrainQuad
(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 terrainTerrainQuad
(String name, int patchSize, int totalSize, int quadSize, Vector3f scale, float[] heightMap) Deprecated.TerrainQuad
(String name, int patchSize, int size, Vector3f scale, float[] heightMap) Deprecated.protected
TerrainQuad
(String name, int patchSize, int quadSize, Vector3f scale, float[] heightMap, int totalSize, Vector2f offset, float offsetAmount) -
Method Summary
Modifier and TypeMethodDescriptionvoid
adjustHeight
(Vector2f xz, float delta) Raise/lower the height in one call (instead of getHeight then setHeight).void
adjustHeight
(List<Vector2f> xz, List<Float> height) Raise/lower the height at many points.void
attachBoundChildren
(Node parent) A handy method that will attach all bounding boxes of this terrain to the node you supply.protected void
Caches the transforms (except rotation) so the LOD calculator, which runs on a separate thread, can access them safely.protected boolean
calculateLod
(List<Vector3f> location, HashMap<String, UpdatedTerrainPatch> updates, LodCalculator lodCalculator) void
Removes any cached references this terrain is holding, in particular the TerrainPatch's neighbour references.clone()
Creates a clone of the asset.clone
(boolean cloneMaterials) void
cloneFields
(Cloner cloner, Object original) Called internally by com.jme3.util.clone.Cloner.int
collideWith
(Collidable other, CollisionResults results) Check collision with another Collidable.float[]
createHeightSubBlock
(float[] heightMap, int x, int y, int side) 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 zcreateQuad
generates four new quads from this quad.protected void
createQuadPatch
(float[] heightMap) createQuadPatch
creates four child patches from this quad.protected TerrainPatch
protected TerrainQuad
protected TerrainPatch
protected TerrainQuad
protected void
findNeighboursLod
(HashMap<String, UpdatedTerrainPatch> updated) void
findPick
(Ray toTest, List<TerrainPickData> results) Gather the terrain patches that intersect the given ray (toTest).protected TerrainPatch
protected TerrainQuad
protected TerrainPatch
protected TerrainQuad
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)void
fixNormalEdges
(BoundingBox affectedArea) fix the normals on the edge of the terrain patches.void
fixNormals
(BoundingBox affectedArea) Find what terrain patches need normal recalculations and update their normals;void
void
generateEntropy
(ProgressMonitor progressMonitor) Generate the entropy values for the terrain for the "perspective" LOD calculator.void
getAllTerrainPatches
(List<TerrainPatch> holder) Retrieve all Terrain Patches from all children and store them in the 'holder' listvoid
getAllTerrainPatchesWithTranslation
(Map<TerrainPatch, Vector3f> holder, Vector3f translation) protected float
getHeight
(int x, int z, float xm, float zm) gets an interpolated value at the specified pointfloat
Get the interpolated height of the terrain at the specified point.float[]
Get the heightmap of the entire terrain.protected float
getHeightmapHeight
(int x, int z) This will just get the heightmap value at the supplied point, not an interpolated (actual) height value.float
Get the heightmap height at the specified X-Z coordinate.Returns the material that this terrain uses.getMaterial
(Vector3f worldLocation) Returns the material that this terrain uses.int
This is calculated by the specific LOD algorithm.protected Vector3f
getMeshNormal
(int x, int z) protected Vector3f
Get the normal vector for the surface of the terrain at the specified X-Z coordinate.int
protected TerrainPatch
getPatch
(int quad) int
protected TerrainQuad
getQuad
(int quad) int
int
Used for painting to get the number of vertices along the edge of the terrain.int
protected boolean
isPointOnTerrain
(int x, int z) protected boolean
protected boolean
void
read
(JmeImporter importer) void
Forces the recalculation of all normals on the terrain.protected void
reIndexPages
(HashMap<String, UpdatedTerrainPatch> updated, boolean usesVariableLod) void
Reset the cached references of neighbours.void
Set the height at the specified X-Z coordinate.void
Set the height at many points.protected void
protected void
setHeight
(List<TerrainQuad.LocationHeight> locations, boolean overrideHeight) void
setLocked
(boolean locked) lock or unlock the meshes of this terrain.protected void
This will cause all normals for this terrain quad to be recalculatedvoid
setNeighbourFinder
(NeighbourFinder neighbourFinder) protected void
setNormalRecalcNeeded
(Vector2f changedPoint) Signal if the normal vectors for the terrain need to be recalculated.protected void
Called byNode.attachChild(Spatial)
andNode.detachChild(Spatial)
- don't call directly.void
setQuadrant
(short quadrant) 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.protected void
split
(int blockSize, float[] heightMap) split
divides the heightmap data for four children.protected void
update the normals if there were any height changes recently.void
write
(JmeExporter e) 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, oldDeepClone, setLightListRefresh, setLodLevel, setMaterial, setMatParamOverrideRefresh, setModelBound, setTransformRefresh, swapChildren, updateGeometricState, updateLogicalState, updateModelBound, updateWorldBound
Methods inherited from class com.jme3.scene.Spatial
addControl, addControlAt, addLight, addMatParamOverride, breadthFirstTraversal, center, checkCulling, clearMatParamOverrides, depthFirstTraversal, forceRefresh, getBatchHint, getControl, getControl, getCullHint, getKey, getLastFrustumIntersection, getLocalBatchHint, getLocalCullHint, getLocalLightList, getLocalMatParamOverrides, getLocalQueueBucket, getLocalRotation, getLocalScale, getLocalShadowMode, getLocalToWorldMatrix, getLocalTransform, getLocalTranslation, getName, getNumControls, getParent, getQueueBucket, getShadowMode, getUserData, getUserDataKeys, getWorldBound, getWorldLightList, getWorldMatParamOverrides, getWorldRotation, getWorldScale, getWorldTransform, getWorldTranslation, hasAncestor, jmeClone, localToWorld, lookAt, matches, move, move, oldClone, removeControl, removeControl, removeFromParent, removeLight, removeMatParamOverride, rotate, rotate, rotateUpTo, runControlRender, scale, scale, setBatchHint, setBoundRefresh, setCullHint, setKey, setLastFrustumIntersection, setLocalRotation, setLocalRotation, setLocalScale, setLocalScale, setLocalScale, setLocalTransform, setLocalTranslation, setLocalTranslation, setName, setQueueBucket, setRequiresUpdates, setShadowMode, setUserData, toString, updateMatParamOverrides, updateWorldLightList, updateWorldTransforms, worldToLocal
-
Field Details
-
offset
-
totalSize
protected int totalSize -
size
protected int size -
patchSize
protected int patchSize -
stepScale
-
offsetAmount
protected float offsetAmount -
quadrant
protected int quadrant -
neighbourFinder
-
-
Constructor Details
-
TerrainQuad
public TerrainQuad() -
TerrainQuad
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 patchessize
- size of this quad, can be between totalSize and patchSizescale
-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 patchestotalSize
- 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
-
-
Method Details
-
setNeighbourFinder
-
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
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 interfaceTerrain
- Parameters:
progressMonitor
- optional
-
isRootQuad
protected boolean isRootQuad() -
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 interfaceTerrain
-
getMaterial
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 interfaceTerrain
- Parameters:
worldLocation
- the location, in world coordinates, of where we are interested in the underlying texture.
-
getNumMajorSubdivisions
public int getNumMajorSubdivisions()- Specified by:
getNumMajorSubdivisions
in interfaceTerrain
-
calculateLod
protected boolean calculateLod(List<Vector3f> location, HashMap<String, UpdatedTerrainPatch> updates, LodCalculator lodCalculator) -
findNeighboursLod
-
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
Find any neighbours that should have their edges seamed because another neighbour changed its LOD to a greater value (less detailed) -
reIndexPages
-
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 zcreateQuad
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
-
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
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
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
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 interfaceTerrain
- 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
-
getHeight
Get the interpolated height of the terrain at the specified point. -
getHeight
protected float getHeight(int x, int z, float xm, float zm) gets an interpolated value at the specified point -
getNormal
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. -
getNormal
-
setHeight
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(). -
adjustHeight
Description copied from interface:Terrain
Raise/lower the height in one call (instead of getHeight then setHeight).- Specified by:
adjustHeight
in interfaceTerrain
- Parameters:
xz
- world coordinate to adjust the terrain heightdelta
- +- value to adjust the height by
-
setHeight
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. -
adjustHeight
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 interfaceTerrain
- Parameters:
xz
- a list of coordinates where the height will be adjustedheight
- +- value to adjust the height by, that matches the xz coordinates
-
setHeight
-
setHeight
-
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 interfaceTerrain
-
setLocked
public void setLocked(boolean locked) lock or unlock the meshes of this terrain. Locked meshes are uneditable but have better performance. -
getQuadrant
public int getQuadrant() -
setQuadrant
public void setQuadrant(short quadrant) -
getPatch
-
getQuad
-
findRightPatch
-
findDownPatch
-
findTopPatch
-
findLeftPatch
-
findRightQuad
-
findDownQuad
-
findTopQuad
-
findLeftQuad
-
fixNormals
Find what terrain patches need normal recalculations and update their normals; -
fixNormalEdges
fix the normals on the edge of the terrain patches. -
collideWith
Description copied from interface:Collidable
Check collision with another Collidable.- Specified by:
collideWith
in interfaceCollidable
- Overrides:
collideWith
in classNode
- Parameters:
other
- The object to check collision againstresults
- Will contain the list ofCollisionResult
s.- Returns:
- how many collisions were found between this and other
-
findPick
Gather the terrain patches that intersect the given ray (toTest). This only tests the bounding boxes- Parameters:
toTest
-results
-
-
getAllTerrainPatches
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
- Specified by:
read
in interfaceSavable
- Overrides:
read
in classNode
- Throws:
IOException
-
write
- Specified by:
write
in interfaceSavable
- Overrides:
write
in classNode
- Throws:
IOException
-
clone
Description copied from interface:CloneableSmartAsset
Creates a clone of the asset. Please seeObject.clone()
for more info on how this method should be implemented.- Specified by:
clone
in interfaceCloneableSmartAsset
- Overrides:
clone
in classSpatial
- 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
- Overrides:
clone
in classNode
- 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
Called internally by com.jme3.util.clone.Cloner. Do not call directly.- Specified by:
cloneFields
in interfaceJmeCloneable
- Overrides:
cloneFields
in classNode
- 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
Description copied from class:Spatial
Called byNode.attachChild(Spatial)
andNode.detachChild(Spatial)
- don't call directly.setParent
sets 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. -
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 interfaceTerrain
-
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
-