* Cleaned up and simplified the Terrain API.
* Removed dependence on TerrainQuad for TerrainLodControl * Comments, general cleanup git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7783 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
7cb3ca4712
commit
70f1a6f323
@ -34,7 +34,6 @@ package com.jme3.terrain;
|
|||||||
import com.jme3.material.Material;
|
import com.jme3.material.Material;
|
||||||
import com.jme3.math.Vector2f;
|
import com.jme3.math.Vector2f;
|
||||||
import com.jme3.math.Vector3f;
|
import com.jme3.math.Vector3f;
|
||||||
import com.jme3.scene.Spatial;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -108,19 +107,6 @@ public interface Terrain {
|
|||||||
*/
|
*/
|
||||||
public float[] getHeightMap();
|
public float[] getHeightMap();
|
||||||
|
|
||||||
/**
|
|
||||||
* Tell the terrain system to use/not use Level of Detail algorithms.
|
|
||||||
* This is allowed to be ignored if a particular implementation cannot support it.
|
|
||||||
*/
|
|
||||||
public void useLOD(boolean useLod);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the terrain is using LOD techniques.
|
|
||||||
* If a terrain system only supports enabled LOD, then this
|
|
||||||
* should always return true.
|
|
||||||
*/
|
|
||||||
public boolean isUsingLOD();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is calculated by the specific LOD algorithm.
|
* This is calculated by the specific LOD algorithm.
|
||||||
* A value of one means that the terrain is showing full detail.
|
* A value of one means that the terrain is showing full detail.
|
||||||
@ -130,24 +116,19 @@ public interface Terrain {
|
|||||||
public int getMaxLod();
|
public int getMaxLod();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called in the update (pre or post, up to you) method of your game.
|
* Called by an LodControl.
|
||||||
* Calculates the level of detail of the terrain and adjusts its geometry.
|
* Calculates the level of detail of the terrain and adjusts its geometry.
|
||||||
* This is where the Terrain's LOD algorithm will change the detail of
|
* This is where the Terrain's LOD algorithm will change the detail of
|
||||||
* the terrain based on how far away this position is from the particular
|
* the terrain based on how far away this position is from the particular
|
||||||
* terrain patch.
|
* terrain patch.
|
||||||
* @param location often the Camera's location
|
* @param location: the Camera's location. A list of one camera location is normal
|
||||||
|
* if you just have one camera in your scene.
|
||||||
*/
|
*/
|
||||||
public void update(List<Vector3f> location);
|
public void update(List<Vector3f> location);
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the spatial instance of this Terrain. Right now just used in the
|
|
||||||
* terrain editor in JMP.
|
|
||||||
*/
|
|
||||||
public Spatial getSpatial();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lock or unlock the meshes of this terrain.
|
* Lock or unlock the meshes of this terrain.
|
||||||
* Locked meshes are uneditable but have better performance.
|
* Locked meshes are un-editable but have better performance.
|
||||||
* This should call the underlying getMesh().setStatic()/setDynamic() methods.
|
* This should call the underlying getMesh().setStatic()/setDynamic() methods.
|
||||||
* @param locked or unlocked
|
* @param locked or unlocked
|
||||||
*/
|
*/
|
||||||
@ -169,17 +150,15 @@ public interface Terrain {
|
|||||||
public Material getMaterial();
|
public Material getMaterial();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the percentage along the terrain (in X-Z plane) that the
|
* Used for painting to get the number of vertices along the edge of the
|
||||||
* supplied point (worldX,worldY) is, starting from the x=0, z=0 world
|
* terrain.
|
||||||
* position of the terrain.
|
* This is an un-scaled size, and should represent the vertex count (ie. the
|
||||||
* This method must take into account local translations and scale of the terrain.
|
* texture coord count) along an edge of a square terrain.
|
||||||
* Used for painting onto an alpha image for texture splatting.
|
|
||||||
*
|
*
|
||||||
* @param worldX world position on X axis
|
* In the standard TerrainQuad default implementation, this will return
|
||||||
* @param worldY world position on Z axis
|
* the "totalSize" of the terrain (512 or so).
|
||||||
* @return a point (U,V in the range [0,1] )
|
|
||||||
*/
|
*/
|
||||||
public Vector2f getPointPercentagePosition(float worldX, float worldY);
|
public int getTerrainSize();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the scale of the texture coordinates. Normally if the texture is
|
* Get the scale of the texture coordinates. Normally if the texture is
|
||||||
|
@ -41,6 +41,7 @@ import java.util.List;
|
|||||||
import com.jme3.renderer.Camera;
|
import com.jme3.renderer.Camera;
|
||||||
import com.jme3.renderer.RenderManager;
|
import com.jme3.renderer.RenderManager;
|
||||||
import com.jme3.renderer.ViewPort;
|
import com.jme3.renderer.ViewPort;
|
||||||
|
import com.jme3.scene.Node;
|
||||||
import com.jme3.scene.Spatial;
|
import com.jme3.scene.Spatial;
|
||||||
import com.jme3.scene.control.AbstractControl;
|
import com.jme3.scene.control.AbstractControl;
|
||||||
import com.jme3.scene.control.Control;
|
import com.jme3.scene.control.Control;
|
||||||
@ -61,22 +62,27 @@ import java.util.ArrayList;
|
|||||||
*/
|
*/
|
||||||
public class TerrainLodControl extends AbstractControl {
|
public class TerrainLodControl extends AbstractControl {
|
||||||
|
|
||||||
private TerrainQuad terrain;
|
private Terrain terrain;
|
||||||
private List<Camera> cameras;
|
private List<Camera> cameras;
|
||||||
private List<Vector3f> cameraLocations = new ArrayList<Vector3f>();
|
private List<Vector3f> cameraLocations = new ArrayList<Vector3f>();
|
||||||
|
|
||||||
public TerrainLodControl() {
|
public TerrainLodControl() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TerrainLodControl(Terrain terrain, Camera camera) {
|
||||||
|
List<Camera> cams = new ArrayList<Camera>();
|
||||||
|
cams.add(camera);
|
||||||
|
this.terrain = terrain;
|
||||||
|
this.cameras = cams;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Only uses the first camera right now.
|
* Only uses the first camera right now.
|
||||||
* @param terrain to act upon (must be a Spatial)
|
* @param terrain to act upon (must be a Spatial)
|
||||||
* @param cameras one or more cameras to reference for LOD calc
|
* @param cameras one or more cameras to reference for LOD calc
|
||||||
*/
|
*/
|
||||||
public TerrainLodControl(Terrain terrain, List<Camera> cameras) {
|
public TerrainLodControl(Terrain terrain, List<Camera> cameras) {
|
||||||
if (terrain instanceof TerrainQuad) {
|
this.terrain = terrain;
|
||||||
this.terrain = (TerrainQuad) terrain;
|
|
||||||
}
|
|
||||||
this.cameras = cameras;
|
this.cameras = cameras;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,11 +113,17 @@ public class TerrainLodControl extends AbstractControl {
|
|||||||
cameraClone.add(c);
|
cameraClone.add(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new TerrainLodControl((TerrainQuad) spatial, cameraClone);
|
return new TerrainLodControl((Terrain) spatial, cameraClone);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setCamera(Camera camera) {
|
||||||
|
List<Camera> cams = new ArrayList<Camera>();
|
||||||
|
cams.add(camera);
|
||||||
|
setCameras(cams);
|
||||||
|
}
|
||||||
|
|
||||||
public void setCameras(List<Camera> cameras) {
|
public void setCameras(List<Camera> cameras) {
|
||||||
this.cameras = cameras;
|
this.cameras = cameras;
|
||||||
cameraLocations.clear();
|
cameraLocations.clear();
|
||||||
@ -123,12 +135,12 @@ public class TerrainLodControl extends AbstractControl {
|
|||||||
@Override
|
@Override
|
||||||
public void setSpatial(Spatial spatial) {
|
public void setSpatial(Spatial spatial) {
|
||||||
super.setSpatial(spatial);
|
super.setSpatial(spatial);
|
||||||
if (spatial instanceof TerrainQuad) {
|
if (spatial instanceof Terrain) {
|
||||||
this.terrain = (TerrainQuad) spatial;
|
this.terrain = (Terrain) spatial;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTerrain(TerrainQuad terrain) {
|
public void setTerrain(Terrain terrain) {
|
||||||
this.terrain = terrain;
|
this.terrain = terrain;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,13 +148,13 @@ public class TerrainLodControl extends AbstractControl {
|
|||||||
public void write(JmeExporter ex) throws IOException {
|
public void write(JmeExporter ex) throws IOException {
|
||||||
super.write(ex);
|
super.write(ex);
|
||||||
OutputCapsule oc = ex.getCapsule(this);
|
OutputCapsule oc = ex.getCapsule(this);
|
||||||
oc.write(terrain, "terrain", null);
|
oc.write((Node)terrain, "terrain", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(JmeImporter im) throws IOException {
|
public void read(JmeImporter im) throws IOException {
|
||||||
super.read(im);
|
super.read(im);
|
||||||
InputCapsule ic = im.getCapsule(this);
|
InputCapsule ic = im.getCapsule(this);
|
||||||
terrain = (TerrainQuad) ic.readSavable("terrain", null);
|
terrain = (Terrain) ic.readSavable("terrain", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,6 @@ import com.jme3.util.TangentBinormalGenerator;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A terrain quad is a node in the quad tree of the terrain system.
|
* A terrain quad is a node in the quad tree of the terrain system.
|
||||||
@ -99,7 +98,6 @@ 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 boolean usingLOD = true;
|
|
||||||
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();
|
||||||
@ -274,10 +272,6 @@ public class TerrainQuad extends Node implements Terrain {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Spatial getSpatial() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void generateEntropy(ProgressMonitor progressMonitor) {
|
public void generateEntropy(ProgressMonitor progressMonitor) {
|
||||||
// only check this on the root quad
|
// only check this on the root quad
|
||||||
if (isRootQuad())
|
if (isRootQuad())
|
||||||
@ -383,12 +377,11 @@ public class TerrainQuad extends Node implements Terrain {
|
|||||||
*/
|
*/
|
||||||
private void updateQuadLODs() {
|
private void updateQuadLODs() {
|
||||||
synchronized (updatePatchesLock) {
|
synchronized (updatePatchesLock) {
|
||||||
//if (true)
|
|
||||||
// return;
|
|
||||||
if (updatedPatches == null || updatedPatches.isEmpty())
|
if (updatedPatches == null || updatedPatches.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//TODO do the actual geometry update here
|
// do the actual geometry update here
|
||||||
for (UpdatedTerrainPatch utp : updatedPatches.values()) {
|
for (UpdatedTerrainPatch utp : updatedPatches.values()) {
|
||||||
utp.updateAll();
|
utp.updateAll();
|
||||||
}
|
}
|
||||||
@ -1104,13 +1097,9 @@ public class TerrainQuad extends Node implements Terrain {
|
|||||||
return (x >= 0 && x <= totalSize && z >= 0 && z <= totalSize);
|
return (x >= 0 && x <= totalSize && z >= 0 && z <= totalSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector2f getPointPercentagePosition(float worldX, float worldY) {
|
|
||||||
Vector2f uv = new Vector2f(worldX,worldY);
|
|
||||||
uv.subtractLocal(getLocalTranslation().x, getLocalTranslation().z); // center it on 0,0
|
|
||||||
uv.addLocal(totalSize/2, totalSize/2); // shift the bottom left corner up to 0,0
|
|
||||||
uv.divideLocal(totalSize); // get the location as a percentage
|
|
||||||
|
|
||||||
return uv;
|
public int getTerrainSize() {
|
||||||
|
return totalSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1510,10 +1499,6 @@ public class TerrainQuad extends Node implements Terrain {
|
|||||||
quadrant = c.readInt("quadrant", 0);
|
quadrant = c.readInt("quadrant", 0);
|
||||||
totalSize = c.readInt("totalSize", 0);
|
totalSize = c.readInt("totalSize", 0);
|
||||||
lodCalculatorFactory = (LodCalculatorFactory) c.readSavable("lodCalculatorFactory", null);
|
lodCalculatorFactory = (LodCalculatorFactory) c.readSavable("lodCalculatorFactory", null);
|
||||||
|
|
||||||
// the terrain is re-built on load, so we need to run this once
|
|
||||||
//affectedAreaBBox = new BoundingBox(new Vector3f(0,0,0), size, Float.MAX_VALUE, size);
|
|
||||||
//updateNormals();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1564,14 +1549,6 @@ public class TerrainQuad extends Node implements Terrain {
|
|||||||
return maxLod;
|
return maxLod;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void useLOD(boolean useLod) {
|
|
||||||
usingLOD = useLod;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isUsingLOD() {
|
|
||||||
return usingLOD;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPatchSize() {
|
public int getPatchSize() {
|
||||||
return patchSize;
|
return patchSize;
|
||||||
}
|
}
|
||||||
@ -1583,9 +1560,6 @@ public class TerrainQuad extends Node implements Terrain {
|
|||||||
|
|
||||||
public float[] getHeightMap() {
|
public float[] getHeightMap() {
|
||||||
|
|
||||||
//if (true)
|
|
||||||
// return heightMap;
|
|
||||||
|
|
||||||
float[] hm = null;
|
float[] hm = null;
|
||||||
int length = ((size-1)/2)+1;
|
int length = ((size-1)/2)+1;
|
||||||
int area = size*size;
|
int area = size*size;
|
||||||
|
@ -33,6 +33,7 @@ package jme3test.terrain;
|
|||||||
|
|
||||||
import com.jme3.app.SimpleApplication;
|
import com.jme3.app.SimpleApplication;
|
||||||
import com.jme3.bounding.BoundingBox;
|
import com.jme3.bounding.BoundingBox;
|
||||||
|
import com.jme3.export.Savable;
|
||||||
import com.jme3.export.binary.BinaryExporter;
|
import com.jme3.export.binary.BinaryExporter;
|
||||||
import com.jme3.export.binary.BinaryImporter;
|
import com.jme3.export.binary.BinaryImporter;
|
||||||
import com.jme3.font.BitmapText;
|
import com.jme3.font.BitmapText;
|
||||||
@ -44,6 +45,8 @@ import com.jme3.material.Material;
|
|||||||
import com.jme3.math.ColorRGBA;
|
import com.jme3.math.ColorRGBA;
|
||||||
import com.jme3.math.Vector3f;
|
import com.jme3.math.Vector3f;
|
||||||
import com.jme3.renderer.Camera;
|
import com.jme3.renderer.Camera;
|
||||||
|
import com.jme3.scene.Node;
|
||||||
|
import com.jme3.terrain.Terrain;
|
||||||
import com.jme3.terrain.geomipmap.TerrainLodControl;
|
import com.jme3.terrain.geomipmap.TerrainLodControl;
|
||||||
import com.jme3.terrain.geomipmap.TerrainQuad;
|
import com.jme3.terrain.geomipmap.TerrainQuad;
|
||||||
import com.jme3.terrain.heightmap.AbstractHeightMap;
|
import com.jme3.terrain.heightmap.AbstractHeightMap;
|
||||||
@ -69,7 +72,7 @@ import jme3tools.converters.ImageToAwt;
|
|||||||
*/
|
*/
|
||||||
public class TerrainTestReadWrite extends SimpleApplication {
|
public class TerrainTestReadWrite extends SimpleApplication {
|
||||||
|
|
||||||
private TerrainQuad terrain;
|
private Terrain terrain;
|
||||||
protected BitmapText hintText;
|
protected BitmapText hintText;
|
||||||
private float grassScale = 64;
|
private float grassScale = 64;
|
||||||
private float dirtScale = 16;
|
private float dirtScale = 16;
|
||||||
@ -147,8 +150,6 @@ public class TerrainTestReadWrite extends SimpleApplication {
|
|||||||
// CREATE HEIGHTMAP
|
// CREATE HEIGHTMAP
|
||||||
AbstractHeightMap heightmap = null;
|
AbstractHeightMap heightmap = null;
|
||||||
try {
|
try {
|
||||||
//heightmap = new HillHeightMap(1025, 1000, 50, 100, (byte) 3);
|
|
||||||
|
|
||||||
heightmap = new ImageBasedHeightMap(ImageToAwt.convert(heightMapImage.getImage(), false, true, 0), 1f);
|
heightmap = new ImageBasedHeightMap(ImageToAwt.convert(heightMapImage.getImage(), false, true, 0), 1f);
|
||||||
heightmap.load();
|
heightmap.load();
|
||||||
|
|
||||||
@ -160,15 +161,17 @@ public class TerrainTestReadWrite extends SimpleApplication {
|
|||||||
loadTerrain();
|
loadTerrain();
|
||||||
} else {
|
} else {
|
||||||
// create the terrain as normal, and give it a control for LOD management
|
// create the terrain as normal, and give it a control for LOD management
|
||||||
terrain = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap());//, new LodPerspectiveCalculatorFactory(getCamera(), 4)); // add this in to see it use entropy for LOD calculations
|
TerrainQuad terrainQuad = new TerrainQuad("terrain", 65, 129, heightmap.getHeightMap());//, new LodPerspectiveCalculatorFactory(getCamera(), 4)); // add this in to see it use entropy for LOD calculations
|
||||||
List<Camera> cameras = new ArrayList<Camera>();
|
List<Camera> cameras = new ArrayList<Camera>();
|
||||||
cameras.add(getCamera());
|
cameras.add(getCamera());
|
||||||
TerrainLodControl control = new TerrainLodControl(terrain, cameras);
|
TerrainLodControl control = new TerrainLodControl(terrainQuad, cameras);
|
||||||
terrain.addControl(control);
|
terrainQuad.addControl(control);
|
||||||
terrain.setMaterial(matTerrain);
|
terrainQuad.setMaterial(matTerrain);
|
||||||
terrain.setLocalTranslation(0, -100, 0);
|
terrainQuad.setLocalTranslation(0, -100, 0);
|
||||||
terrain.setLocalScale(2f, 1f, 2f);
|
terrainQuad.setLocalScale(4f, 0.25f, 4f);
|
||||||
rootNode.attachChild(terrain);
|
rootNode.attachChild(terrainQuad);
|
||||||
|
|
||||||
|
this.terrain = terrainQuad;
|
||||||
}
|
}
|
||||||
|
|
||||||
DirectionalLight light = new DirectionalLight();
|
DirectionalLight light = new DirectionalLight();
|
||||||
@ -211,7 +214,7 @@ public class TerrainTestReadWrite extends SimpleApplication {
|
|||||||
fos = new FileOutputStream(new File("terrainsave.jme"));
|
fos = new FileOutputStream(new File("terrainsave.jme"));
|
||||||
|
|
||||||
// we just use the exporter and pass in the terrain
|
// we just use the exporter and pass in the terrain
|
||||||
BinaryExporter.getInstance().save(terrain, new BufferedOutputStream(fos));
|
BinaryExporter.getInstance().save((Savable)terrain, new BufferedOutputStream(fos));
|
||||||
|
|
||||||
fos.flush();
|
fos.flush();
|
||||||
float duration = (System.currentTimeMillis() - start) / 1000.0f;
|
float duration = (System.currentTimeMillis() - start) / 1000.0f;
|
||||||
@ -237,29 +240,28 @@ public class TerrainTestReadWrite extends SimpleApplication {
|
|||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
// remove the existing terrain and detach it from the root node.
|
// remove the existing terrain and detach it from the root node.
|
||||||
if (terrain != null) {
|
if (terrain != null) {
|
||||||
terrain.removeFromParent();
|
Node existingTerrain = (Node)terrain;
|
||||||
terrain.removeControl(TerrainLodControl.class);
|
existingTerrain.removeFromParent();
|
||||||
terrain.detachAllChildren();
|
existingTerrain.removeControl(TerrainLodControl.class);
|
||||||
|
existingTerrain.detachAllChildren();
|
||||||
terrain = null;
|
terrain = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// import the saved terrain, and attach it back to the root node
|
// import the saved terrain, and attach it back to the root node
|
||||||
fis = new FileInputStream(new File("terrainsave.jme"));
|
File f = new File("terrainsave.jme");
|
||||||
|
fis = new FileInputStream(f);
|
||||||
BinaryImporter imp = BinaryImporter.getInstance();
|
BinaryImporter imp = BinaryImporter.getInstance();
|
||||||
imp.setAssetManager(assetManager);
|
imp.setAssetManager(assetManager);
|
||||||
terrain = (TerrainQuad) imp.load(new BufferedInputStream(fis));
|
terrain = (TerrainQuad) imp.load(new BufferedInputStream(fis));
|
||||||
rootNode.attachChild(terrain);
|
rootNode.attachChild((Node)terrain);
|
||||||
|
|
||||||
float duration = (System.currentTimeMillis() - start) / 1000.0f;
|
float duration = (System.currentTimeMillis() - start) / 1000.0f;
|
||||||
System.out.println("Load took " + duration + " seconds");
|
System.out.println("Load took " + duration + " seconds");
|
||||||
|
|
||||||
// now we have to add back the cameras to the LOD control, since we didn't want to duplicate them on save
|
// now we have to add back the camera to the LOD control
|
||||||
List<Camera> cameras = new ArrayList<Camera>();
|
TerrainLodControl lodControl = ((Node)terrain).getControl(TerrainLodControl.class);
|
||||||
cameras.add(getCamera());
|
if (lodControl != null)
|
||||||
TerrainLodControl lodControl = terrain.getControl(TerrainLodControl.class);
|
lodControl.setCamera(getCamera());
|
||||||
if (lodControl != null) {
|
|
||||||
lodControl.setCameras(cameras);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
Logger.getLogger(TerrainTestReadWrite.class.getName()).log(Level.SEVERE, null, ex);
|
Logger.getLogger(TerrainTestReadWrite.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
@ -286,10 +288,10 @@ public class TerrainTestReadWrite extends SimpleApplication {
|
|||||||
public void onAction(String name, boolean pressed, float tpf) {
|
public void onAction(String name, boolean pressed, float tpf) {
|
||||||
if (name.equals("clone") && !pressed) {
|
if (name.equals("clone") && !pressed) {
|
||||||
|
|
||||||
TerrainQuad clone = terrain.clone();
|
Terrain clone = (Terrain) ((Node)terrain).clone();
|
||||||
terrain.removeFromParent();
|
((Node)terrain).removeFromParent();
|
||||||
terrain = clone;
|
terrain = clone;
|
||||||
getRootNode().attachChild(terrain);
|
getRootNode().attachChild((Node)terrain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user