* Make Geomap and LODGeomap use a float[] heightmap internally instead of FloatBuffer

* Remove normal map buffer from Geomap, not needed since its generated procedurally 
 * Optimized LODGeomap normal buffer generation to create less garbage

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8734 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
sha..rd 13 years ago
parent b192166072
commit 268a464191
  1. 207
      engine/src/terrain/com/jme3/terrain/GeoMap.java
  2. 139
      engine/src/terrain/com/jme3/terrain/geomipmap/LODGeomap.java
  3. 11
      engine/src/terrain/com/jme3/terrain/geomipmap/TerrainPatch.java
  4. 8
      engine/src/terrain/com/jme3/terrain/geomipmap/TerrainQuad.java

@ -53,38 +53,25 @@ import java.nio.IntBuffer;
*/ */
public class GeoMap implements Savable { public class GeoMap implements Savable {
protected FloatBuffer hdata; protected float[] hdata;
protected ByteBuffer ndata;
protected int width, height, maxval; protected int width, height, maxval;
public GeoMap() {} public GeoMap() {}
public GeoMap(FloatBuffer heightData, ByteBuffer normalData, int width, int height, int maxval){ public GeoMap(float[] heightData, int width, int height, int maxval){
this.hdata = heightData; this.hdata = heightData;
this.ndata = normalData;
this.width = width; this.width = width;
this.height = height; this.height = height;
this.maxval = maxval; this.maxval = maxval;
} }
public GeoMap(int width, int height, int maxval) { public float[] getHeightData(){
this(BufferUtils.createFloatBuffer(width*height), null, width,height,maxval);
}
public FloatBuffer getHeightData(){
if (!isLoaded()) if (!isLoaded())
return null; return null;
return hdata; return hdata;
} }
public ByteBuffer getNormalData(){
if (!isLoaded() || !hasNormalmap())
return null;
return ndata;
}
/** /**
* @return The maximum possible value that <code>getValue()</code> can * @return The maximum possible value that <code>getValue()</code> can
* return. Mostly depends on the source data format (byte, short, int, etc). * return. Mostly depends on the source data format (byte, short, int, etc).
@ -105,7 +92,7 @@ public class GeoMap implements Savable {
* @throws NullPointerException If isLoaded() is false * @throws NullPointerException If isLoaded() is false
*/ */
public float getValue(int x, int y) { public float getValue(int x, int y) {
return hdata.get(y*width+x); return hdata[y*width+x];
} }
/** /**
@ -120,50 +107,9 @@ public class GeoMap implements Savable {
* @throws NullPointerException If isLoaded() is false * @throws NullPointerException If isLoaded() is false
*/ */
public float getValue(int i) { public float getValue(int i) {
return hdata.get(i); return hdata[i];
} }
/**
* Returns the normal at a point
*
* If store is null, then a new vector is returned,
* otherwise, the result is stored in the provided vector
* and then returned from this method
*
* @param x the X coordinate
* @param y the Y coordinate
* @param store A preallocated vector for storing the normal data, optional
* @returns store, or a new vector with the normal data if store is null
*
* @throws NullPointerException If isLoaded() or hasNormalmap() is false
*/
public Vector3f getNormal(int x, int y, Vector3f store) {
return getNormal(y*width+x,store);
}
/**
* Returns the normal at an index
*
* If store is null, then a new vector is returned,
* otherwise, the result is stored in the provided vector
* and then returned from this method
*
* See getHeight(int) for information about index lookup
*
* @param i the index
* @param store A preallocated vector for storing the normal data, optional
* @returns store, or a new vector with the normal data if store is null
*
* @throws NullPointerException If isLoaded() or hasNormalmap() is false
*/
public Vector3f getNormal(int i, Vector3f store) {
ndata.position( i*3 );
if (store==null) store = new Vector3f();
store.setX( (((float)(ndata.get() & 0xFF)/255f)-0.5f)*2f );
store.setY( (((float)(ndata.get() & 0xFF)/255f)-0.5f)*2f );
store.setZ( (((float)(ndata.get() & 0xFF)/255f)-0.5f)*2f );
return store;
}
/** /**
* Returns the width of this Geomap * Returns the width of this Geomap
@ -183,43 +129,6 @@ public class GeoMap implements Savable {
return height; return height;
} }
/**
* Copies a section of this geomap as a new geomap
*/
public GeoMap copySubGeomap(int x, int y, int w, int h){
FloatBuffer nhdata = BufferUtils.createFloatBuffer(w * h);
hdata.position(y*width+x);
for (int cy = 0; cy < height; cy++){
hdata.limit(hdata.position()+w);
nhdata.put(hdata);
hdata.limit(hdata.capacity());
hdata.position(hdata.position()+width);
}
nhdata.flip();
ByteBuffer nndata = null;
if (ndata!=null){
nndata = BufferUtils.createByteBuffer(w*h*3);
ndata.position( (y*width+x)*3 );
for (int cy = 0; cy < height; cy++){
ndata.limit(ndata.position()+w*3);
nndata.put(ndata);
ndata.limit(ndata.capacity());
ndata.position(ndata.position()+width*3);
}
nndata.flip();
}
return new GeoMap(nhdata,nndata,w,h,maxval);
}
/**
* Returns true if this Geomap has a normalmap associated with it
*/
public boolean hasNormalmap() {
return ndata != null;
}
/** /**
* Returns true if the Geomap data is loaded in memory * Returns true if the Geomap data is loaded in memory
* If false, then the data is unavailable- must be loaded with load() * If false, then the data is unavailable- must be loaded with load()
@ -251,64 +160,54 @@ public class GeoMap implements Savable {
} }
store.rewind(); store.rewind();
if (!hasNormalmap()){ Vector3f oppositePoint = new Vector3f();
Vector3f oppositePoint = new Vector3f(); Vector3f adjacentPoint = new Vector3f();
Vector3f adjacentPoint = new Vector3f(); Vector3f rootPoint = new Vector3f();
Vector3f rootPoint = new Vector3f(); Vector3f tempNorm = new Vector3f();
Vector3f tempNorm = new Vector3f(); int normalIndex = 0;
int normalIndex = 0;
for (int y = 0; y < getHeight(); y++) {
for (int y = 0; y < getHeight(); y++) { for (int x = 0; x < getWidth(); x++) {
for (int x = 0; x < getWidth(); x++) { rootPoint.set(x, getValue(x,y), y);
rootPoint.set(x, getValue(x,y), y); if (y == getHeight() - 1) {
if (y == getHeight() - 1) { if (x == getWidth() - 1) { // case #4 : last row, last col
if (x == getWidth() - 1) { // case #4 : last row, last col // left cross up
// left cross up
// adj = normalIndex - getWidth(); // adj = normalIndex - getWidth();
// opp = normalIndex - 1; // opp = normalIndex - 1;
adjacentPoint.set(x, getValue(x,y-1), y-1); adjacentPoint.set(x, getValue(x,y-1), y-1);
oppositePoint.set(x-1, getValue(x-1, y), y); oppositePoint.set(x-1, getValue(x-1, y), y);
} else { // case #3 : last row, except for last col } else { // case #3 : last row, except for last col
// right cross up // right cross up
// adj = normalIndex + 1; // adj = normalIndex + 1;
// opp = normalIndex - getWidth(); // opp = normalIndex - getWidth();
adjacentPoint.set(x+1, getValue(x+1,y), y); adjacentPoint.set(x+1, getValue(x+1,y), y);
oppositePoint.set(x, getValue(x,y-1), y-1); oppositePoint.set(x, getValue(x,y-1), y-1);
} }
} else { } else {
if (x == getWidth() - 1) { // case #2 : last column except for last row if (x == getWidth() - 1) { // case #2 : last column except for last row
// left cross down // left cross down
adjacentPoint.set(x-1, getValue(x-1,y), y); adjacentPoint.set(x-1, getValue(x-1,y), y);
oppositePoint.set(x, getValue(x,y+1), y+1); oppositePoint.set(x, getValue(x,y+1), y+1);
// adj = normalIndex - 1; // adj = normalIndex - 1;
// opp = normalIndex + getWidth(); // opp = normalIndex + getWidth();
} else { // case #1 : most cases } else { // case #1 : most cases
// right cross down // right cross down
adjacentPoint.set(x, getValue(x,y+1), y+1); adjacentPoint.set(x, getValue(x,y+1), y+1);
oppositePoint.set(x+1, getValue(x+1,y), y); oppositePoint.set(x+1, getValue(x+1,y), y);
// adj = normalIndex + getWidth(); // adj = normalIndex + getWidth();
// opp = normalIndex + 1; // opp = normalIndex + 1;
}
} }
}
tempNorm.set(adjacentPoint).subtractLocal(rootPoint) tempNorm.set(adjacentPoint).subtractLocal(rootPoint)
.crossLocal(oppositePoint.subtractLocal(rootPoint)); .crossLocal(oppositePoint.subtractLocal(rootPoint));
tempNorm.multLocal(scale).normalizeLocal(); tempNorm.multLocal(scale).normalizeLocal();
// store.put(tempNorm.x).put(tempNorm.y).put(tempNorm.z); // store.put(tempNorm.x).put(tempNorm.y).put(tempNorm.z);
BufferUtils.setInBuffer(tempNorm, store, BufferUtils.setInBuffer(tempNorm, store,
normalIndex); normalIndex);
normalIndex++; normalIndex++;
}
}
}else{
Vector3f temp = new Vector3f();
for (int z = 0; z < getHeight(); z++){
for (int x = 0; x < getWidth(); x++){
getNormal(x,z,temp);
store.put(temp.x).put(temp.y).put(temp.z);
}
} }
} }
@ -337,9 +236,8 @@ public class GeoMap implements Savable {
}else{ }else{
store = BufferUtils.createFloatBuffer(width*height*3); store = BufferUtils.createFloatBuffer(width*height*3);
} }
hdata.rewind();
assert hdata.limit() == height*width; assert hdata.length == height*width;
Vector3f offset = new Vector3f(-getWidth() * scale.x * 0.5f, Vector3f offset = new Vector3f(-getWidth() * scale.x * 0.5f,
0, 0,
@ -347,10 +245,11 @@ public class GeoMap implements Savable {
if (!center) if (!center)
offset.zero(); offset.zero();
int i = 0;
for (int z = 0; z < height; z++){ for (int z = 0; z < height; z++){
for (int x = 0; x < width; x++){ for (int x = 0; x < width; x++){
store.put( (float)x*scale.x + offset.x ); store.put( (float)x*scale.x + offset.x );
store.put( (float)hdata.get()*scale.y ); store.put( (float)hdata[i++]*scale.y );
store.put( (float)z*scale.z + offset.z ); store.put( (float)z*scale.z + offset.z );
} }
} }
@ -433,24 +332,6 @@ public class GeoMap implements Savable {
return m; return m;
} }
/**
* Populate the height data from the supplied mesh.
* The mesh's dimensions should be the same as width and height
* of this geomap
*/
public void populateHdataFromMesh(Mesh mesh) {
hdata = BufferUtils.createFloatBuffer(width*height);
hdata.rewind();
VertexBuffer pb = mesh.getBuffer(Type.Position);
FloatBuffer fb = (FloatBuffer) pb.getData();
for (int r=0; r<height; r++) {
for (int c=0; c<width; c++) {
float f = fb.get( (width*r) + c + 1);
hdata.put( f );
}
}
}
public void write(JmeExporter ex) throws IOException { public void write(JmeExporter ex) throws IOException {
OutputCapsule oc = ex.getCapsule(this); OutputCapsule oc = ex.getCapsule(this);
oc.write(hdata, "hdata", null); oc.write(hdata, "hdata", null);
@ -461,7 +342,7 @@ public class GeoMap implements Savable {
public void read(JmeImporter im) throws IOException { public void read(JmeImporter im) throws IOException {
InputCapsule ic = im.getCapsule(this); InputCapsule ic = im.getCapsule(this);
hdata = ic.readFloatBuffer("hdata", null); hdata = ic.readFloatArray("hdata", null);
width = ic.readInt("width", 0); width = ic.readInt("width", 0);
height = ic.readInt("height", 0); height = ic.readInt("height", 0);
maxval = ic.readInt("maxval", 0); maxval = ic.readInt("maxval", 0);

@ -49,6 +49,7 @@ import com.jme3.scene.VertexBuffer;
import com.jme3.scene.VertexBuffer.Type; import com.jme3.scene.VertexBuffer.Type;
import com.jme3.util.BufferUtils; import com.jme3.util.BufferUtils;
import com.jme3.util.TangentBinormalGenerator; import com.jme3.util.TangentBinormalGenerator;
import com.jme3.util.TempVars;
import java.io.IOException; import java.io.IOException;
/** /**
@ -69,8 +70,8 @@ public class LODGeomap extends GeoMap {
public LODGeomap() { public LODGeomap() {
} }
public LODGeomap(int size, FloatBuffer heightMap) { public LODGeomap(int size, float[] heightMap) {
super(heightMap, null, size, size, 1); super(heightMap, size, size, 1);
} }
public Mesh createMesh(Vector3f scale, Vector2f tcScale, Vector2f tcOffset, float offsetAmount, int totalSize, boolean center) { public Mesh createMesh(Vector3f scale, Vector2f tcScale, Vector2f tcOffset, float offsetAmount, int totalSize, boolean center) {
@ -98,10 +99,6 @@ public class LODGeomap extends GeoMap {
return m; return m;
} }
protected void removeNormalBuffer() {
ndata = null;
}
public FloatBuffer writeTexCoordArray(FloatBuffer store, Vector2f offset, Vector2f scale, float offsetAmount, int totalSize) { public FloatBuffer writeTexCoordArray(FloatBuffer store, Vector2f offset, Vector2f scale, float offsetAmount, int totalSize) {
if (store != null) { if (store != null) {
if (store.remaining() < getWidth() * getHeight() * 2) { if (store.remaining() < getWidth() * getHeight() * 2) {
@ -762,94 +759,150 @@ public class LODGeomap extends GeoMap {
} }
store.rewind(); store.rewind();
Vector3f rootPoint = new Vector3f(); TempVars vars = TempVars.get();
Vector3f rightPoint = new Vector3f();
Vector3f leftPoint = new Vector3f(); Vector3f rootPoint = vars.vect1;
Vector3f topPoint = new Vector3f(); Vector3f rightPoint = vars.vect2;
Vector3f bottomPoint = new Vector3f(); Vector3f leftPoint = vars.vect3;
Vector3f topPoint = vars.vect4;
Vector3f bottomPoint = vars.vect5;
Vector3f tmp1 = vars.vect6;
Vector3f tmp2 = vars.vect7;
// calculate normals for each polygon // calculate normals for each polygon
for (int r = 0; r < getHeight(); r++) { for (int r = 0; r < getHeight(); r++) {
for (int c = 0; c < getWidth(); c++) { for (int c = 0; c < getWidth(); c++) {
rootPoint.set(c, getValue(c, r), r); rootPoint.set(c, getValue(c, r), r);
Vector3f normal = new Vector3f(); Vector3f normal = vars.vect8;
if (r == 0) { // first row if (r == 0) { // first row
if (c == 0) { // first column if (c == 0) { // first column
rightPoint.set(c + 1, getValue(c + 1, r), r); rightPoint.set(c + 1, getValue(c + 1, r), r);
bottomPoint.set(c, getValue(c, r + 1), r + 1); bottomPoint.set(c, getValue(c, r + 1), r + 1);
normal.set(getNormal(bottomPoint, rootPoint, rightPoint, scale)); getNormal(bottomPoint, rootPoint, rightPoint, scale, normal);
normal.set(Vector3f.UNIT_Y);
} else if (c == getWidth() - 1) { // last column } else if (c == getWidth() - 1) { // last column
leftPoint.set(c - 1, getValue(c - 1, r), r); leftPoint.set(c - 1, getValue(c - 1, r), r);
bottomPoint.set(c, getValue(c, r + 1), r + 1); bottomPoint.set(c, getValue(c, r + 1), r + 1);
normal.set(getNormal(leftPoint, rootPoint, bottomPoint, scale)); getNormal(leftPoint, rootPoint, bottomPoint, scale, normal);
normal.set(Vector3f.UNIT_Y);
} else { // all middle columns } else { // all middle columns
leftPoint.set(c - 1, getValue(c - 1, r), r); leftPoint.set(c - 1, getValue(c - 1, r), r);
rightPoint.set(c + 1, getValue(c + 1, r), r); rightPoint.set(c + 1, getValue(c + 1, r), r);
bottomPoint.set(c, getValue(c, r + 1), r + 1); bottomPoint.set(c, getValue(c, r + 1), r + 1);
Vector3f n1 = getNormal(leftPoint, rootPoint, bottomPoint, scale);
Vector3f n2 = getNormal(bottomPoint, rootPoint, rightPoint, scale); normal.set( getNormal(leftPoint, rootPoint, bottomPoint, scale, tmp1) );
normal.set(n1.add(n2).normalizeLocal()); normal.add( getNormal(bottomPoint, rootPoint, rightPoint, scale, tmp1) );
normal.normalizeLocal();
normal.set(Vector3f.UNIT_Y);
} }
} else if (r == getHeight() - 1) { // last row } else if (r == getHeight() - 1) { // last row
if (c == 0) { // first column if (c == 0) { // first column
topPoint.set(c, getValue(c, r - 1), r - 1); topPoint.set(c, getValue(c, r - 1), r - 1);
rightPoint.set(c + 1, getValue(c + 1, r), r); rightPoint.set(c + 1, getValue(c + 1, r), r);
normal.set(getNormal(rightPoint, rootPoint, topPoint, scale)); getNormal(rightPoint, rootPoint, topPoint, scale, normal);
normal.set(Vector3f.UNIT_Y);
} else if (c == getWidth() - 1) { // last column } else if (c == getWidth() - 1) { // last column
topPoint.set(c, getValue(c, r - 1), r - 1); topPoint.set(c, getValue(c, r - 1), r - 1);
leftPoint.set(c - 1, getValue(c - 1, r), r); leftPoint.set(c - 1, getValue(c - 1, r), r);
normal.set(getNormal(topPoint, rootPoint, leftPoint, scale)); getNormal(topPoint, rootPoint, leftPoint, scale, normal);
normal.set(Vector3f.UNIT_Y);
} else { // all middle columns } else { // all middle columns
topPoint.set(c, getValue(c, r - 1), r - 1); topPoint.set(c, getValue(c, r - 1), r - 1);
leftPoint.set(c - 1, getValue(c - 1, r), r); leftPoint.set(c - 1, getValue(c - 1, r), r);
rightPoint.set(c + 1, getValue(c + 1, r), r); rightPoint.set(c + 1, getValue(c + 1, r), r);
Vector3f n1 = getNormal(topPoint, rootPoint, leftPoint, scale);
Vector3f n2 = getNormal(rightPoint, rootPoint, topPoint, scale); normal.set( getNormal(topPoint, rootPoint, leftPoint, scale, tmp1) );
normal.set(n1.add(n2).normalizeLocal()); normal.add( getNormal(rightPoint, rootPoint, topPoint, scale, tmp1) );
normal.normalizeLocal();
normal.set(Vector3f.UNIT_Y);
} }
} else { // all middle rows } else { // all middle rows
if (c == 0) { // first column if (c == 0) { // first column
topPoint.set(c, getValue(c, r - 1), r - 1); topPoint.set(c, getValue(c, r - 1), r - 1);
rightPoint.set(c + 1, getValue(c + 1, r), r); rightPoint.set(c + 1, getValue(c + 1, r), r);
bottomPoint.set(c, getValue(c, r + 1), r + 1); bottomPoint.set(c, getValue(c, r + 1), r + 1);
Vector3f n1 = getNormal(rightPoint, rootPoint, topPoint, scale);
Vector3f n2 = getNormal(bottomPoint, rootPoint, rightPoint, scale); normal.set( getNormal(rightPoint, rootPoint, topPoint, scale, tmp1) );
normal.set(n1.add(n2).normalizeLocal()); normal.add( getNormal(bottomPoint, rootPoint, rightPoint, scale, tmp1) );
normal.normalizeLocal();
normal.set(Vector3f.UNIT_Y);
} else if (c == getWidth() - 1) { // last column } else if (c == getWidth() - 1) { // last column
topPoint.set(c, getValue(c, r - 1), r - 1); topPoint.set(c, getValue(c, r - 1), r - 1);
leftPoint.set(c - 1, getValue(c - 1, r), r); leftPoint.set(c - 1, getValue(c - 1, r), r);
bottomPoint.set(c, getValue(c, r + 1), r + 1); bottomPoint.set(c, getValue(c, r + 1), r + 1);
Vector3f n1 = getNormal(topPoint, rootPoint, leftPoint, scale);
Vector3f n2 = getNormal(leftPoint, rootPoint, bottomPoint, scale); normal.set( getNormal(topPoint, rootPoint, leftPoint, scale, tmp1) );
normal.set(n1.add(n2).normalizeLocal()); normal.add( getNormal(leftPoint, rootPoint, bottomPoint, scale, tmp1) );
normal.normalizeLocal();
normal.set(Vector3f.UNIT_Y);
} else { // all middle columns } else { // all middle columns
topPoint.set(c, getValue(c, r - 1), r - 1); topPoint.set(c, getValue(c, r - 1), r - 1);
leftPoint.set(c - 1, getValue(c - 1, r), r); leftPoint.set(c - 1, getValue(c - 1, r), r);
rightPoint.set(c + 1, getValue(c + 1, r), r); rightPoint.set(c + 1, getValue(c + 1, r), r);
bottomPoint.set(c, getValue(c, r + 1), r + 1); bottomPoint.set(c, getValue(c, r + 1), r + 1);
Vector3f n1 = getNormal(topPoint, rootPoint, leftPoint, scale);
Vector3f n2 = getNormal(leftPoint, rootPoint, bottomPoint, scale); normal.set( getNormal(topPoint, rootPoint, leftPoint, scale, tmp1 ) );
Vector3f n3 = getNormal(bottomPoint, rootPoint, rightPoint, scale); normal.add( getNormal(leftPoint, rootPoint, bottomPoint, scale, tmp1) );
Vector3f n4 = getNormal(rightPoint, rootPoint, topPoint, scale); normal.add( getNormal(bottomPoint, rootPoint, rightPoint, scale, tmp1) );
normal.set(n1.add(n2).add(n3).add(n4).normalizeLocal()); normal.add( getNormal(rightPoint, rootPoint, topPoint, scale, tmp1) );
normal.normalizeLocal();
normal.set(Vector3f.UNIT_Y);
} }
} }
normal.set(Vector3f.UNIT_Y);
BufferUtils.setInBuffer(normal, store, (r * getWidth() + c)); // save the normal BufferUtils.setInBuffer(normal, store, (r * getWidth() + c)); // save the normal
} }
} }
vars.release();
return store; return store;
} }
private Vector3f getNormal(Vector3f firstPoint, Vector3f rootPoint, Vector3f secondPoint, Vector3f scale) { private Vector3f getNormal(Vector3f firstPoint, Vector3f rootPoint, Vector3f secondPoint, Vector3f scale, Vector3f store) {
Vector3f normal = new Vector3f(); // store.set(firstPoint).subtractLocal(rootPoint);
//scale = Vector3f.UNIT_XYZ; // tmp.set(secondPoint).subtractLocal(rootPoint);
normal.set(firstPoint.mult(scale)).subtractLocal(rootPoint.mult(scale)).crossLocal(secondPoint.mult(scale).subtract(rootPoint.mult(scale))).normalizeLocal(); // store.crossLocal(tmp).mult(scale).normalizeLocal();
return normal;
// store.set(
// firstPoint.mult(scale)).subtractLocal(rootPoint.mult(scale))
// .crossLocal(
// secondPoint.mult(scale).subtract(rootPoint.mult(scale))).normalizeLocal();
float x1 = firstPoint.x - rootPoint.x;
float y1 = firstPoint.y - rootPoint.y;
float z1 = firstPoint.z - rootPoint.z;
float x2 = secondPoint.x - rootPoint.x;
float y2 = secondPoint.y - rootPoint.y;
float z2 = secondPoint.z - rootPoint.z;
float x3 = (y1 * z2) - (z1 * y2);
float y3 = (z1 * x2) - (x1 * z2);
float z3 = (x1 * y2) - (y1 * x2);
x3 *= scale.x;
y3 *= scale.y;
z3 *= scale.z;
float inv = 1.0f / FastMath.sqrt(x3 * x3 + y3 * y3 + z3 * z3);
store.x = x3 * inv;
store.y = y3 * inv;
store.z = z3 * inv;
return store;
} }
/** /**
@ -953,10 +1006,10 @@ public class LODGeomap extends GeoMap {
Triangle t = new Triangle(new Vector3f(), new Vector3f(), new Vector3f()); Triangle t = new Triangle(new Vector3f(), new Vector3f(), new Vector3f());
Triangle t2 = new Triangle(new Vector3f(), new Vector3f(), new Vector3f()); Triangle t2 = new Triangle(new Vector3f(), new Vector3f(), new Vector3f());
float h1 = hdata.get(index); // top left float h1 = hdata[index]; // top left
float h2 = hdata.get(index + 1); // top right float h2 = hdata[index + 1]; // top right
float h3 = hdata.get(index + width); // bottom left float h3 = hdata[index + width]; // bottom left
float h4 = hdata.get(index + width + 1); // bottom right float h4 = hdata[index + width + 1]; // bottom right
if ((gridX == 0 && gridY == 0) || (gridX == width - 1 && gridY == width - 1)) { if ((gridX == 0 && gridY == 0) || (gridX == width - 1 && gridY == width - 1)) {

@ -186,10 +186,7 @@ public class TerrainPatch extends Geometry {
setLocalTranslation(origin); setLocalTranslation(origin);
FloatBuffer heightBuffer = BufferUtils.createFloatBuffer(size*size); geomap = new LODGeomap(size, heightMap);
heightBuffer.put(heightMap);
geomap = new LODGeomap(size, heightBuffer);
Mesh m = geomap.createMesh(stepScale, new Vector2f(1,1), offset, offsetAmount, totalSize, false); Mesh m = geomap.createMesh(stepScale, new Vector2f(1,1), offset, offsetAmount, totalSize, false);
setMesh(m); setMesh(m);
@ -216,7 +213,7 @@ public class TerrainPatch extends Geometry {
return lodEntropy; return lodEntropy;
} }
public FloatBuffer getHeightmap() { public float[] getHeightmap() {
return geomap.getHeightData(); return geomap.getHeightData();
} }
@ -300,10 +297,10 @@ public class TerrainPatch extends Geometry {
continue; continue;
int idx = lh.z * size + lh.x; int idx = lh.z * size + lh.x;
if (overrideHeight) { if (overrideHeight) {
geomap.getHeightData().put(idx, lh.h); geomap.getHeightData()[idx] = lh.h;
} else { } else {
float h = getMesh().getFloatBuffer(Type.Position).get(idx*3+1); float h = getMesh().getFloatBuffer(Type.Position).get(idx*3+1);
geomap.getHeightData().put(idx, h+lh.h); geomap.getHeightData()[idx] = h+lh.h;
} }
} }

@ -1796,13 +1796,13 @@ public class TerrainQuad extends Node implements Terrain {
if (getChild(0) instanceof TerrainPatch) { if (getChild(0) instanceof TerrainPatch) {
for (Spatial s : getChildren()) { for (Spatial s : getChildren()) {
if ( ((TerrainPatch)s).getQuadrant() == 1) if ( ((TerrainPatch)s).getQuadrant() == 1)
ul = BufferUtils.getFloatArray(((TerrainPatch)s).getHeightmap()); ul = ((TerrainPatch)s).getHeightmap();
else if(((TerrainPatch) s).getQuadrant() == 2) else if(((TerrainPatch) s).getQuadrant() == 2)
bl = BufferUtils.getFloatArray(((TerrainPatch)s).getHeightmap()); bl = ((TerrainPatch)s).getHeightmap();
else if(((TerrainPatch) s).getQuadrant() == 3) else if(((TerrainPatch) s).getQuadrant() == 3)
ur = BufferUtils.getFloatArray(((TerrainPatch)s).getHeightmap()); ur = ((TerrainPatch)s).getHeightmap();
else if(((TerrainPatch) s).getQuadrant() == 4) else if(((TerrainPatch) s).getQuadrant() == 4)
br = BufferUtils.getFloatArray(((TerrainPatch)s).getHeightmap()); br = ((TerrainPatch)s).getHeightmap();
} }
} }
else { else {

Loading…
Cancel
Save