* fixed lod bug in TerrainGrid
* flipped the grid orientation to match the Quad's orientation * removed blocking call to loading thread git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7833 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
feef9dc6d5
commit
1a08b7b0f6
@ -1,9 +1,38 @@
|
|||||||
/*
|
/*
|
||||||
* To change this template, choose Tools | Templates
|
* Copyright (c) 2009-2010 jMonkeyEngine
|
||||||
* and open the template in the editor.
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
package com.jme3.terrain.geomipmap;
|
package com.jme3.terrain.geomipmap;
|
||||||
|
|
||||||
|
import com.jme3.scene.control.UpdateControl;
|
||||||
|
import com.jme3.app.Application;
|
||||||
import com.jme3.bullet.PhysicsSpace;
|
import com.jme3.bullet.PhysicsSpace;
|
||||||
import com.jme3.bullet.collision.shapes.HeightfieldCollisionShape;
|
import com.jme3.bullet.collision.shapes.HeightfieldCollisionShape;
|
||||||
import com.jme3.bullet.control.RigidBodyControl;
|
import com.jme3.bullet.control.RigidBodyControl;
|
||||||
@ -19,10 +48,11 @@ import com.jme3.material.Material;
|
|||||||
import com.jme3.math.FastMath;
|
import com.jme3.math.FastMath;
|
||||||
import com.jme3.math.Vector2f;
|
import com.jme3.math.Vector2f;
|
||||||
import com.jme3.math.Vector3f;
|
import com.jme3.math.Vector3f;
|
||||||
|
import com.jme3.renderer.Camera;
|
||||||
import com.jme3.terrain.geomipmap.lodcalc.LodCalculatorFactory;
|
import com.jme3.terrain.geomipmap.lodcalc.LodCalculatorFactory;
|
||||||
import com.jme3.terrain.geomipmap.lodcalc.LodDistanceCalculatorFactory;
|
import com.jme3.terrain.geomipmap.lodcalc.LodDistanceCalculatorFactory;
|
||||||
import com.jme3.terrain.heightmap.HeightMapGrid;
|
import com.jme3.terrain.heightmap.HeightMapGrid;
|
||||||
import com.jme3.terrain.heightmap.RawHeightMap;
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Anthyon
|
* @author Anthyon
|
||||||
@ -34,7 +64,7 @@ public class TerrainGrid extends TerrainQuad {
|
|||||||
private int quarterSize;
|
private int quarterSize;
|
||||||
private int quadSize;
|
private int quadSize;
|
||||||
private HeightMapGrid heightMapGrid;
|
private HeightMapGrid heightMapGrid;
|
||||||
private Vector3f[] quadOrigins;
|
//private Vector3f[] quadOrigins;
|
||||||
private Vector3f[] quadIndex;
|
private Vector3f[] quadIndex;
|
||||||
private Map<String, TerrainGridListener> listeners = new HashMap<String, TerrainGridListener>();
|
private Map<String, TerrainGridListener> listeners = new HashMap<String, TerrainGridListener>();
|
||||||
private Material material;
|
private Material material;
|
||||||
@ -45,31 +75,42 @@ public class TerrainGrid extends TerrainQuad {
|
|||||||
private class UpdateQuadCache implements Runnable {
|
private class UpdateQuadCache implements Runnable {
|
||||||
|
|
||||||
private final Vector3f location;
|
private final Vector3f location;
|
||||||
private final boolean centerOnly;
|
|
||||||
|
|
||||||
public UpdateQuadCache(Vector3f location) {
|
public UpdateQuadCache(Vector3f location) {
|
||||||
this.location = location;
|
this.location = location;
|
||||||
this.centerOnly = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UpdateQuadCache(Vector3f location, boolean centerOnly) {
|
|
||||||
this.location = location;
|
|
||||||
this.centerOnly = centerOnly;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
for (int i = centerOnly ? 1 : 0; i < (centerOnly ? 3 : 4); i++) {
|
|
||||||
for (int j = centerOnly ? 1 : 0; j < (centerOnly ? 3 : 4); j++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
Vector3f temp = location.add(quadIndex[i * 4 + j]);
|
for (int j = 0; j < 4; j++) {
|
||||||
if (cache.get(temp) == null) {
|
int quadIdx = i * 4 + j;
|
||||||
|
final Vector3f temp = location.add(quadIndex[quadIdx]);
|
||||||
|
TerrainQuad q = cache.get(temp);
|
||||||
|
if (q == null) {
|
||||||
|
// create the new Quad since it doesn't exist
|
||||||
HeightMap heightMapAt = heightMapGrid.getHeightMapAt(temp);
|
HeightMap heightMapAt = heightMapGrid.getHeightMapAt(temp);
|
||||||
TerrainQuad q = new TerrainQuad(getName() + "Quad" + temp, patchSize, quadSize, heightMapAt == null ? null : heightMapAt.getHeightMap(), lodCalculatorFactory);
|
q = new TerrainQuad(getName() + "Quad" + temp, patchSize, quadSize, totalSize, heightMapAt == null ? null : heightMapAt.getHeightMap(), lodCalculatorFactory);
|
||||||
Material mat = material.clone();
|
Material mat = material.clone();
|
||||||
for (TerrainGridListener l : listeners.values()) {
|
for (TerrainGridListener l : listeners.values()) {
|
||||||
mat = l.tileLoaded(mat, temp);
|
mat = l.tileLoaded(mat, temp);
|
||||||
}
|
}
|
||||||
q.setMaterial(mat);
|
q.setMaterial(mat);
|
||||||
|
log.log(Level.FINE, "Loaded TerrainQuad {0}", q.getName());
|
||||||
|
}
|
||||||
cache.put(temp, q);
|
cache.put(temp, q);
|
||||||
|
|
||||||
|
if (isCenter(quadIdx)) {
|
||||||
|
// if it should be attached as a child right now, attach it
|
||||||
|
final int quadrant = getQuadrant(quadIdx);
|
||||||
|
final TerrainQuad newQuad = q;
|
||||||
|
// back on the OpenGL thread:
|
||||||
|
getControl(UpdateControl.class).enqueue(new Callable() {
|
||||||
|
public Object call() throws Exception {
|
||||||
|
attachQuadAt(newQuad, quadrant, temp);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -77,45 +118,64 @@ public class TerrainGrid extends TerrainQuad {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public TerrainGrid(String name, int patchSize, int size, Vector3f stepScale, HeightMapGrid heightMapGrid, int totalSize,
|
private boolean isCenter(int quadIndex) {
|
||||||
|
return quadIndex == 9 || quadIndex == 5 || quadIndex == 10 || quadIndex == 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getQuadrant(int quadIndex) {
|
||||||
|
if (quadIndex == 9)
|
||||||
|
return 1;
|
||||||
|
else if (quadIndex == 5)
|
||||||
|
return 2;
|
||||||
|
else if (quadIndex == 10)
|
||||||
|
return 3;
|
||||||
|
else if (quadIndex == 6)
|
||||||
|
return 4;
|
||||||
|
return 0; // error
|
||||||
|
}
|
||||||
|
|
||||||
|
public TerrainGrid(String name, int patchSize, int maxVisibleSize, Vector3f scale, HeightMapGrid heightMapGrid,
|
||||||
Vector2f offset, float offsetAmount, LodCalculatorFactory lodCalculatorFactory) {
|
Vector2f offset, float offsetAmount, LodCalculatorFactory lodCalculatorFactory) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.patchSize = patchSize;
|
this.patchSize = patchSize;
|
||||||
this.size = size;
|
this.size = maxVisibleSize;
|
||||||
this.quarterSize = size >> 2;
|
this.quarterSize = maxVisibleSize >> 2;
|
||||||
this.quadSize = (size + 1) >> 1;
|
this.quadSize = (maxVisibleSize + 1) >> 1;
|
||||||
this.stepScale = stepScale;
|
this.stepScale = scale;
|
||||||
this.heightMapGrid = heightMapGrid;
|
this.heightMapGrid = heightMapGrid;
|
||||||
heightMapGrid.setSize(this.quadSize);
|
heightMapGrid.setSize(this.quadSize);
|
||||||
this.totalSize = totalSize;
|
this.totalSize = maxVisibleSize;
|
||||||
this.offset = offset;
|
this.offset = offset;
|
||||||
this.offsetAmount = offsetAmount;
|
this.offsetAmount = offsetAmount;
|
||||||
this.lodCalculatorFactory = lodCalculatorFactory;
|
this.lodCalculatorFactory = lodCalculatorFactory;
|
||||||
if (lodCalculatorFactory == null) {
|
if (lodCalculatorFactory == null) {
|
||||||
lodCalculatorFactory = new LodDistanceCalculatorFactory();
|
lodCalculatorFactory = new LodDistanceCalculatorFactory();
|
||||||
}
|
}
|
||||||
this.quadOrigins = new Vector3f[]{new Vector3f(-this.quarterSize, 0, -this.quarterSize).mult(this.stepScale),
|
// this.quadOrigins = new Vector3f[]{
|
||||||
new Vector3f(-this.quarterSize, 0, this.quarterSize).mult(this.stepScale),
|
// new Vector3f(-this.quarterSize, 0, -this.quarterSize).mult(this.stepScale),
|
||||||
new Vector3f(this.quarterSize, 0, -this.quarterSize).mult(this.stepScale),
|
// new Vector3f(-this.quarterSize, 0, this.quarterSize).mult(this.stepScale),
|
||||||
new Vector3f(this.quarterSize, 0, this.quarterSize).mult(this.stepScale)};
|
// new Vector3f(this.quarterSize, 0, -this.quarterSize).mult(this.stepScale),
|
||||||
|
// new Vector3f(this.quarterSize, 0, this.quarterSize).mult(this.stepScale)};
|
||||||
this.quadIndex = new Vector3f[]{
|
this.quadIndex = new Vector3f[]{
|
||||||
new Vector3f(-1, 0, -1), new Vector3f(-1, 0, 0), new Vector3f(-1, 0, 1), new Vector3f(-1, 0, 2),
|
new Vector3f(-1, 0, 2), new Vector3f(0, 0, 2), new Vector3f(1, 0, 2), new Vector3f(2, 0, 2),
|
||||||
new Vector3f(0, 0, -1), new Vector3f(0, 0, 0), new Vector3f(0, 0, 1), new Vector3f(0, 0, 2),
|
new Vector3f(-1, 0, 1), new Vector3f(0, 0, 1), new Vector3f(1, 0, 1), new Vector3f(2, 0, 1),
|
||||||
new Vector3f(1, 0, -1), new Vector3f(1, 0, 0), new Vector3f(1, 0, 1), new Vector3f(1, 0, 2),
|
new Vector3f(-1, 0, 0), new Vector3f(0, 0, 0), new Vector3f(1, 0, 0), new Vector3f(2, 0, 0),
|
||||||
new Vector3f(2, 0, -1), new Vector3f(2, 0, 0), new Vector3f(2, 0, 1), new Vector3f(2, 0, 2)};
|
new Vector3f(-1, 0, -1), new Vector3f(0, 0, -1), new Vector3f(1, 0, -1), new Vector3f(-2, 0, -1)};
|
||||||
|
|
||||||
|
addControl(new UpdateControl());
|
||||||
}
|
}
|
||||||
|
|
||||||
public TerrainGrid(String name, int patchSize, int size, Vector3f scale, HeightMapGrid heightMapGrid,
|
public TerrainGrid(String name, int patchSize, int maxVisibleSize, Vector3f scale, HeightMapGrid heightMapGrid,
|
||||||
LodCalculatorFactory lodCalculatorFactory) {
|
LodCalculatorFactory lodCalculatorFactory) {
|
||||||
this(name, patchSize, size, scale, heightMapGrid, size, new Vector2f(), 0, lodCalculatorFactory);
|
this(name, patchSize, maxVisibleSize, scale, heightMapGrid, new Vector2f(), 0, lodCalculatorFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TerrainGrid(String name, int patchSize, int totalSize, HeightMapGrid heightMapGrid, LodCalculatorFactory lodCalculatorFactory) {
|
public TerrainGrid(String name, int patchSize, int maxVisibleSize, HeightMapGrid heightMapGrid, LodCalculatorFactory lodCalculatorFactory) {
|
||||||
this(name, patchSize, totalSize, Vector3f.UNIT_XYZ, heightMapGrid, lodCalculatorFactory);
|
this(name, patchSize, maxVisibleSize, Vector3f.UNIT_XYZ, heightMapGrid, lodCalculatorFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TerrainGrid(String name, int patchSize, int totalSize, HeightMapGrid heightMapGrid) {
|
public TerrainGrid(String name, int patchSize, int maxVisibleSize, HeightMapGrid heightMapGrid) {
|
||||||
this(name, patchSize, totalSize, heightMapGrid, null);
|
this(name, patchSize, maxVisibleSize, heightMapGrid, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TerrainGrid() {
|
public TerrainGrid() {
|
||||||
@ -164,13 +224,18 @@ public class TerrainGrid extends TerrainQuad {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs on the rendering thread
|
||||||
|
*/
|
||||||
protected void attachQuadAt(TerrainQuad q, int quadrant, Vector3f cam) {
|
protected void attachQuadAt(TerrainQuad q, int quadrant, Vector3f cam) {
|
||||||
|
this.removeQuad(quadrant);
|
||||||
//q.setMaterial(this.material);
|
//q.setMaterial(this.material);
|
||||||
//q.setLocalTranslation(quadOrigins[quadrant - 1]);
|
//q.setLocalTranslation(quadOrigins[quadrant - 1]);
|
||||||
q.setQuadrant((short) quadrant);
|
q.setQuadrant((short) quadrant);
|
||||||
this.attachChild(q);
|
this.attachChild(q);
|
||||||
|
|
||||||
q.setLocalTranslation(cam.mult(this.quadSize).add(quadOrigins[quadrant-1]));
|
Vector3f loc = cam.mult(this.quadSize-1).subtract(quarterSize, 0, quarterSize);// quadrant location handled TerrainQuad automatically now
|
||||||
|
q.setLocalTranslation(loc );
|
||||||
|
|
||||||
if (quadControls != null) {
|
if (quadControls != null) {
|
||||||
quadControls[quadrant - 1].setEnabled(false);
|
quadControls[quadrant - 1].setEnabled(false);
|
||||||
@ -181,6 +246,8 @@ public class TerrainGrid extends TerrainQuad {
|
|||||||
//quadControls[quadrant - 1].setPhysicsLocation(cam.add(this.quadOrigins[quadrant - 1]));
|
//quadControls[quadrant - 1].setPhysicsLocation(cam.add(this.quadOrigins[quadrant - 1]));
|
||||||
} else {
|
} else {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateModelBound();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateChildrens(Vector3f cam) {
|
private void updateChildrens(Vector3f cam) {
|
||||||
@ -203,11 +270,14 @@ public class TerrainGrid extends TerrainQuad {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TerrainQuad q1 = cache.get(cam.add(quadIndex[5]));
|
//TerrainQuad q1 = cache.get(cam.add(quadIndex[9]));
|
||||||
TerrainQuad q2 = cache.get(cam.add(quadIndex[6]));
|
//TerrainQuad q2 = cache.get(cam.add(quadIndex[5]));
|
||||||
TerrainQuad q3 = cache.get(cam.add(quadIndex[9]));
|
//TerrainQuad q3 = cache.get(cam.add(quadIndex[10]));
|
||||||
TerrainQuad q4 = cache.get(cam.add(quadIndex[10]));
|
//TerrainQuad q4 = cache.get(cam.add(quadIndex[6]));
|
||||||
|
|
||||||
|
// ---------------------------------------------------
|
||||||
|
// what does this block do?
|
||||||
|
// ---------------------------------------------------
|
||||||
int dx = 0;
|
int dx = 0;
|
||||||
int dy = 0;
|
int dy = 0;
|
||||||
if (currentCell != null) {
|
if (currentCell != null) {
|
||||||
@ -236,16 +306,21 @@ public class TerrainGrid extends TerrainQuad {
|
|||||||
cache.get(cam.add(quadIndex[i * 4 + j]));
|
cache.get(cam.add(quadIndex[i * 4 + j]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// ---------------------------------------------------
|
||||||
|
// ---------------------------------------------------
|
||||||
|
|
||||||
if (q1 == null || q2 == null || q3 == null || q4 == null) {
|
|
||||||
try {
|
|
||||||
if (executor == null)
|
if (executor == null)
|
||||||
executor = createExecutorService();
|
executor = createExecutorService();
|
||||||
executor.submit(new UpdateQuadCache(cam, true)).get();
|
|
||||||
q1 = cache.get(cam.add(quadIndex[5]));
|
executor.submit(new UpdateQuadCache(cam));
|
||||||
q2 = cache.get(cam.add(quadIndex[6]));
|
|
||||||
q3 = cache.get(cam.add(quadIndex[9]));
|
/* if (q1 == null || q2 == null || q3 == null || q4 == null) {
|
||||||
q4 = cache.get(cam.add(quadIndex[10]));
|
try {
|
||||||
|
executor.submit(new UpdateQuadCache(cam, true)).get(); // BLOCKING
|
||||||
|
q1 = cache.get(cam.add(quadIndex[9]));
|
||||||
|
q2 = cache.get(cam.add(quadIndex[5]));
|
||||||
|
q3 = cache.get(cam.add(quadIndex[10]));
|
||||||
|
q4 = cache.get(cam.add(quadIndex[6]));
|
||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
Logger.getLogger(TerrainGrid.class.getName()).log(Level.SEVERE, null, ex);
|
Logger.getLogger(TerrainGrid.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
return;
|
return;
|
||||||
@ -263,13 +338,13 @@ public class TerrainGrid extends TerrainQuad {
|
|||||||
this.removeQuad(3);
|
this.removeQuad(3);
|
||||||
this.removeQuad(4);
|
this.removeQuad(4);
|
||||||
|
|
||||||
attachQuadAt(q1, 1, cam);
|
attachQuadAt(q1, 1, cam); // quadIndex[9]
|
||||||
attachQuadAt(q2, 2, cam);
|
attachQuadAt(q2, 2, cam); // quadIndex[5]
|
||||||
attachQuadAt(q3, 3, cam);
|
attachQuadAt(q3, 3, cam); // quadIndex[10]
|
||||||
attachQuadAt(q4, 4, cam);
|
attachQuadAt(q4, 4, cam); // quadIndex[6]
|
||||||
|
*/
|
||||||
this.currentCell = cam;
|
this.currentCell = cam;
|
||||||
this.updateModelBound();
|
// this.updateModelBound();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addListener(String id, TerrainGridListener listener) {
|
public void addListener(String id, TerrainGridListener listener) {
|
||||||
@ -293,4 +368,15 @@ public class TerrainGrid extends TerrainQuad {
|
|||||||
public void setQuadSize(int quadSize) {
|
public void setQuadSize(int quadSize) {
|
||||||
this.quadSize = quadSize;
|
this.quadSize = quadSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void adjustHeight(List<Vector2f> xz, List<Float> height) {
|
||||||
|
Vector3f currentGridLocation = getCurrentCell().mult( getLocalScale() ).multLocal( quadSize-1 );
|
||||||
|
for ( Vector2f vect : xz )
|
||||||
|
{
|
||||||
|
vect.x -= currentGridLocation.x;
|
||||||
|
vect.y -= currentGridLocation.z;
|
||||||
|
}
|
||||||
|
super.adjustHeight( xz, height );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,33 @@
|
|||||||
/*
|
/*
|
||||||
* To change this template, choose Tools | Templates
|
* Copyright (c) 2009-2010 jMonkeyEngine
|
||||||
* and open the template in the editor.
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
package com.jme3.terrain.geomipmap;
|
package com.jme3.terrain.geomipmap;
|
||||||
|
|
||||||
|
@ -32,6 +32,8 @@
|
|||||||
|
|
||||||
package com.jme3.terrain.geomipmap;
|
package com.jme3.terrain.geomipmap;
|
||||||
|
|
||||||
|
import com.jme3.scene.control.UpdateControl;
|
||||||
|
import com.jme3.app.AppTask;
|
||||||
import com.jme3.material.Material;
|
import com.jme3.material.Material;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -67,6 +69,9 @@ 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.concurrent.Callable;
|
||||||
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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.
|
||||||
@ -95,7 +100,6 @@ public class TerrainQuad extends Node implements Terrain {
|
|||||||
|
|
||||||
protected LodCalculatorFactory lodCalculatorFactory;
|
protected LodCalculatorFactory lodCalculatorFactory;
|
||||||
|
|
||||||
|
|
||||||
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 int maxLod = -1;
|
private int maxLod = -1;
|
||||||
@ -130,13 +134,18 @@ public class TerrainQuad extends Node implements Terrain {
|
|||||||
this(name, patchSize, totalSize, Vector3f.UNIT_XYZ, heightMap, lodCalculatorFactory);
|
this(name, patchSize, totalSize, Vector3f.UNIT_XYZ, heightMap, lodCalculatorFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TerrainQuad(String name, int patchSize, int size, Vector3f scale, float[] heightMap, LodCalculatorFactory lodCalculatorFactory) {
|
public TerrainQuad(String name, int patchSize, int size, int totalSize, float[] heightMap, LodCalculatorFactory lodCalculatorFactory) {
|
||||||
this(name, patchSize, size, scale, heightMap, size, new Vector2f(), 0, lodCalculatorFactory);
|
this(name, patchSize, size, Vector3f.UNIT_XYZ, heightMap, totalSize, new Vector2f(), 0, lodCalculatorFactory);
|
||||||
affectedAreaBBox = new BoundingBox(new Vector3f(0,0,0), size, Float.MAX_VALUE, size);
|
affectedAreaBBox = new BoundingBox(new Vector3f(0,0,0), size, Float.MAX_VALUE, size);
|
||||||
fixNormalEdges(affectedAreaBBox);
|
fixNormalEdges(affectedAreaBBox);
|
||||||
addControl(new NormalRecalcControl(this));
|
addControl(new NormalRecalcControl(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TerrainQuad(String name, int patchSize, int size, Vector3f scale, float[] heightMap, LodCalculatorFactory lodCalculatorFactory) {
|
||||||
|
this(name, patchSize, size, scale, heightMap, size, new Vector2f(), 0, lodCalculatorFactory);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
protected TerrainQuad(String name, int patchSize, int size,
|
protected TerrainQuad(String name, int patchSize, int size,
|
||||||
Vector3f scale, float[] heightMap, int totalSize,
|
Vector3f scale, float[] heightMap, int totalSize,
|
||||||
Vector2f offset, float offsetAmount,
|
Vector2f offset, float offsetAmount,
|
||||||
@ -1580,7 +1589,7 @@ public class TerrainQuad extends Node implements Terrain {
|
|||||||
int area = size*size;
|
int area = size*size;
|
||||||
hm = new float[area];
|
hm = new float[area];
|
||||||
|
|
||||||
if (getChildren() != null) {
|
if (getChildren() != null && !getChildren().isEmpty()) {
|
||||||
float[] ul=null, ur=null, bl=null, br=null;
|
float[] ul=null, ur=null, bl=null, br=null;
|
||||||
// get the child heightmaps
|
// get the child heightmaps
|
||||||
if (getChild(0) instanceof TerrainPatch) {
|
if (getChild(0) instanceof TerrainPatch) {
|
||||||
|
@ -1,3 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2010 jMonkeyEngine
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
package com.jme3.terrain.heightmap;
|
package com.jme3.terrain.heightmap;
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
|
@ -1,6 +1,33 @@
|
|||||||
/*
|
/*
|
||||||
* To change this template, choose Tools | Templates
|
* Copyright (c) 2009-2010 jMonkeyEngine
|
||||||
* and open the template in the editor.
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
package com.jme3.terrain.heightmap;
|
package com.jme3.terrain.heightmap;
|
||||||
|
|
||||||
|
@ -19,10 +19,7 @@ import com.jme3.math.Vector3f;
|
|||||||
import com.jme3.renderer.Camera;
|
import com.jme3.renderer.Camera;
|
||||||
import com.jme3.terrain.geomipmap.TerrainGrid;
|
import com.jme3.terrain.geomipmap.TerrainGrid;
|
||||||
import com.jme3.terrain.geomipmap.TerrainLodControl;
|
import com.jme3.terrain.geomipmap.TerrainLodControl;
|
||||||
import com.jme3.terrain.geomipmap.TerrainQuad;
|
|
||||||
import com.jme3.terrain.heightmap.FractalHeightMapGrid;
|
import com.jme3.terrain.heightmap.FractalHeightMapGrid;
|
||||||
import com.jme3.terrain.heightmap.ImageBasedHeightMapGrid;
|
|
||||||
import com.jme3.terrain.heightmap.Namer;
|
|
||||||
import com.jme3.texture.Texture;
|
import com.jme3.texture.Texture;
|
||||||
import com.jme3.texture.Texture.WrapMode;
|
import com.jme3.texture.Texture.WrapMode;
|
||||||
import org.novyon.noise.ShaderUtils;
|
import org.novyon.noise.ShaderUtils;
|
||||||
|
@ -47,12 +47,22 @@ import com.jme3.math.ColorRGBA;
|
|||||||
import com.jme3.math.Ray;
|
import com.jme3.math.Ray;
|
||||||
import com.jme3.math.Vector2f;
|
import com.jme3.math.Vector2f;
|
||||||
import com.jme3.math.Vector3f;
|
import com.jme3.math.Vector3f;
|
||||||
|
import com.jme3.terrain.geomipmap.TerrainGrid;
|
||||||
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.FractalHeightMapGrid;
|
||||||
import com.jme3.texture.Texture;
|
import com.jme3.texture.Texture;
|
||||||
import com.jme3.texture.Texture.WrapMode;
|
import com.jme3.texture.Texture.WrapMode;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import org.novyon.noise.ShaderUtils;
|
||||||
|
import org.novyon.noise.basis.FilteredBasis;
|
||||||
|
import org.novyon.noise.filter.IterativeFilter;
|
||||||
|
import org.novyon.noise.filter.OptimizedErode;
|
||||||
|
import org.novyon.noise.filter.PerturbFilter;
|
||||||
|
import org.novyon.noise.filter.SmoothFilter;
|
||||||
|
import org.novyon.noise.fractal.FractalSum;
|
||||||
|
import org.novyon.noise.modulator.NoiseModulator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -82,15 +92,15 @@ public class TerrainTestModifyHeight extends SimpleApplication {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void simpleUpdate(float tpf){
|
public void simpleUpdate(float tpf){
|
||||||
updateHintText();
|
Vector3f intersection = getWorldIntersection();
|
||||||
|
updateHintText(intersection);
|
||||||
|
|
||||||
if (raiseTerrain){
|
if (raiseTerrain){
|
||||||
Vector3f intersection = getWorldIntersection();
|
|
||||||
if (intersection != null) {
|
if (intersection != null) {
|
||||||
adjustHeight(intersection, 64, tpf * 60);
|
adjustHeight(intersection, 64, tpf * 60);
|
||||||
}
|
}
|
||||||
}else if (lowerTerrain){
|
}else if (lowerTerrain){
|
||||||
Vector3f intersection = getWorldIntersection();
|
|
||||||
if (intersection != null) {
|
if (intersection != null) {
|
||||||
adjustHeight(intersection, 64, -tpf * 60);
|
adjustHeight(intersection, 64, -tpf * 60);
|
||||||
}
|
}
|
||||||
@ -103,47 +113,13 @@ public class TerrainTestModifyHeight extends SimpleApplication {
|
|||||||
initCrossHairs();
|
initCrossHairs();
|
||||||
setupKeys();
|
setupKeys();
|
||||||
|
|
||||||
// First, we load up our textures and the heightmap texture for the terrain
|
|
||||||
|
|
||||||
// TERRAIN TEXTURE material
|
|
||||||
matTerrain = new Material(assetManager, "Common/MatDefs/Terrain/TerrainLighting.j3md");
|
|
||||||
matTerrain.setBoolean("useTriPlanarMapping", false);
|
|
||||||
matTerrain.setBoolean("WardIso", true);
|
|
||||||
|
|
||||||
// ALPHA map (for splat textures)
|
|
||||||
matTerrain.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png"));
|
|
||||||
|
|
||||||
// GRASS texture
|
|
||||||
Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg");
|
|
||||||
grass.setWrap(WrapMode.Repeat);
|
|
||||||
matTerrain.setTexture("DiffuseMap", grass);
|
|
||||||
matTerrain.setFloat("DiffuseMap_0_scale", grassScale);
|
|
||||||
|
|
||||||
// DIRT texture
|
|
||||||
Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg");
|
|
||||||
dirt.setWrap(WrapMode.Repeat);
|
|
||||||
matTerrain.setTexture("DiffuseMap_1", dirt);
|
|
||||||
matTerrain.setFloat("DiffuseMap_1_scale", dirtScale);
|
|
||||||
|
|
||||||
// ROCK texture
|
|
||||||
Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg");
|
|
||||||
rock.setWrap(WrapMode.Repeat);
|
|
||||||
matTerrain.setTexture("DiffuseMap_2", rock);
|
|
||||||
matTerrain.setFloat("DiffuseMap_2_scale", rockScale);
|
|
||||||
|
|
||||||
// WIREFRAME material
|
// WIREFRAME material
|
||||||
matWire = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
|
matWire = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
|
||||||
matWire.getAdditionalRenderState().setWireframe(true);
|
matWire.getAdditionalRenderState().setWireframe(true);
|
||||||
matWire.setColor("Color", ColorRGBA.Green);
|
matWire.setColor("Color", ColorRGBA.Green);
|
||||||
|
|
||||||
// CREATE THE TERRAIN
|
//createTerrain();
|
||||||
terrain = new TerrainQuad("terrain", 65, 513, null);
|
createTerrainGrid();
|
||||||
TerrainLodControl control = new TerrainLodControl(terrain, getCamera());
|
|
||||||
terrain.addControl(control);
|
|
||||||
terrain.setMaterial(matTerrain);
|
|
||||||
terrain.setLocalTranslation(0, -100, 0);
|
|
||||||
terrain.setLocalScale(2f, 1f, 2f);
|
|
||||||
rootNode.attachChild(terrain);
|
|
||||||
|
|
||||||
DirectionalLight light = new DirectionalLight();
|
DirectionalLight light = new DirectionalLight();
|
||||||
light.setDirection((new Vector3f(-0.5f, -1f, -0.5f)).normalize());
|
light.setDirection((new Vector3f(-0.5f, -1f, -0.5f)).normalize());
|
||||||
@ -153,7 +129,7 @@ public class TerrainTestModifyHeight extends SimpleApplication {
|
|||||||
ambLight.setColor(new ColorRGBA(1f, 1f, 0.8f, 0.2f));
|
ambLight.setColor(new ColorRGBA(1f, 1f, 0.8f, 0.2f));
|
||||||
rootNode.addLight(ambLight);
|
rootNode.addLight(ambLight);
|
||||||
|
|
||||||
cam.setLocation(new Vector3f(0, 10, -10));
|
cam.setLocation(new Vector3f(0, 256, 0));
|
||||||
cam.lookAtDirection(new Vector3f(0, -1.5f, -1).normalizeLocal(), Vector3f.UNIT_Y);
|
cam.lookAtDirection(new Vector3f(0, -1.5f, -1).normalizeLocal(), Vector3f.UNIT_Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,11 +140,14 @@ public class TerrainTestModifyHeight extends SimpleApplication {
|
|||||||
guiNode.attachChild(hintText);
|
guiNode.attachChild(hintText);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateHintText() {
|
public void updateHintText(Vector3f target) {
|
||||||
int x = (int) getCamera().getLocation().x;
|
int x = (int) getCamera().getLocation().x;
|
||||||
int y = (int) getCamera().getLocation().y;
|
int y = (int) getCamera().getLocation().y;
|
||||||
int z = (int) getCamera().getLocation().z;
|
int z = (int) getCamera().getLocation().z;
|
||||||
hintText.setText("Press left mouse button to raise terrain, press right mouse button to lower terrain. " + x + "," + y + "," + z);
|
String targetText = "";
|
||||||
|
if (target!= null)
|
||||||
|
targetText = " intersect: "+target.toString();
|
||||||
|
hintText.setText("Press left mouse button to raise terrain, press right mouse button to lower terrain. " + x + "," + y + "," + z+targetText);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void initCrossHairs() {
|
protected void initCrossHairs() {
|
||||||
@ -272,4 +251,132 @@ public class TerrainTestModifyHeight extends SimpleApplication {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void createTerrain() {
|
||||||
|
// First, we load up our textures and the heightmap texture for the terrain
|
||||||
|
|
||||||
|
// TERRAIN TEXTURE material
|
||||||
|
matTerrain = new Material(assetManager, "Common/MatDefs/Terrain/TerrainLighting.j3md");
|
||||||
|
matTerrain.setBoolean("useTriPlanarMapping", false);
|
||||||
|
matTerrain.setBoolean("WardIso", true);
|
||||||
|
|
||||||
|
// ALPHA map (for splat textures)
|
||||||
|
matTerrain.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png"));
|
||||||
|
|
||||||
|
// GRASS texture
|
||||||
|
Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg");
|
||||||
|
grass.setWrap(WrapMode.Repeat);
|
||||||
|
matTerrain.setTexture("DiffuseMap", grass);
|
||||||
|
matTerrain.setFloat("DiffuseMap_0_scale", grassScale);
|
||||||
|
|
||||||
|
// DIRT texture
|
||||||
|
Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg");
|
||||||
|
dirt.setWrap(WrapMode.Repeat);
|
||||||
|
matTerrain.setTexture("DiffuseMap_1", dirt);
|
||||||
|
matTerrain.setFloat("DiffuseMap_1_scale", dirtScale);
|
||||||
|
|
||||||
|
// ROCK texture
|
||||||
|
Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg");
|
||||||
|
rock.setWrap(WrapMode.Repeat);
|
||||||
|
matTerrain.setTexture("DiffuseMap_2", rock);
|
||||||
|
matTerrain.setFloat("DiffuseMap_2_scale", rockScale);
|
||||||
|
|
||||||
|
// CREATE THE TERRAIN
|
||||||
|
terrain = new TerrainQuad("terrain", 65, 513, null);
|
||||||
|
TerrainLodControl control = new TerrainLodControl(terrain, getCamera());
|
||||||
|
terrain.addControl(control);
|
||||||
|
terrain.setMaterial(matTerrain);
|
||||||
|
terrain.setLocalTranslation(0, -100, 0);
|
||||||
|
terrain.setLocalScale(2f, 1f, 2f);
|
||||||
|
rootNode.attachChild(terrain);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createTerrainGrid() {
|
||||||
|
|
||||||
|
// TERRAIN TEXTURE material
|
||||||
|
matTerrain = new Material(this.assetManager, "Common/MatDefs/Terrain/HeightBasedTerrain.j3md");
|
||||||
|
|
||||||
|
// Parameters to material:
|
||||||
|
// regionXColorMap: X = 1..4 the texture that should be appliad to state X
|
||||||
|
// regionX: a Vector3f containing the following information:
|
||||||
|
// regionX.x: the start height of the region
|
||||||
|
// regionX.y: the end height of the region
|
||||||
|
// regionX.z: the texture scale for the region
|
||||||
|
// it might not be the most elegant way for storing these 3 values, but it packs the data nicely :)
|
||||||
|
// slopeColorMap: the texture to be used for cliffs, and steep mountain sites
|
||||||
|
// slopeTileFactor: the texture scale for slopes
|
||||||
|
// terrainSize: the total size of the terrain (used for scaling the texture)
|
||||||
|
// GRASS texture
|
||||||
|
Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg");
|
||||||
|
grass.setWrap(WrapMode.Repeat);
|
||||||
|
matTerrain.setTexture("region1ColorMap", grass);
|
||||||
|
matTerrain.setVector3("region1", new Vector3f(88, 200, this.grassScale));
|
||||||
|
|
||||||
|
// DIRT texture
|
||||||
|
Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg");
|
||||||
|
dirt.setWrap(WrapMode.Repeat);
|
||||||
|
matTerrain.setTexture("region2ColorMap", dirt);
|
||||||
|
matTerrain.setVector3("region2", new Vector3f(0, 90, this.dirtScale));
|
||||||
|
|
||||||
|
// ROCK texture
|
||||||
|
Texture rock = assetManager.loadTexture("Textures/Terrain/Rock2/rock.jpg");
|
||||||
|
rock.setWrap(WrapMode.Repeat);
|
||||||
|
matTerrain.setTexture("region3ColorMap", rock);
|
||||||
|
matTerrain.setVector3("region3", new Vector3f(198, 260, this.rockScale));
|
||||||
|
|
||||||
|
matTerrain.setTexture("region4ColorMap", rock);
|
||||||
|
matTerrain.setVector3("region4", new Vector3f(198, 260, this.rockScale));
|
||||||
|
|
||||||
|
matTerrain.setTexture("slopeColorMap", rock);
|
||||||
|
matTerrain.setFloat("slopeTileFactor", 32);
|
||||||
|
|
||||||
|
matTerrain.setFloat("terrainSize", 513);
|
||||||
|
|
||||||
|
FractalSum base = new FractalSum();
|
||||||
|
base.setRoughness(0.7f);
|
||||||
|
base.setFrequency(1.0f);
|
||||||
|
base.setAmplitude(1.0f);
|
||||||
|
base.setLacunarity(2.12f);
|
||||||
|
base.setOctaves(8);
|
||||||
|
base.setScale(0.02125f);
|
||||||
|
base.addModulator(new NoiseModulator() {
|
||||||
|
@Override
|
||||||
|
public float value(float... in) {
|
||||||
|
return ShaderUtils.clamp(in[0] * 0.5f + 0.5f, 0, 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
FilteredBasis ground = new FilteredBasis(base);
|
||||||
|
|
||||||
|
PerturbFilter perturb = new PerturbFilter();
|
||||||
|
perturb.setMagnitude(0.119f);
|
||||||
|
|
||||||
|
OptimizedErode therm = new OptimizedErode();
|
||||||
|
therm.setRadius(5);
|
||||||
|
therm.setTalus(0.011f);
|
||||||
|
|
||||||
|
SmoothFilter smooth = new SmoothFilter();
|
||||||
|
smooth.setRadius(1);
|
||||||
|
smooth.setEffect(0.7f);
|
||||||
|
|
||||||
|
IterativeFilter iterate = new IterativeFilter();
|
||||||
|
iterate.addPreFilter(perturb);
|
||||||
|
iterate.addPostFilter(smooth);
|
||||||
|
iterate.setFilter(therm);
|
||||||
|
iterate.setIterations(1);
|
||||||
|
|
||||||
|
ground.addPreFilter(iterate);
|
||||||
|
|
||||||
|
this.terrain = new TerrainGrid("terrain", 65, 257, new FractalHeightMapGrid(ground, null, 256f));
|
||||||
|
|
||||||
|
|
||||||
|
terrain.setMaterial(matWire);
|
||||||
|
terrain.setLocalTranslation(0, 0, 0);
|
||||||
|
terrain.setLocalScale(2f, 1f, 2f);
|
||||||
|
((TerrainGrid)terrain).initialize(Vector3f.ZERO);
|
||||||
|
rootNode.attachChild(this.terrain);
|
||||||
|
|
||||||
|
TerrainLodControl control = new TerrainLodControl(this.terrain, getCamera());
|
||||||
|
this.terrain.addControl(control);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user