|
|
|
@ -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,17 +66,18 @@ 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); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public Mesh createMesh(Vector3f scale, Vector2f tcScale, Vector2f tcOffset, float offsetAmount, int totalSize, boolean center) { |
|
|
|
|
return this.createMesh(scale, tcScale, tcOffset, offsetAmount, totalSize, center, 1, false,false,false,false); |
|
|
|
|
return this.createMesh(scale, tcScale, tcOffset, offsetAmount, totalSize, center, 1, false, false, false, false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public Mesh createMesh(Vector3f scale, Vector2f tcScale, Vector2f tcOffset, float offsetAmount, int totalSize, boolean center, int lod, boolean rightLod, boolean topLod, boolean leftLod, boolean bottomLod){ |
|
|
|
|
public Mesh createMesh(Vector3f scale, Vector2f tcScale, Vector2f tcOffset, float offsetAmount, int totalSize, boolean center, int lod, boolean rightLod, boolean topLod, boolean leftLod, boolean bottomLod) { |
|
|
|
|
FloatBuffer pb = writeVertexArray(null, scale, center); |
|
|
|
|
FloatBuffer tb = writeTexCoordArray(null, tcOffset, tcScale, offsetAmount, totalSize); |
|
|
|
|
FloatBuffer nb = writeNormalArray(null, scale); |
|
|
|
@ -93,44 +93,45 @@ 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) |
|
|
|
|
public FloatBuffer writeTexCoordArray(FloatBuffer store, Vector2f offset, Vector2f scale, float offsetAmount, int totalSize) { |
|
|
|
|
if (store != null) { |
|
|
|
|
if (store.remaining() < getWidth() * getHeight() * 2) { |
|
|
|
|
throw new BufferUnderflowException(); |
|
|
|
|
}else{ |
|
|
|
|
store = BufferUtils.createFloatBuffer(getWidth()*getHeight()*2); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
store = BufferUtils.createFloatBuffer(getWidth() * getHeight() * 2); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (offset == null) |
|
|
|
|
if (offset == null) { |
|
|
|
|
offset = new Vector2f(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Vector2f tcStore = new Vector2f(); |
|
|
|
|
|
|
|
|
|
for (int y = 0; y < getHeight(); y++){ |
|
|
|
|
for (int y = 0; y < getHeight(); y++) { |
|
|
|
|
|
|
|
|
|
for (int x = 0; x < getWidth(); x++){ |
|
|
|
|
getUV(x,y,tcStore, offset, offsetAmount, totalSize); |
|
|
|
|
for (int x = 0; x < getWidth(); x++) { |
|
|
|
|
getUV(x, y, tcStore, offset, offsetAmount, totalSize); |
|
|
|
|
float tx = tcStore.x * scale.x; |
|
|
|
|
float ty = tcStore.y * scale.y; |
|
|
|
|
store.put( tx ); |
|
|
|
|
store.put( ty ); |
|
|
|
|
store.put(tx); |
|
|
|
|
store.put(ty); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return store; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public Vector2f getUV(int x, int y, Vector2f store, Vector2f offset, float offsetAmount, int totalSize){ |
|
|
|
|
public Vector2f getUV(int x, int y, Vector2f store, Vector2f offset, float offsetAmount, int totalSize) { |
|
|
|
|
float offsetX = offset.x + (offsetAmount * 1.0f);//stepScale.x);
|
|
|
|
|
float offsetY = offset.y + (offsetAmount * 1.0f);//stepScale.z);
|
|
|
|
|
|
|
|
|
|
store.set( ( ((float)x)+offsetX) / (float)totalSize, // calculates percentage of texture here
|
|
|
|
|
( ((float)y)+offsetY) / (float)totalSize ); |
|
|
|
|
store.set((((float) x) + offsetX) / (float) totalSize, // calculates percentage of texture here
|
|
|
|
|
(((float) y) + offsetY) / (float) totalSize); |
|
|
|
|
return store; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -146,33 +147,34 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
* @param bottomLod LOD of the bottom neighbour |
|
|
|
|
* @return the LOD-ified index buffer |
|
|
|
|
*/ |
|
|
|
|
public IntBuffer writeIndexArrayLodDiff(IntBuffer store, int lod, boolean rightLod, boolean topLod, boolean leftLod, boolean bottomLod){ |
|
|
|
|
public IntBuffer writeIndexArrayLodDiff(IntBuffer store, int lod, boolean rightLod, boolean topLod, boolean leftLod, boolean bottomLod) { |
|
|
|
|
|
|
|
|
|
IntBuffer buffer2 = store; |
|
|
|
|
int numIndexes = calculateNumIndexesLodDiff(lod); |
|
|
|
|
if (store == null) |
|
|
|
|
if (store == null) { |
|
|
|
|
buffer2 = BufferUtils.createIntBuffer(numIndexes); |
|
|
|
|
} |
|
|
|
|
VerboseIntBuffer buffer = new VerboseIntBuffer(buffer2); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// generate center squares minus the edges
|
|
|
|
|
//System.out.println("for (x="+lod+"; x<"+(getWidth()-(2*lod))+"; x+="+lod+")");
|
|
|
|
|
//System.out.println(" for (z="+lod+"; z<"+(getWidth()-(1*lod))+"; z+="+lod+")");
|
|
|
|
|
for (int r=lod; r<getWidth()-(2*lod); r+=lod) { // row
|
|
|
|
|
int rowIdx = r*getWidth(); |
|
|
|
|
int nextRowIdx = (r+1*lod)*getWidth(); |
|
|
|
|
for (int c=lod; c<getWidth()-(1*lod); c+=lod) { // column
|
|
|
|
|
int idx = rowIdx+c; |
|
|
|
|
for (int r = lod; r < getWidth() - (2 * lod); r += lod) { // row
|
|
|
|
|
int rowIdx = r * getWidth(); |
|
|
|
|
int nextRowIdx = (r + 1 * lod) * getWidth(); |
|
|
|
|
for (int c = lod; c < getWidth() - (1 * lod); c += lod) { // column
|
|
|
|
|
int idx = rowIdx + c; |
|
|
|
|
buffer.put(idx); |
|
|
|
|
idx = nextRowIdx+c; |
|
|
|
|
idx = nextRowIdx + c; |
|
|
|
|
buffer.put(idx); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// add degenerate triangles
|
|
|
|
|
if (r < getWidth()-(3*lod)) { |
|
|
|
|
int idx = nextRowIdx+getWidth()-(1*lod)-1; |
|
|
|
|
if (r < getWidth() - (3 * lod)) { |
|
|
|
|
int idx = nextRowIdx + getWidth() - (1 * lod) - 1; |
|
|
|
|
buffer.put(idx); |
|
|
|
|
idx = nextRowIdx+(1*lod); // inset by 1
|
|
|
|
|
idx = nextRowIdx + (1 * lod); // inset by 1
|
|
|
|
|
buffer.put(idx); |
|
|
|
|
//System.out.println("");
|
|
|
|
|
} |
|
|
|
@ -184,36 +186,35 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// right
|
|
|
|
|
int br = getWidth()*(getWidth()-lod)-1-lod; |
|
|
|
|
int br = getWidth() * (getWidth() - lod) - 1 - lod; |
|
|
|
|
buffer.put(br); // bottom right -1
|
|
|
|
|
int corner = getWidth()*getWidth()-1; |
|
|
|
|
int corner = getWidth() * getWidth() - 1; |
|
|
|
|
buffer.put(corner); // bottom right corner
|
|
|
|
|
if (rightLod) { // if lower LOD
|
|
|
|
|
for (int row=getWidth()-lod; row>=1+lod; row-=2*lod) { |
|
|
|
|
int idx = (row)*getWidth()-1-lod; |
|
|
|
|
for (int row = getWidth() - lod; row >= 1 + lod; row -= 2 * lod) { |
|
|
|
|
int idx = (row) * getWidth() - 1 - lod; |
|
|
|
|
buffer.put(idx); |
|
|
|
|
idx = (row-lod)*getWidth()-1; |
|
|
|
|
idx = (row - lod) * getWidth() - 1; |
|
|
|
|
buffer.put(idx); |
|
|
|
|
if (row > lod+1) { //if not the last one
|
|
|
|
|
idx = (row-lod)*getWidth()-1-lod; |
|
|
|
|
if (row > lod + 1) { //if not the last one
|
|
|
|
|
idx = (row - lod) * getWidth() - 1 - lod; |
|
|
|
|
buffer.put(idx); |
|
|
|
|
idx = (row-lod)*getWidth()-1; |
|
|
|
|
idx = (row - lod) * getWidth() - 1; |
|
|
|
|
buffer.put(idx); |
|
|
|
|
} else { |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
buffer.put(corner);//br+1);//degenerate to flip winding order
|
|
|
|
|
for (int row=getWidth()-lod; row>lod; row-=lod) { |
|
|
|
|
int idx = row*getWidth()-1; // mult to get row
|
|
|
|
|
for (int row = getWidth() - lod; row > lod; row -= lod) { |
|
|
|
|
int idx = row * getWidth() - 1; // mult to get row
|
|
|
|
|
buffer.put(idx); |
|
|
|
|
buffer.put(idx-lod); |
|
|
|
|
buffer.put(idx - lod); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
buffer.put(getWidth()-1); |
|
|
|
|
buffer.put(getWidth() - 1); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//System.out.println("\nbuffer right: "+(buffer.getCount()-runningBufferCount));
|
|
|
|
@ -224,27 +225,28 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
|
|
|
|
|
// top (the order gets reversed here so the diagonals line up)
|
|
|
|
|
if (topLod) { // if lower LOD
|
|
|
|
|
if (rightLod) |
|
|
|
|
buffer.put(getWidth()-1); |
|
|
|
|
for (int col=getWidth()-1; col>=lod; col-=2*lod) { |
|
|
|
|
int idx = (lod*getWidth())+col-lod; // next row
|
|
|
|
|
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); |
|
|
|
|
idx = col-2*lod; |
|
|
|
|
idx = col - 2 * lod; |
|
|
|
|
buffer.put(idx); |
|
|
|
|
if (col > lod*2) { //if not the last one
|
|
|
|
|
idx = (lod*getWidth())+col-2*lod; |
|
|
|
|
if (col > lod * 2) { //if not the last one
|
|
|
|
|
idx = (lod * getWidth()) + col - 2 * lod; |
|
|
|
|
buffer.put(idx); |
|
|
|
|
idx = col-2*lod; |
|
|
|
|
idx = col - 2 * lod; |
|
|
|
|
buffer.put(idx); |
|
|
|
|
} else { |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
if (rightLod) |
|
|
|
|
buffer.put(getWidth()-1); |
|
|
|
|
for (int col=getWidth()-1-lod; col>0; col-=lod) { |
|
|
|
|
int idx = col + (lod*getWidth()); |
|
|
|
|
if (rightLod) { |
|
|
|
|
buffer.put(getWidth() - 1); |
|
|
|
|
} |
|
|
|
|
for (int col = getWidth() - 1 - lod; col > 0; col -= lod) { |
|
|
|
|
int idx = col + (lod * getWidth()); |
|
|
|
|
buffer.put(idx); |
|
|
|
|
idx = col; |
|
|
|
|
buffer.put(idx); |
|
|
|
@ -260,36 +262,37 @@ 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; |
|
|
|
|
} |
|
|
|
|
for (int row = 0; row < getWidth() - lod; row += 2 * lod) { |
|
|
|
|
int idx = (row + lod) * getWidth() + lod; |
|
|
|
|
buffer.put(idx); |
|
|
|
|
idx = (row+2*lod)*getWidth(); |
|
|
|
|
idx = (row + 2 * lod) * getWidth(); |
|
|
|
|
buffer.put(idx); |
|
|
|
|
if (row < getWidth()-lod-2-1) { //if not the last one
|
|
|
|
|
idx = (row+2*lod)*getWidth()+lod; |
|
|
|
|
if (row < getWidth() - lod - 2 - 1) { //if not the last one
|
|
|
|
|
idx = (row + 2 * lod) * getWidth() + lod; |
|
|
|
|
buffer.put(idx); |
|
|
|
|
idx = (row+2*lod)*getWidth(); |
|
|
|
|
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) { |
|
|
|
|
int idx = row*getWidth(); |
|
|
|
|
for (int row = lod; row < getWidth() - lod; row += lod) { |
|
|
|
|
int idx = row * getWidth(); |
|
|
|
|
buffer.put(idx); |
|
|
|
|
idx = row*getWidth()+lod; |
|
|
|
|
idx = row * getWidth() + lod; |
|
|
|
|
buffer.put(idx); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
buffer.put(getWidth()*(getWidth()-1)); |
|
|
|
|
buffer.put(getWidth() * (getWidth() - 1)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//System.out.println("\nbuffer left: "+(buffer.getCount()-runningBufferCount));
|
|
|
|
@ -300,39 +303,39 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
|
|
|
|
|
// bottom
|
|
|
|
|
if (bottomLod) { // if lower LOD
|
|
|
|
|
if (leftLod) |
|
|
|
|
buffer.put(getWidth()*(getWidth()-1)); |
|
|
|
|
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
|
|
|
|
|
for (int col=0; col<getWidth()-lod; col+=2*lod) { |
|
|
|
|
int idx = getWidth()*(getWidth()-1-lod)+col+lod; |
|
|
|
|
for (int col = 0; col < getWidth() - lod; col += 2 * lod) { |
|
|
|
|
int idx = getWidth() * (getWidth() - 1 - lod) + col + lod; |
|
|
|
|
buffer.put(idx); |
|
|
|
|
idx = getWidth()*(getWidth()-1)+col+2*lod; |
|
|
|
|
idx = getWidth() * (getWidth() - 1) + col + 2 * lod; |
|
|
|
|
buffer.put(idx); |
|
|
|
|
if (col < getWidth()-1-2*lod) { //if not the last one
|
|
|
|
|
idx = getWidth()*(getWidth()-1-lod)+col+2*lod; |
|
|
|
|
if (col < getWidth() - 1 - 2 * lod) { //if not the last one
|
|
|
|
|
idx = getWidth() * (getWidth() - 1 - lod) + col + 2 * lod; |
|
|
|
|
buffer.put(idx); |
|
|
|
|
idx = getWidth()*(getWidth()-1)+col+2*lod; |
|
|
|
|
idx = getWidth() * (getWidth() - 1) + col + 2 * lod; |
|
|
|
|
buffer.put(idx); |
|
|
|
|
} else { |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
if (leftLod) { |
|
|
|
|
buffer.put(getWidth()*(getWidth()-1)); |
|
|
|
|
buffer.put(getWidth() * (getWidth() - 1)); |
|
|
|
|
} |
|
|
|
|
for (int col=lod; col<getWidth()-lod; col+=lod) { |
|
|
|
|
int idx = getWidth()*(getWidth()-1-lod) + col; // up
|
|
|
|
|
for (int col = lod; col < getWidth() - lod; col += lod) { |
|
|
|
|
int idx = getWidth() * (getWidth() - 1 - lod) + col; // up
|
|
|
|
|
buffer.put(idx); |
|
|
|
|
idx = getWidth()*(getWidth()-1) + col; // down
|
|
|
|
|
idx = getWidth() * (getWidth() - 1) + col; // down
|
|
|
|
|
buffer.put(idx); |
|
|
|
|
} |
|
|
|
|
//buffer.put(getWidth()*getWidth()-1-lod); // <-- THIS caused holes at the end!
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
buffer.put(getWidth()*getWidth()-1); |
|
|
|
|
buffer.put(getWidth() * getWidth() - 1); |
|
|
|
|
|
|
|
|
|
//System.out.println("\nbuffer bottom: "+(buffer.getCount()-runningBufferCount));
|
|
|
|
|
//runningBufferCount = buffer.getCount();
|
|
|
|
@ -340,39 +343,41 @@ 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++) |
|
|
|
|
buffer.put(getWidth()*getWidth()-1); |
|
|
|
|
for (int i = buffer.getCount(); i < numIndexes; i++) { |
|
|
|
|
buffer.put(getWidth() * getWidth() - 1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return buffer.delegate; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public IntBuffer writeIndexArrayLodVariable(IntBuffer store, int lod, int rightLod, int topLod, int leftLod, int bottomLod){ |
|
|
|
|
public IntBuffer writeIndexArrayLodVariable(IntBuffer store, int lod, int rightLod, int topLod, int leftLod, int bottomLod) { |
|
|
|
|
|
|
|
|
|
IntBuffer buffer2 = store; |
|
|
|
|
int numIndexes = calculateNumIndexesLodDiff(lod); |
|
|
|
|
if (store == null) |
|
|
|
|
if (store == null) { |
|
|
|
|
buffer2 = BufferUtils.createIntBuffer(numIndexes); |
|
|
|
|
} |
|
|
|
|
VerboseIntBuffer buffer = new VerboseIntBuffer(buffer2); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// generate center squares minus the edges
|
|
|
|
|
//System.out.println("for (x="+lod+"; x<"+(getWidth()-(2*lod))+"; x+="+lod+")");
|
|
|
|
|
//System.out.println(" for (z="+lod+"; z<"+(getWidth()-(1*lod))+"; z+="+lod+")");
|
|
|
|
|
for (int r=lod; r<getWidth()-(2*lod); r+=lod) { // row
|
|
|
|
|
int rowIdx = r*getWidth(); |
|
|
|
|
int nextRowIdx = (r+1*lod)*getWidth(); |
|
|
|
|
for (int c=lod; c<getWidth()-(1*lod); c+=lod) { // column
|
|
|
|
|
int idx = rowIdx+c; |
|
|
|
|
for (int r = lod; r < getWidth() - (2 * lod); r += lod) { // row
|
|
|
|
|
int rowIdx = r * getWidth(); |
|
|
|
|
int nextRowIdx = (r + 1 * lod) * getWidth(); |
|
|
|
|
for (int c = lod; c < getWidth() - (1 * lod); c += lod) { // column
|
|
|
|
|
int idx = rowIdx + c; |
|
|
|
|
buffer.put(idx); |
|
|
|
|
idx = nextRowIdx+c; |
|
|
|
|
idx = nextRowIdx + c; |
|
|
|
|
buffer.put(idx); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// add degenerate triangles
|
|
|
|
|
if (r < getWidth()-(3*lod)) { |
|
|
|
|
int idx = nextRowIdx+getWidth()-(1*lod)-1; |
|
|
|
|
if (r < getWidth() - (3 * lod)) { |
|
|
|
|
int idx = nextRowIdx + getWidth() - (1 * lod) - 1; |
|
|
|
|
buffer.put(idx); |
|
|
|
|
idx = nextRowIdx+(1*lod); // inset by 1
|
|
|
|
|
idx = nextRowIdx + (1 * lod); // inset by 1
|
|
|
|
|
buffer.put(idx); |
|
|
|
|
//System.out.println("");
|
|
|
|
|
} |
|
|
|
@ -384,24 +389,24 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// right
|
|
|
|
|
int br = getWidth()*(getWidth()-lod)-1-lod; |
|
|
|
|
int br = getWidth() * (getWidth() - lod) - 1 - lod; |
|
|
|
|
buffer.put(br); // bottom right -1
|
|
|
|
|
int corner = getWidth()*getWidth()-1; |
|
|
|
|
int corner = getWidth() * getWidth() - 1; |
|
|
|
|
buffer.put(corner); // bottom right corner
|
|
|
|
|
if (rightLod>lod) { // if lower LOD
|
|
|
|
|
if (rightLod > lod) { // if lower LOD
|
|
|
|
|
int idx = corner; |
|
|
|
|
int it = (getWidth()-1)/rightLod; // iterations
|
|
|
|
|
int lodDiff = rightLod/lod; |
|
|
|
|
for (int i=it; i>0; i--) { // for each lod level of the neighbour
|
|
|
|
|
idx = getWidth()*(i*rightLod+1)-1; |
|
|
|
|
for (int j=1; j<=lodDiff; j++) { // for each section in that lod level
|
|
|
|
|
int idxB = idx - (getWidth()*(j*lod)) - lod; |
|
|
|
|
int it = (getWidth() - 1) / rightLod; // iterations
|
|
|
|
|
int lodDiff = rightLod / lod; |
|
|
|
|
for (int i = it; i > 0; i--) { // for each lod level of the neighbour
|
|
|
|
|
idx = getWidth() * (i * rightLod + 1) - 1; |
|
|
|
|
for (int j = 1; j <= lodDiff; j++) { // for each section in that lod level
|
|
|
|
|
int idxB = idx - (getWidth() * (j * lod)) - lod; |
|
|
|
|
|
|
|
|
|
if (j == lodDiff && i == 1) {// the last one
|
|
|
|
|
buffer.put(getWidth()-1); |
|
|
|
|
buffer.put(getWidth() - 1); |
|
|
|
|
} else if (j == lodDiff) { |
|
|
|
|
buffer.put(idxB); |
|
|
|
|
buffer.put(idxB+lod); |
|
|
|
|
buffer.put(idxB + lod); |
|
|
|
|
} else { |
|
|
|
|
buffer.put(idxB); |
|
|
|
|
buffer.put(idx); |
|
|
|
@ -409,17 +414,17 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// reset winding order
|
|
|
|
|
buffer.put(getWidth()*(lod+1)-lod-1); // top-right +1row
|
|
|
|
|
buffer.put(getWidth()-1);// top-right
|
|
|
|
|
buffer.put(getWidth() * (lod + 1) - lod - 1); // top-right +1row
|
|
|
|
|
buffer.put(getWidth() - 1);// top-right
|
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
buffer.put(corner);//br+1);//degenerate to flip winding order
|
|
|
|
|
for (int row=getWidth()-lod; row>lod; row-=lod) { |
|
|
|
|
int idx = row*getWidth()-1; // mult to get row
|
|
|
|
|
for (int row = getWidth() - lod; row > lod; row -= lod) { |
|
|
|
|
int idx = row * getWidth() - 1; // mult to get row
|
|
|
|
|
buffer.put(idx); |
|
|
|
|
buffer.put(idx-lod); |
|
|
|
|
buffer.put(idx - lod); |
|
|
|
|
} |
|
|
|
|
buffer.put(getWidth()-1); |
|
|
|
|
buffer.put(getWidth() - 1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -430,26 +435,26 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
//System.out.println("\ntop:");
|
|
|
|
|
|
|
|
|
|
// top (the order gets reversed here so the diagonals line up)
|
|
|
|
|
if (topLod>lod) { // if lower LOD
|
|
|
|
|
if (rightLod>lod) { |
|
|
|
|
if (topLod > lod) { // if lower LOD
|
|
|
|
|
if (rightLod > lod) { |
|
|
|
|
// need to flip winding order
|
|
|
|
|
buffer.put(getWidth()-1); |
|
|
|
|
buffer.put(getWidth()*lod -1); |
|
|
|
|
buffer.put(getWidth()-1); |
|
|
|
|
} |
|
|
|
|
int idx = getWidth()-1; |
|
|
|
|
int it = (getWidth()-1)/topLod; // iterations
|
|
|
|
|
int lodDiff = topLod/lod; |
|
|
|
|
for (int i=it; i>0; i--) { // for each lod level of the neighbour
|
|
|
|
|
idx = (i*topLod); |
|
|
|
|
for (int j=1; j<=lodDiff; j++) { // for each section in that lod level
|
|
|
|
|
int idxB = lod*getWidth() +(i*topLod) - (j*lod); |
|
|
|
|
buffer.put(getWidth() - 1); |
|
|
|
|
buffer.put(getWidth() * lod - 1); |
|
|
|
|
buffer.put(getWidth() - 1); |
|
|
|
|
} |
|
|
|
|
int idx = getWidth() - 1; |
|
|
|
|
int it = (getWidth() - 1) / topLod; // iterations
|
|
|
|
|
int lodDiff = topLod / lod; |
|
|
|
|
for (int i = it; i > 0; i--) { // for each lod level of the neighbour
|
|
|
|
|
idx = (i * topLod); |
|
|
|
|
for (int j = 1; j <= lodDiff; j++) { // for each section in that lod level
|
|
|
|
|
int idxB = lod * getWidth() + (i * topLod) - (j * lod); |
|
|
|
|
|
|
|
|
|
if (j == lodDiff && i == 1) {// the last one
|
|
|
|
|
buffer.put(0); |
|
|
|
|
} else if (j == lodDiff) { |
|
|
|
|
buffer.put(idxB); |
|
|
|
|
buffer.put(idx-topLod); |
|
|
|
|
buffer.put(idx - topLod); |
|
|
|
|
} else { |
|
|
|
|
buffer.put(idxB); |
|
|
|
|
buffer.put(idx); |
|
|
|
@ -457,10 +462,11 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
if (rightLod>lod) |
|
|
|
|
buffer.put(getWidth()-1); |
|
|
|
|
for (int col=getWidth()-1-lod; col>0; col-=lod) { |
|
|
|
|
int idx = col + (lod*getWidth()); |
|
|
|
|
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); |
|
|
|
|
idx = col; |
|
|
|
|
buffer.put(idx); |
|
|
|
@ -475,21 +481,21 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
//System.out.println("\nleft:");
|
|
|
|
|
|
|
|
|
|
// left
|
|
|
|
|
if (leftLod>lod) { // if lower LOD
|
|
|
|
|
if (leftLod > lod) { // if lower LOD
|
|
|
|
|
|
|
|
|
|
int idx = 0; |
|
|
|
|
int it = (getWidth()-1)/leftLod; // iterations
|
|
|
|
|
int lodDiff = leftLod/lod; |
|
|
|
|
for (int i=0; i<it; i++) { // for each lod level of the neighbour
|
|
|
|
|
idx = getWidth()*(i*leftLod); |
|
|
|
|
for (int j=1; j<=lodDiff; j++) { // for each section in that lod level
|
|
|
|
|
int idxB = idx +(getWidth()*(j*lod)) +lod; |
|
|
|
|
|
|
|
|
|
if (j == lodDiff && i == it-1) {// the last one
|
|
|
|
|
buffer.put(getWidth()*getWidth() - getWidth()); |
|
|
|
|
int it = (getWidth() - 1) / leftLod; // iterations
|
|
|
|
|
int lodDiff = leftLod / lod; |
|
|
|
|
for (int i = 0; i < it; i++) { // for each lod level of the neighbour
|
|
|
|
|
idx = getWidth() * (i * leftLod); |
|
|
|
|
for (int j = 1; j <= lodDiff; j++) { // for each section in that lod level
|
|
|
|
|
int idxB = idx + (getWidth() * (j * lod)) + lod; |
|
|
|
|
|
|
|
|
|
if (j == lodDiff && i == it - 1) {// the last one
|
|
|
|
|
buffer.put(getWidth() * getWidth() - getWidth()); |
|
|
|
|
} else if (j == lodDiff) { |
|
|
|
|
buffer.put(idxB); |
|
|
|
|
buffer.put(idxB-lod); |
|
|
|
|
buffer.put(idxB - lod); |
|
|
|
|
} else { |
|
|
|
|
buffer.put(idxB); |
|
|
|
|
buffer.put(idx); |
|
|
|
@ -499,15 +505,15 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
buffer.put(0); |
|
|
|
|
buffer.put(getWidth()*lod + lod); |
|
|
|
|
buffer.put(getWidth() * lod + lod); |
|
|
|
|
buffer.put(0); |
|
|
|
|
for (int row=lod; row<getWidth()-lod; row+=lod) { |
|
|
|
|
int idx = row*getWidth(); |
|
|
|
|
for (int row = lod; row < getWidth() - lod; row += lod) { |
|
|
|
|
int idx = row * getWidth(); |
|
|
|
|
buffer.put(idx); |
|
|
|
|
idx = row*getWidth()+lod; |
|
|
|
|
idx = row * getWidth() + lod; |
|
|
|
|
buffer.put(idx); |
|
|
|
|
} |
|
|
|
|
buffer.put(getWidth()*(getWidth()-1)); |
|
|
|
|
buffer.put(getWidth() * (getWidth() - 1)); |
|
|
|
|
} |
|
|
|
|
//buffer.put(getWidth()*(getWidth()-1));
|
|
|
|
|
|
|
|
|
@ -519,26 +525,26 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
//System.out.println("\nbottom");
|
|
|
|
|
|
|
|
|
|
// bottom
|
|
|
|
|
if (bottomLod>lod) { // if lower LOD
|
|
|
|
|
if (leftLod>lod) { |
|
|
|
|
buffer.put(getWidth()*(getWidth()-1)); |
|
|
|
|
buffer.put(getWidth()*(getWidth()-lod)); |
|
|
|
|
buffer.put(getWidth()*(getWidth()-1)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int idx = getWidth()*getWidth() - getWidth(); |
|
|
|
|
int it = (getWidth()-1)/bottomLod; // iterations
|
|
|
|
|
int lodDiff = bottomLod/lod; |
|
|
|
|
for (int i=0; i<it; i++) { // for each lod level of the neighbour
|
|
|
|
|
idx = getWidth()*getWidth() - getWidth() + (i*bottomLod); |
|
|
|
|
for (int j=1; j<=lodDiff; j++) { // for each section in that lod level
|
|
|
|
|
int idxB = idx - (getWidth()*lod) +j*lod; |
|
|
|
|
|
|
|
|
|
if (j == lodDiff && i == it-1) {// the last one
|
|
|
|
|
buffer.put(getWidth()*getWidth()-1); |
|
|
|
|
if (bottomLod > lod) { // if lower LOD
|
|
|
|
|
if (leftLod > lod) { |
|
|
|
|
buffer.put(getWidth() * (getWidth() - 1)); |
|
|
|
|
buffer.put(getWidth() * (getWidth() - lod)); |
|
|
|
|
buffer.put(getWidth() * (getWidth() - 1)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int idx = getWidth() * getWidth() - getWidth(); |
|
|
|
|
int it = (getWidth() - 1) / bottomLod; // iterations
|
|
|
|
|
int lodDiff = bottomLod / lod; |
|
|
|
|
for (int i = 0; i < it; i++) { // for each lod level of the neighbour
|
|
|
|
|
idx = getWidth() * getWidth() - getWidth() + (i * bottomLod); |
|
|
|
|
for (int j = 1; j <= lodDiff; j++) { // for each section in that lod level
|
|
|
|
|
int idxB = idx - (getWidth() * lod) + j * lod; |
|
|
|
|
|
|
|
|
|
if (j == lodDiff && i == it - 1) {// the last one
|
|
|
|
|
buffer.put(getWidth() * getWidth() - 1); |
|
|
|
|
} else if (j == lodDiff) { |
|
|
|
|
buffer.put(idxB); |
|
|
|
|
buffer.put(idx+bottomLod); |
|
|
|
|
buffer.put(idx + bottomLod); |
|
|
|
|
} else { |
|
|
|
|
buffer.put(idxB); |
|
|
|
|
buffer.put(idx); |
|
|
|
@ -546,21 +552,21 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
if (leftLod>lod) { |
|
|
|
|
buffer.put(getWidth()*(getWidth()-1)); |
|
|
|
|
buffer.put(getWidth()*getWidth() - (getWidth()*lod)+lod); |
|
|
|
|
buffer.put(getWidth()*(getWidth()-1)); |
|
|
|
|
if (leftLod > lod) { |
|
|
|
|
buffer.put(getWidth() * (getWidth() - 1)); |
|
|
|
|
buffer.put(getWidth() * getWidth() - (getWidth() * lod) + lod); |
|
|
|
|
buffer.put(getWidth() * (getWidth() - 1)); |
|
|
|
|
} |
|
|
|
|
for (int col=lod; col<getWidth()-lod; col+=lod) { |
|
|
|
|
int idx = getWidth()*(getWidth()-1-lod) + col; // up
|
|
|
|
|
for (int col = lod; col < getWidth() - lod; col += lod) { |
|
|
|
|
int idx = getWidth() * (getWidth() - 1 - lod) + col; // up
|
|
|
|
|
buffer.put(idx); |
|
|
|
|
idx = getWidth()*(getWidth()-1) + col; // down
|
|
|
|
|
idx = getWidth() * (getWidth() - 1) + col; // down
|
|
|
|
|
buffer.put(idx); |
|
|
|
|
} |
|
|
|
|
//buffer.put(getWidth()*getWidth()-1-lod); // <-- THIS caused holes at the end!
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
buffer.put(getWidth()*getWidth()-1); |
|
|
|
|
buffer.put(getWidth() * getWidth() - 1); |
|
|
|
|
|
|
|
|
|
//System.out.println("\nbuffer bottom: "+(buffer.getCount()-runningBufferCount));
|
|
|
|
|
//runningBufferCount = buffer.getCount();
|
|
|
|
@ -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++) |
|
|
|
|
buffer.put(getWidth()*getWidth()-1); |
|
|
|
|
for (int i = buffer.getCount(); i < numIndexes; i++) { |
|
|
|
|
buffer.put(getWidth() * getWidth() - 1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return buffer.delegate; |
|
|
|
|
} |
|
|
|
@ -586,46 +593,48 @@ 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); |
|
|
|
|
} |
|
|
|
|
int length = getWidth() - 1; // make it even for lod calc
|
|
|
|
|
int side = (length / lod) + 1 - (2); |
|
|
|
|
//System.out.println("side: "+side);
|
|
|
|
|
int num = side*side*2; |
|
|
|
|
int num = side * side * 2; |
|
|
|
|
//System.out.println("num: "+num);
|
|
|
|
|
num -= 2*side; // remove one first row and one last row (they are only hit once each)
|
|
|
|
|
num -= 2 * side; // remove one first row and one last row (they are only hit once each)
|
|
|
|
|
//System.out.println("num2: "+num);
|
|
|
|
|
// now get the degenerate indexes that exist between strip rows
|
|
|
|
|
int degenerates = 2*(side-(2)); // every row except the first and last
|
|
|
|
|
int degenerates = 2 * (side - (2)); // every row except the first and last
|
|
|
|
|
num += degenerates; |
|
|
|
|
//System.out.println("degenerates: "+degenerates);
|
|
|
|
|
|
|
|
|
|
//System.out.println("center, before edges: "+num);
|
|
|
|
|
|
|
|
|
|
num += (getWidth()/lod)*2 *4; |
|
|
|
|
num += (getWidth() / lod) * 2 * 4; |
|
|
|
|
num++; |
|
|
|
|
|
|
|
|
|
num+=10;// TODO remove me: extra
|
|
|
|
|
num += 10;// TODO remove me: extra
|
|
|
|
|
//System.out.println("Index buffer size: "+num);
|
|
|
|
|
return num; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@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 != null) { |
|
|
|
|
if (store.remaining() < getWidth() * getHeight() * 3) { |
|
|
|
|
throw new BufferUnderflowException(); |
|
|
|
|
}else{ |
|
|
|
|
store = BufferUtils.createFloatBuffer(getWidth()*getHeight()*3); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
store = BufferUtils.createFloatBuffer(getWidth() * getHeight() * 3); |
|
|
|
|
} |
|
|
|
|
store.rewind(); |
|
|
|
|
|
|
|
|
@ -636,66 +645,66 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
Vector3f bottomPoint = new Vector3f(); |
|
|
|
|
|
|
|
|
|
// calculate normals for each polygon
|
|
|
|
|
for (int r=0; r<getHeight(); r++) { |
|
|
|
|
for (int c=0; c<getWidth(); c++) { |
|
|
|
|
for (int r = 0; r < getHeight(); r++) { |
|
|
|
|
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(); |
|
|
|
|
|
|
|
|
|
if (r == 0) { // first row
|
|
|
|
|
if (c == 0) { // first column
|
|
|
|
|
rightPoint.set(c+1, getValue(c+1,r), r); |
|
|
|
|
bottomPoint.set(c, getValue(c,r+1), r+1); |
|
|
|
|
rightPoint.set(c + 1, getValue(c + 1, r), r); |
|
|
|
|
bottomPoint.set(c, getValue(c, r + 1), r + 1); |
|
|
|
|
normal.set(getNormal(bottomPoint, rootPoint, rightPoint)); |
|
|
|
|
} else if (c == getWidth()-1) { // last column
|
|
|
|
|
leftPoint.set(c-1, getValue(c-1,r), r); |
|
|
|
|
bottomPoint.set(c, getValue(c,r+1), r+1); |
|
|
|
|
} else if (c == getWidth() - 1) { // last column
|
|
|
|
|
leftPoint.set(c - 1, getValue(c - 1, r), r); |
|
|
|
|
bottomPoint.set(c, getValue(c, r + 1), r + 1); |
|
|
|
|
normal.set(getNormal(leftPoint, rootPoint, bottomPoint)); |
|
|
|
|
} else { // all middle columns
|
|
|
|
|
leftPoint.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); |
|
|
|
|
leftPoint.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); |
|
|
|
|
Vector3f n1 = getNormal(leftPoint, rootPoint, bottomPoint); |
|
|
|
|
Vector3f n2 = getNormal(bottomPoint, rootPoint, rightPoint); |
|
|
|
|
normal.set(n1.add(n2).normalizeLocal()); |
|
|
|
|
} |
|
|
|
|
} else if (r == getHeight()-1) { // last row
|
|
|
|
|
} else if (r == getHeight() - 1) { // last row
|
|
|
|
|
if (c == 0) { // first column
|
|
|
|
|
topPoint.set(c, getValue(c,r-1), r-1); |
|
|
|
|
rightPoint.set(c+1, getValue(c+1, r), r); |
|
|
|
|
topPoint.set(c, getValue(c, r - 1), r - 1); |
|
|
|
|
rightPoint.set(c + 1, getValue(c + 1, r), r); |
|
|
|
|
normal.set(getNormal(rightPoint, rootPoint, topPoint)); |
|
|
|
|
} else if (c == getWidth()-1) { // last column
|
|
|
|
|
topPoint.set(c, getValue(c,r-1), r-1); |
|
|
|
|
leftPoint.set(c-1, getValue(c-1,r), r); |
|
|
|
|
} else if (c == getWidth() - 1) { // last column
|
|
|
|
|
topPoint.set(c, getValue(c, r - 1), r - 1); |
|
|
|
|
leftPoint.set(c - 1, getValue(c - 1, r), r); |
|
|
|
|
normal.set(getNormal(topPoint, rootPoint, leftPoint)); |
|
|
|
|
} else { // all middle columns
|
|
|
|
|
topPoint.set(c, getValue(c,r-1), r-1); |
|
|
|
|
leftPoint.set(c-1, getValue(c-1,r), r); |
|
|
|
|
rightPoint.set(c+1, getValue(c+1,r), r); |
|
|
|
|
topPoint.set(c, getValue(c, r - 1), r - 1); |
|
|
|
|
leftPoint.set(c - 1, getValue(c - 1, r), r); |
|
|
|
|
rightPoint.set(c + 1, getValue(c + 1, r), r); |
|
|
|
|
Vector3f n1 = getNormal(topPoint, rootPoint, leftPoint); |
|
|
|
|
Vector3f n2 = getNormal(rightPoint, rootPoint, topPoint); |
|
|
|
|
normal.set(n1.add(n2).normalizeLocal()); |
|
|
|
|
} |
|
|
|
|
} else { // all middle rows
|
|
|
|
|
if (c == 0) { // first column
|
|
|
|
|
topPoint.set(c, getValue(c,r-1), r-1); |
|
|
|
|
rightPoint.set(c+1, getValue(c+1,r), r); |
|
|
|
|
bottomPoint.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); |
|
|
|
|
bottomPoint.set(c, getValue(c, r + 1), r + 1); |
|
|
|
|
Vector3f n1 = getNormal(rightPoint, rootPoint, topPoint); |
|
|
|
|
Vector3f n2 = getNormal(bottomPoint, rootPoint, rightPoint); |
|
|
|
|
normal.set(n1.add(n2).normalizeLocal()); |
|
|
|
|
} else if (c == getWidth()-1) { // last column
|
|
|
|
|
topPoint.set(c, getValue(c,r-1), r-1); |
|
|
|
|
leftPoint.set(c-1, getValue(c-1,r), r); |
|
|
|
|
bottomPoint.set(c, getValue(c,r+1), r+1); |
|
|
|
|
} else if (c == getWidth() - 1) { // last column
|
|
|
|
|
topPoint.set(c, getValue(c, r - 1), r - 1); |
|
|
|
|
leftPoint.set(c - 1, getValue(c - 1, r), r); |
|
|
|
|
bottomPoint.set(c, getValue(c, r + 1), r + 1); |
|
|
|
|
Vector3f n1 = getNormal(topPoint, rootPoint, leftPoint); |
|
|
|
|
Vector3f n2 = getNormal(leftPoint, rootPoint, bottomPoint); |
|
|
|
|
normal.set(n1.add(n2).normalizeLocal()); |
|
|
|
|
} else { // all middle columns
|
|
|
|
|
topPoint.set(c, getValue(c,r-1), r-1); |
|
|
|
|
leftPoint.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); |
|
|
|
|
topPoint.set(c, getValue(c, r - 1), r - 1); |
|
|
|
|
leftPoint.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); |
|
|
|
|
Vector3f n1 = getNormal(topPoint, rootPoint, leftPoint); |
|
|
|
|
Vector3f n2 = getNormal(leftPoint, rootPoint, bottomPoint); |
|
|
|
|
Vector3f n3 = getNormal(bottomPoint, rootPoint, rightPoint); |
|
|
|
@ -704,7 +713,7 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
BufferUtils.setInBuffer(normal, store, (r*getWidth()+c)); // save the normal
|
|
|
|
|
BufferUtils.setInBuffer(normal, store, (r * getWidth() + c)); // save the normal
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -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; |
|
|
|
|
} |
|
|
|
@ -807,12 +817,13 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
* @return |
|
|
|
|
*/ |
|
|
|
|
protected Triangle[] getGridTrianglesAtPoint(float x, float z) { |
|
|
|
|
int gridX = (int)x; |
|
|
|
|
int gridY = (int)z; |
|
|
|
|
int gridX = (int) x; |
|
|
|
|
int gridY = (int) z; |
|
|
|
|
|
|
|
|
|
int index = findClosestHeightIndex(gridX,gridY); |
|
|
|
|
if (index < 0) |
|
|
|
|
int index = findClosestHeightIndex(gridX, gridY); |
|
|
|
|
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()); |
|
|
|
@ -823,7 +834,7 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
float h4 = hdata.get(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)) { |
|
|
|
|
// top left or bottom right grid point
|
|
|
|
|
t.get(0).x = (gridX); |
|
|
|
|
t.get(0).y = (h1); |
|
|
|
@ -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); |
|
|
|
@ -876,7 +886,7 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
t2.get(2).z = (gridY + 1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return new Triangle[]{t,t2}; |
|
|
|
|
return new Triangle[]{t, t2}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -889,7 +899,7 @@ public class LODGeomap extends BufferGeomap { |
|
|
|
|
protected Triangle getTriangleAtPoint(float x, float z) { |
|
|
|
|
Triangle[] triangles = getGridTrianglesAtPoint(x, z); |
|
|
|
|
if (triangles == null) { |
|
|
|
|
System.out.println("x,z: "+x+","+z); |
|
|
|
|
System.out.println("x,z: " + x + "," + z); |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
Vector2f point = new Vector2f(x, z); |
|
|
|
@ -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); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|