* 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
This commit is contained in:
parent
b192166072
commit
268a464191
@ -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,7 +160,6 @@ 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();
|
||||||
@ -302,15 +210,6 @@ public class GeoMap implements Savable {
|
|||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return store;
|
return store;
|
||||||
}
|
}
|
||||||
@ -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…
x
Reference in New Issue
Block a user