|
|
|
@ -29,7 +29,6 @@ |
|
|
|
|
* 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; |
|
|
|
|
|
|
|
|
|
import com.jme3.export.InputCapsule; |
|
|
|
@ -67,7 +66,8 @@ import java.io.IOException; |
|
|
|
|
*/ |
|
|
|
|
public class LODGeomap extends BufferGeomap { |
|
|
|
|
|
|
|
|
|
public LODGeomap() {} |
|
|
|
|
public LODGeomap() { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public LODGeomap(int size, FloatBuffer heightMap) { |
|
|
|
|
super(heightMap, null, size, size, 1); |
|
|
|
@ -93,21 +93,22 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
return m; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected void removeNormalBuffer() { |
|
|
|
|
ndata = null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public FloatBuffer writeTexCoordArray(FloatBuffer store, Vector2f offset, Vector2f scale, float offsetAmount, int totalSize) { |
|
|
|
|
if (store != null) { |
|
|
|
|
if (store.remaining() < getWidth()*getHeight()*2) |
|
|
|
|
if (store.remaining() < getWidth() * getHeight() * 2) { |
|
|
|
|
throw new BufferUnderflowException(); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
store = BufferUtils.createFloatBuffer(getWidth() * getHeight() * 2); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (offset == null) |
|
|
|
|
if (offset == null) { |
|
|
|
|
offset = new Vector2f(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Vector2f tcStore = new Vector2f(); |
|
|
|
|
|
|
|
|
@ -150,8 +151,9 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
|
|
|
|
|
IntBuffer buffer2 = store; |
|
|
|
|
int numIndexes = calculateNumIndexesLodDiff(lod); |
|
|
|
|
if (store == null) |
|
|
|
|
if (store == null) { |
|
|
|
|
buffer2 = BufferUtils.createIntBuffer(numIndexes); |
|
|
|
|
} |
|
|
|
|
VerboseIntBuffer buffer = new VerboseIntBuffer(buffer2); |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -200,7 +202,6 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
idx = (row - lod) * getWidth() - 1; |
|
|
|
|
buffer.put(idx); |
|
|
|
|
} else { |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
@ -224,8 +225,9 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
|
|
|
|
|
// top (the order gets reversed here so the diagonals line up)
|
|
|
|
|
if (topLod) { // if lower LOD
|
|
|
|
|
if (rightLod) |
|
|
|
|
if (rightLod) { |
|
|
|
|
buffer.put(getWidth() - 1); |
|
|
|
|
} |
|
|
|
|
for (int col = getWidth() - 1; col >= lod; col -= 2 * lod) { |
|
|
|
|
int idx = (lod * getWidth()) + col - lod; // next row
|
|
|
|
|
buffer.put(idx); |
|
|
|
@ -237,12 +239,12 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
idx = col - 2 * lod; |
|
|
|
|
buffer.put(idx); |
|
|
|
|
} else { |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
if (rightLod) |
|
|
|
|
if (rightLod) { |
|
|
|
|
buffer.put(getWidth() - 1); |
|
|
|
|
} |
|
|
|
|
for (int col = getWidth() - 1 - lod; col > 0; col -= lod) { |
|
|
|
|
int idx = col + (lod * getWidth()); |
|
|
|
|
buffer.put(idx); |
|
|
|
@ -260,8 +262,9 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
|
|
|
|
|
// left
|
|
|
|
|
if (leftLod) { // if lower LOD
|
|
|
|
|
if (topLod) |
|
|
|
|
if (topLod) { |
|
|
|
|
buffer.put(0); |
|
|
|
|
} |
|
|
|
|
for (int row = 0; row < getWidth() - lod; row += 2 * lod) { |
|
|
|
|
int idx = (row + lod) * getWidth() + lod; |
|
|
|
|
buffer.put(idx); |
|
|
|
@ -273,12 +276,12 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
idx = (row + 2 * lod) * getWidth(); |
|
|
|
|
buffer.put(idx); |
|
|
|
|
} else { |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
if (!topLod) |
|
|
|
|
if (!topLod) { |
|
|
|
|
buffer.put(0); |
|
|
|
|
} |
|
|
|
|
//buffer.put(getWidth()+1); // degenerate
|
|
|
|
|
//buffer.put(0); // degenerate winding-flip
|
|
|
|
|
for (int row = lod; row < getWidth() - lod; row += lod) { |
|
|
|
@ -300,8 +303,9 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
|
|
|
|
|
// bottom
|
|
|
|
|
if (bottomLod) { // if lower LOD
|
|
|
|
|
if (leftLod) |
|
|
|
|
if (leftLod) { |
|
|
|
|
buffer.put(getWidth() * (getWidth() - 1)); |
|
|
|
|
} |
|
|
|
|
// there was a slight bug here when really high LOD near maxLod
|
|
|
|
|
// far right has extra index one row up and all the way to the right, need to skip last index entered
|
|
|
|
|
// seemed to be fixed by making "getWidth()-1-2-lod" this: "getWidth()-1-2*lod", which seems more correct
|
|
|
|
@ -316,7 +320,6 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
idx = getWidth() * (getWidth() - 1) + col + 2 * lod; |
|
|
|
|
buffer.put(idx); |
|
|
|
|
} else { |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
@ -340,8 +343,9 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
//System.out.println("\nBuffer size: "+buffer.getCount());
|
|
|
|
|
|
|
|
|
|
// fill in the rest of the buffer with degenerates, there should only be a couple
|
|
|
|
|
for (int i=buffer.getCount(); i<numIndexes; i++) |
|
|
|
|
for (int i = buffer.getCount(); i < numIndexes; i++) { |
|
|
|
|
buffer.put(getWidth() * getWidth() - 1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return buffer.delegate; |
|
|
|
|
} |
|
|
|
@ -350,8 +354,9 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
|
|
|
|
|
IntBuffer buffer2 = store; |
|
|
|
|
int numIndexes = calculateNumIndexesLodDiff(lod); |
|
|
|
|
if (store == null) |
|
|
|
|
if (store == null) { |
|
|
|
|
buffer2 = BufferUtils.createIntBuffer(numIndexes); |
|
|
|
|
} |
|
|
|
|
VerboseIntBuffer buffer = new VerboseIntBuffer(buffer2); |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -457,8 +462,9 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
if (rightLod>lod) |
|
|
|
|
if (rightLod > lod) { |
|
|
|
|
buffer.put(getWidth() - 1); |
|
|
|
|
} |
|
|
|
|
for (int col = getWidth() - 1 - lod; col > 0; col -= lod) { |
|
|
|
|
int idx = col + (lod * getWidth()); |
|
|
|
|
buffer.put(idx); |
|
|
|
@ -568,8 +574,9 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
//System.out.println("\nBuffer size: "+buffer.getCount());
|
|
|
|
|
|
|
|
|
|
// fill in the rest of the buffer with degenerates, there should only be a couple
|
|
|
|
|
for (int i=buffer.getCount(); i<numIndexes; i++) |
|
|
|
|
for (int i = buffer.getCount(); i < numIndexes; i++) { |
|
|
|
|
buffer.put(getWidth() * getWidth() - 1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return buffer.delegate; |
|
|
|
|
} |
|
|
|
@ -586,14 +593,14 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
System.out.println("Index buffer size: "+num); |
|
|
|
|
return num; |
|
|
|
|
}*/ |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* calculate how many indexes there will be. |
|
|
|
|
* This isn't that precise and there might be a couple extra. |
|
|
|
|
*/ |
|
|
|
|
private int calculateNumIndexesLodDiff(int lod) { |
|
|
|
|
if (lod == 0) |
|
|
|
|
if (lod == 0) { |
|
|
|
|
lod = 1; |
|
|
|
|
} |
|
|
|
|
int length = getWidth() - 1; // make it even for lod calc
|
|
|
|
|
int side = (length / lod) + 1 - (2); |
|
|
|
|
//System.out.println("side: "+side);
|
|
|
|
@ -618,12 +625,14 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public FloatBuffer writeNormalArray(FloatBuffer store, Vector3f scale) { |
|
|
|
|
if (!isLoaded()) |
|
|
|
|
if (!isLoaded()) { |
|
|
|
|
throw new NullPointerException(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (store != null) { |
|
|
|
|
if (store.remaining() < getWidth()*getHeight()*3) |
|
|
|
|
if (store.remaining() < getWidth() * getHeight() * 3) { |
|
|
|
|
throw new BufferUnderflowException(); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
store = BufferUtils.createFloatBuffer(getWidth() * getHeight() * 3); |
|
|
|
|
} |
|
|
|
@ -714,22 +723,22 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
|
|
|
|
|
private Vector3f getNormal(Vector3f firstPoint, Vector3f rootPoint, Vector3f secondPoint) { |
|
|
|
|
Vector3f normal = new Vector3f(); |
|
|
|
|
normal.set(firstPoint).subtractLocal(rootPoint) |
|
|
|
|
.crossLocal(secondPoint.subtract(rootPoint)).normalizeLocal(); |
|
|
|
|
normal.set(firstPoint).subtractLocal(rootPoint).crossLocal(secondPoint.subtract(rootPoint)).normalizeLocal(); |
|
|
|
|
return normal; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Keeps a count of the number of indexes, good for debugging |
|
|
|
|
*/ |
|
|
|
|
public class VerboseIntBuffer { |
|
|
|
|
|
|
|
|
|
private IntBuffer delegate; |
|
|
|
|
int count = 0; |
|
|
|
|
|
|
|
|
|
public VerboseIntBuffer(IntBuffer d) { |
|
|
|
|
delegate = d; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public void put(int value) { |
|
|
|
|
try { |
|
|
|
|
delegate.put(value); |
|
|
|
@ -738,6 +747,7 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
//System.out.println("err buffer size: "+delegate.capacity());
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public int getCount() { |
|
|
|
|
return count; |
|
|
|
|
} |
|
|
|
@ -811,8 +821,9 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
int gridY = (int) z; |
|
|
|
|
|
|
|
|
|
int index = findClosestHeightIndex(gridX, gridY); |
|
|
|
|
if (index < 0) |
|
|
|
|
if (index < 0) { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Triangle t = new Triangle(new Vector3f(), new Vector3f(), new Vector3f()); |
|
|
|
|
Triangle t2 = new Triangle(new Vector3f(), new Vector3f(), new Vector3f()); |
|
|
|
@ -848,8 +859,7 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
t2.get(2).x = (gridX + 1); |
|
|
|
|
t2.get(2).y = (h2); |
|
|
|
|
t2.get(2).z = (gridY); |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
} else { |
|
|
|
|
// all other grid points
|
|
|
|
|
t.get(0).x = (gridX); |
|
|
|
|
t.get(0).y = (h1); |
|
|
|
@ -897,20 +907,21 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
Vector2f t2 = new Vector2f(triangles[0].get2().x, triangles[0].get2().z); |
|
|
|
|
Vector2f t3 = new Vector2f(triangles[0].get3().x, triangles[0].get3().z); |
|
|
|
|
|
|
|
|
|
if (0 != FastMath.pointInsideTriangle(t1, t2, t3, point)) |
|
|
|
|
if (0 != FastMath.pointInsideTriangle(t1, t2, t3, point)) { |
|
|
|
|
return triangles[0]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
t1.set(triangles[1].get1().x, triangles[1].get1().z); |
|
|
|
|
t1.set(triangles[1].get2().x, triangles[1].get2().z); |
|
|
|
|
t1.set(triangles[1].get3().x, triangles[1].get3().z); |
|
|
|
|
|
|
|
|
|
if (0 != FastMath.pointInsideTriangle(t1, t2, t3, point)) |
|
|
|
|
if (0 != FastMath.pointInsideTriangle(t1, t2, t3, point)) { |
|
|
|
|
return triangles[1]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected int findClosestHeightIndex(int x, int z) { |
|
|
|
|
|
|
|
|
|
if (x < 0 || x >= width - 1) { |
|
|
|
@ -933,4 +944,3 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
super.read(im); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|