/** * 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) { lod = 1; } 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; //System.out.println("num: "+num); 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 num += degenerates; //System.out.println("degenerates: "+degenerates); //System.out.println("center, before edges: "+num); num += (getWidth() / lod) * 2 * 4; num++; num += 10;// TODO remove me: extra //System.out.println("Index buffer size: "+num); return num; }
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); if (r < getWidth() - (3 * lod)) { int idx = nextRowIdx + getWidth() - (1 * lod) - 1; buffer.put(idx); idx = nextRowIdx + (1 * lod); // inset by 1 int br = getWidth() * (getWidth() - lod) - 1 - lod; int corner = getWidth() * getWidth() - 1; 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; buffer.put(idx); if (row > lod + 1) { //if not the last one idx = (row - lod) * getWidth() - 1 - lod; buffer.put(idx); idx = (row - lod) * getWidth() - 1; buffer.put(idx); } else { for (int row = getWidth() - lod; row > lod; row -= 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; buffer.put(idx); if (r < getWidth() - (3 * lod)) { int idx = nextRowIdx + getWidth() - (1 * lod) - 1; buffer.put(idx); idx = nextRowIdx + (1 * lod); // inset by 1 int br = getWidth() * (getWidth() - lod) - 1 - lod; int corner = getWidth() * getWidth() - 1; 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; buffer.put(getWidth() - 1); } else if (j == lodDiff) { buffer.put(idxB); buffer.put(getWidth() * (lod + 1) - lod - 1); // top-right +1row buffer.put(getWidth() - 1);// top-right
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); } if (offset == null) { offset = new Vector2f(); } Vector2f tcStore = new Vector2f(); // work from bottom of heightmap up, so we don't flip the coords for (int y = getHeight() - 1; y >= 0; y--) { 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); } } return store; }
if (tangentStore.remaining() < getWidth() * getHeight() * 3) { throw new BufferUnderflowException(); tangentStore = BufferUtils.createFloatBuffer(getWidth() * getHeight() * 3); if (binormalStore.remaining() < getWidth() * getHeight() * 3) { throw new BufferUnderflowException(); binormalStore = BufferUtils.createFloatBuffer(getWidth() * getHeight() * 3); for (int c = 0; c < getWidth(); c++) { int idx = (r * getWidth() + c) * 3; normal.set(normalBuffer.get(idx), normalBuffer.get(idx+1), normalBuffer.get(idx+2)); tangent.set(normal.cross(new Vector3f(0,0,1))); binormal.set(new Vector3f(1,0,0).cross(normal)); BufferUtils.setInBuffer(tangent.normalizeLocal(), tangentStore, (r * getWidth() + c)); // save the tangent BufferUtils.setInBuffer(binormal.normalizeLocal(), binormalStore, (r * getWidth() + c)); // save the binormal
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 texb = writeTexCoordArray(null, tcOffset, tcScale, offsetAmount, totalSize); FloatBuffer nb = writeNormalArray(null, scale); Buffer ib; IndexBuffer idxB = writeIndexArrayLodDiff(lod, rightLod, topLod, leftLod, bottomLod, totalSize); if (idxB.getBuffer() instanceof IntBuffer) ib = (IntBuffer)idxB.getBuffer(); else ib = (ShortBuffer)idxB.getBuffer(); FloatBuffer bb = BufferUtils.createFloatBuffer(getWidth() * getHeight() * 3); FloatBuffer tanb = BufferUtils.createFloatBuffer(getWidth() * getHeight() * 3); writeTangentArray(nb, tanb, bb, texb, scale); Mesh m = new Mesh(); m.setMode(Mode.TriangleStrip); m.setBuffer(Type.Position, 3, pb); m.setBuffer(Type.Normal, 3, nb); m.setBuffer(Type.Tangent, 3, tanb); m.setBuffer(Type.Binormal, 3, bb); m.setBuffer(Type.TexCoord, 2, texb); if (ib instanceof IntBuffer) m.setBuffer(Type.Index, 3, (IntBuffer)ib); else if (ib instanceof ShortBuffer) m.setBuffer(Type.Index, 3, (ShortBuffer)ib); m.setStatic(); m.updateBound(); return m; }
if (store.remaining() < getWidth() * getHeight() * 3) { throw new BufferUnderflowException(); store = BufferUtils.createFloatBuffer(getWidth() * getHeight() * 3); for (int c = 0; c < getWidth(); c++) { bottomPoint.set(0, getValue(c, r + 1), 1); getNormal(bottomPoint, rootPoint, rightPoint, scale, normal); } else if (c == getWidth() - 1) { // last column leftPoint.set(-1, getValue(c - 1, r), 0); bottomPoint.set(0, getValue(c, r + 1), 1); rightPoint.set(1, getValue(c + 1, r), 0); getNormal(rightPoint, rootPoint, topPoint, scale, normal); } else if (c == getWidth() - 1) { // last column topPoint.set(0, getValue(c, r - 1), -1); leftPoint.set(-1, getValue(c - 1, r), 0); } else if (c == getWidth() - 1) { // last column topPoint.set(0, getValue(c, r - 1), -1); leftPoint.set(-1, getValue(c - 1, r), 0); BufferUtils.setInBuffer(normal, store, (r * getWidth() + c)); // save the normal
/** * 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) { lod = 1; } 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; //System.out.println("num: "+num); 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 num += degenerates; //System.out.println("degenerates: "+degenerates); //System.out.println("center, before edges: "+num); num += (getWidth() / lod) * 2 * 4; num++; num += 10;// TODO remove me: extra //System.out.println("Index buffer size: "+num); return num; }
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); if (r < getWidth() - (3 * lod)) { int idx = nextRowIdx + getWidth() - (1 * lod) - 1; buffer.put(idx); idx = nextRowIdx + (1 * lod); // inset by 1 int br = getWidth() * (getWidth() - lod) - 1 - lod; int corner = getWidth() * getWidth() - 1; 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; buffer.put(idx); if (row > lod + 1) { //if not the last one idx = (row - lod) * getWidth() - 1 - lod; buffer.put(idx); idx = (row - lod) * getWidth() - 1; buffer.put(idx); } else { for (int row = getWidth() - lod; row > lod; row -= 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; buffer.put(idx); if (r < getWidth() - (3 * lod)) { int idx = nextRowIdx + getWidth() - (1 * lod) - 1; buffer.put(idx); idx = nextRowIdx + (1 * lod); // inset by 1 int br = getWidth() * (getWidth() - lod) - 1 - lod; int corner = getWidth() * getWidth() - 1; 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; buffer.put(getWidth() - 1); } else if (j == lodDiff) { buffer.put(idxB); buffer.put(getWidth() * (lod + 1) - lod - 1); // top-right +1row buffer.put(getWidth() - 1);// top-right
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); } if (offset == null) { offset = new Vector2f(); } Vector2f tcStore = new Vector2f(); // work from bottom of heightmap up, so we don't flip the coords for (int y = getHeight() - 1; y >= 0; y--) { 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); } } return store; }
if (tangentStore.remaining() < getWidth() * getHeight() * 3) { throw new BufferUnderflowException(); tangentStore = BufferUtils.createFloatBuffer(getWidth() * getHeight() * 3); if (binormalStore.remaining() < getWidth() * getHeight() * 3) { throw new BufferUnderflowException(); binormalStore = BufferUtils.createFloatBuffer(getWidth() * getHeight() * 3); for (int c = 0; c < getWidth(); c++) { int idx = (r * getWidth() + c) * 3; normal.set(normalBuffer.get(idx), normalBuffer.get(idx+1), normalBuffer.get(idx+2)); tangent.set(normal.cross(new Vector3f(0,0,1))); binormal.set(new Vector3f(1,0,0).cross(normal)); BufferUtils.setInBuffer(tangent.normalizeLocal(), tangentStore, (r * getWidth() + c)); // save the tangent BufferUtils.setInBuffer(binormal.normalizeLocal(), binormalStore, (r * getWidth() + c)); // save the binormal
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 texb = writeTexCoordArray(null, tcOffset, tcScale, offsetAmount, totalSize); FloatBuffer nb = writeNormalArray(null, scale); Buffer ib; IndexBuffer idxB = writeIndexArrayLodDiff(lod, rightLod, topLod, leftLod, bottomLod, totalSize); if (idxB.getBuffer() instanceof IntBuffer) ib = (IntBuffer)idxB.getBuffer(); else ib = (ShortBuffer)idxB.getBuffer(); FloatBuffer bb = BufferUtils.createFloatBuffer(getWidth() * getHeight() * 3); FloatBuffer tanb = BufferUtils.createFloatBuffer(getWidth() * getHeight() * 3); writeTangentArray(nb, tanb, bb, texb, scale); Mesh m = new Mesh(); m.setMode(Mode.TriangleStrip); m.setBuffer(Type.Position, 3, pb); m.setBuffer(Type.Normal, 3, nb); m.setBuffer(Type.Tangent, 3, tanb); m.setBuffer(Type.Binormal, 3, bb); m.setBuffer(Type.TexCoord, 2, texb); if (ib instanceof IntBuffer) m.setBuffer(Type.Index, 3, (IntBuffer)ib); else if (ib instanceof ShortBuffer) m.setBuffer(Type.Index, 3, (ShortBuffer)ib); m.setStatic(); m.updateBound(); return m; }
if (store.remaining() < getWidth() * getHeight() * 3) { throw new BufferUnderflowException(); store = BufferUtils.createFloatBuffer(getWidth() * getHeight() * 3); for (int c = 0; c < getWidth(); c++) { bottomPoint.set(0, getValue(c, r + 1), 1); getNormal(bottomPoint, rootPoint, rightPoint, scale, normal); } else if (c == getWidth() - 1) { // last column leftPoint.set(-1, getValue(c - 1, r), 0); bottomPoint.set(0, getValue(c, r + 1), 1); rightPoint.set(1, getValue(c + 1, r), 0); getNormal(rightPoint, rootPoint, topPoint, scale, normal); } else if (c == getWidth() - 1) { // last column topPoint.set(0, getValue(c, r - 1), -1); leftPoint.set(-1, getValue(c - 1, r), 0); } else if (c == getWidth() - 1) { // last column topPoint.set(0, getValue(c, r - 1), -1); leftPoint.set(-1, getValue(c - 1, r), 0); BufferUtils.setInBuffer(normal, store, (r * getWidth() + c)); // save the normal