159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/* 259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Copyright (c) 2009-2010 jMonkeyEngine 359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * All rights reserved. 459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Redistribution and use in source and binary forms, with or without 659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * modification, are permitted provided that the following conditions are 759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * met: 859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions of source code must retain the above copyright 1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * notice, this list of conditions and the following disclaimer. 1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions in binary form must reproduce the above copyright 1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * notice, this list of conditions and the following disclaimer in the 1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * documentation and/or other materials provided with the distribution. 1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Neither the name of 'jMonkeyEngine' nor the names of its contributors 1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * may be used to endorse or promote products derived from this software 1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * without specific prior written permission. 1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapackage com.jme3.terrain.geomipmap; 3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.JmeExporter; 3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.JmeImporter; 3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.FastMath; 37a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Bartaimport com.jme3.math.Plane; 3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Triangle; 3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Vector2f; 4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Vector3f; 4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.Mesh; 4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.Mesh.Mode; 4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.VertexBuffer.Type; 4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.terrain.GeoMap; 4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.util.BufferUtils; 4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.util.TempVars; 4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.io.IOException; 4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.nio.BufferOverflowException; 4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.nio.BufferUnderflowException; 5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.nio.FloatBuffer; 5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.nio.IntBuffer; 5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/** 5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Produces the mesh for the TerrainPatch. 5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * This LOD algorithm generates a single triangle strip by first building the center of the 5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * mesh, minus one outer edge around it. Then it builds the edges in counter-clockwise order, 5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * starting at the bottom right and working up, then left across the top, then down across the 5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * left, then right across the bottom. 5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * It needs to know what its neighbour's LOD's are so it can stitch the edges. 6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * It creates degenerate polygons in order to keep the winding order of the polygons and to move 6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the strip to a new position while still maintaining the continuity of the overall mesh. These 6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * degenerates are removed quickly by the video card. 6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @author Brent Owens 6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapublic class LODGeomap extends GeoMap { 6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public LODGeomap() { 6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta @Deprecated 7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public LODGeomap(int size, FloatBuffer heightMap) { 7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta super(heightMap, size, size, 1); 7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public LODGeomap(int size, float[] heightMap) { 7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta super(heightMap, size, size, 1); 7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public Mesh createMesh(Vector3f scale, Vector2f tcScale, Vector2f tcOffset, float offsetAmount, int totalSize, boolean center) { 8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return this.createMesh(scale, tcScale, tcOffset, offsetAmount, totalSize, center, 1, false, false, false, false); 8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 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) { 8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta FloatBuffer pb = writeVertexArray(null, scale, center); 8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta FloatBuffer texb = writeTexCoordArray(null, tcOffset, tcScale, offsetAmount, totalSize); 8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta FloatBuffer nb = writeNormalArray(null, scale); 8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta IntBuffer ib = writeIndexArrayLodDiff(null, lod, rightLod, topLod, leftLod, bottomLod); 8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta FloatBuffer bb = BufferUtils.createFloatBuffer(getWidth() * getHeight() * 3); 9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta FloatBuffer tanb = BufferUtils.createFloatBuffer(getWidth() * getHeight() * 3); 91a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta writeTangentArray(nb, tanb, bb, texb, scale); 9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Mesh m = new Mesh(); 9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta m.setMode(Mode.TriangleStrip); 9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta m.setBuffer(Type.Position, 3, pb); 9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta m.setBuffer(Type.Normal, 3, nb); 9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta m.setBuffer(Type.Tangent, 3, tanb); 9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta m.setBuffer(Type.Binormal, 3, bb); 9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta m.setBuffer(Type.TexCoord, 2, texb); 9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta m.setBuffer(Type.Index, 3, ib); 10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta m.setStatic(); 10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta m.updateBound(); 10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return m; 10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public FloatBuffer writeTexCoordArray(FloatBuffer store, Vector2f offset, Vector2f scale, float offsetAmount, int totalSize) { 10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (store != null) { 10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (store.remaining() < getWidth() * getHeight() * 2) { 10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta throw new BufferUnderflowException(); 10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta store = BufferUtils.createFloatBuffer(getWidth() * getHeight() * 2); 11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (offset == null) { 11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta offset = new Vector2f(); 11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector2f tcStore = new Vector2f(); 11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // work from bottom of heightmap up, so we don't flip the coords 12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int y = getHeight() - 1; y >= 0; y--) { 12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int x = 0; x < getWidth(); x++) { 12359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta getUV(x, y, tcStore, offset, offsetAmount, totalSize); 12459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float tx = tcStore.x * scale.x; 12559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float ty = tcStore.y * scale.y; 12659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta store.put(tx); 12759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta store.put(ty); 12859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 12959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 13059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 13159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return store; 13259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 13359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 13459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public Vector2f getUV(int x, int y, Vector2f store, Vector2f offset, float offsetAmount, int totalSize) { 13559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float offsetX = offset.x + (offsetAmount * 1.0f); 13659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float offsetY = -offset.y + (offsetAmount * 1.0f);//note the -, we flip the tex coords 13759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 13859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta store.set((((float) x) + offsetX) / (float) (totalSize - 1), // calculates percentage of texture here 13959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta (((float) y) + offsetY) / (float) (totalSize - 1)); 14059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return store; 14159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 14259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 14359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 14459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Create the LOD index array that will seam its edges with its neighbour's LOD. 14559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * This is a scary method!!! It will break your mind. 14659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 14759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param store to store the index buffer 14859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param lod level of detail of the mesh 14959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param rightLod LOD of the right neighbour 15059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param topLod LOD of the top neighbour 15159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param leftLod LOD of the left neighbour 15259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param bottomLod LOD of the bottom neighbour 15359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @return the LOD-ified index buffer 15459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 15559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public IntBuffer writeIndexArrayLodDiff(IntBuffer store, int lod, boolean rightLod, boolean topLod, boolean leftLod, boolean bottomLod) { 15659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 15759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta IntBuffer buffer2 = store; 15859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int numIndexes = calculateNumIndexesLodDiff(lod); 15959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (store == null) { 16059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer2 = BufferUtils.createIntBuffer(numIndexes); 16159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 16259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta VerboseIntBuffer buffer = new VerboseIntBuffer(buffer2); 16359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 16459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 16559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // generate center squares minus the edges 16659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println("for (x="+lod+"; x<"+(getWidth()-(2*lod))+"; x+="+lod+")"); 16759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println(" for (z="+lod+"; z<"+(getWidth()-(1*lod))+"; z+="+lod+")"); 16859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int r = lod; r < getWidth() - (2 * lod); r += lod) { // row 16959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int rowIdx = r * getWidth(); 17059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int nextRowIdx = (r + 1 * lod) * getWidth(); 17159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int c = lod; c < getWidth() - (1 * lod); c += lod) { // column 17259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int idx = rowIdx + c; 17359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 17459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta idx = nextRowIdx + c; 17559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 17659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 17759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 17859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // add degenerate triangles 17959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (r < getWidth() - (3 * lod)) { 18059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int idx = nextRowIdx + getWidth() - (1 * lod) - 1; 18159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 18259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta idx = nextRowIdx + (1 * lod); // inset by 1 18359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 18459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println(""); 18559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 18659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 18759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println("\nright:"); 18859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 18959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //int runningBufferCount = buffer.getCount(); 19059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println("buffer start: "+runningBufferCount); 19159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 19259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 19359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // right 19459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int br = getWidth() * (getWidth() - lod) - 1 - lod; 19559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(br); // bottom right -1 19659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int corner = getWidth() * getWidth() - 1; 19759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(corner); // bottom right corner 19859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (rightLod) { // if lower LOD 19959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int row = getWidth() - lod; row >= 1 + lod; row -= 2 * lod) { 20059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int idx = (row) * getWidth() - 1 - lod; 20159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 20259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta idx = (row - lod) * getWidth() - 1; 20359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 20459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (row > lod + 1) { //if not the last one 20559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta idx = (row - lod) * getWidth() - 1 - lod; 20659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 20759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta idx = (row - lod) * getWidth() - 1; 20859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 20959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 21059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 21159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 21259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 21359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(corner);//br+1);//degenerate to flip winding order 21459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int row = getWidth() - lod; row > lod; row -= lod) { 21559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int idx = row * getWidth() - 1; // mult to get row 21659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 21759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx - lod); 21859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 21959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 22059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 22159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 22259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(getWidth() - 1); 22359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 22459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 22559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println("\nbuffer right: "+(buffer.getCount()-runningBufferCount)); 22659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //runningBufferCount = buffer.getCount(); 22759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 22859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 22959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println("\ntop:"); 23059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 23159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // top (the order gets reversed here so the diagonals line up) 23259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (topLod) { // if lower LOD 23359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (rightLod) { 23459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(getWidth() - 1); 23559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 23659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int col = getWidth() - 1; col >= lod; col -= 2 * lod) { 23759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int idx = (lod * getWidth()) + col - lod; // next row 23859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 23959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta idx = col - 2 * lod; 24059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 24159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (col > lod * 2) { //if not the last one 24259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta idx = (lod * getWidth()) + col - 2 * lod; 24359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 24459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta idx = col - 2 * lod; 24559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 24659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 24759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 24859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 24959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 25059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (rightLod) { 25159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(getWidth() - 1); 25259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 25359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int col = getWidth() - 1 - lod; col > 0; col -= lod) { 25459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int idx = col + (lod * getWidth()); 25559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 25659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta idx = col; 25759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 25859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 25959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(0); 26059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 26159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(0); 26259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 26359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println("\nbuffer top: "+(buffer.getCount()-runningBufferCount)); 26459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //runningBufferCount = buffer.getCount(); 26559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 26659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println("\nleft:"); 26759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 26859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // left 26959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (leftLod) { // if lower LOD 27059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (topLod) { 27159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(0); 27259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 27359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int row = 0; row < getWidth() - lod; row += 2 * lod) { 27459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int idx = (row + lod) * getWidth() + lod; 27559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 27659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta idx = (row + 2 * lod) * getWidth(); 27759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 27859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (row < getWidth() - lod - 2 - 1) { //if not the last one 27959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta idx = (row + 2 * lod) * getWidth() + lod; 28059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 28159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta idx = (row + 2 * lod) * getWidth(); 28259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 28359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 28459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 28559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 28659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 28759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (!topLod) { 28859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(0); 28959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 29059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //buffer.put(getWidth()+1); // degenerate 29159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //buffer.put(0); // degenerate winding-flip 29259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int row = lod; row < getWidth() - lod; row += lod) { 29359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int idx = row * getWidth(); 29459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 29559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta idx = row * getWidth() + lod; 29659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 29759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 29859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 29959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 30059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(getWidth() * (getWidth() - 1)); 30159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 30259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 30359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println("\nbuffer left: "+(buffer.getCount()-runningBufferCount)); 30459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //runningBufferCount = buffer.getCount(); 30559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 30659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //if (true) return buffer.delegate; 30759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println("\nbottom"); 30859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 30959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // bottom 31059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (bottomLod) { // if lower LOD 31159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (leftLod) { 31259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(getWidth() * (getWidth() - 1)); 31359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 31459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // there was a slight bug here when really high LOD near maxLod 31559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // far right has extra index one row up and all the way to the right, need to skip last index entered 31659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // seemed to be fixed by making "getWidth()-1-2-lod" this: "getWidth()-1-2*lod", which seems more correct 31759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int col = 0; col < getWidth() - lod; col += 2 * lod) { 31859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int idx = getWidth() * (getWidth() - 1 - lod) + col + lod; 31959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 32059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta idx = getWidth() * (getWidth() - 1) + col + 2 * lod; 32159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 32259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (col < getWidth() - 1 - 2 * lod) { //if not the last one 32359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta idx = getWidth() * (getWidth() - 1 - lod) + col + 2 * lod; 32459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 32559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta idx = getWidth() * (getWidth() - 1) + col + 2 * lod; 32659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 32759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 32859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 32959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 33059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 33159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (leftLod) { 33259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(getWidth() * (getWidth() - 1)); 33359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 33459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int col = lod; col < getWidth() - lod; col += lod) { 33559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int idx = getWidth() * (getWidth() - 1 - lod) + col; // up 33659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 33759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta idx = getWidth() * (getWidth() - 1) + col; // down 33859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 33959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 34059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //buffer.put(getWidth()*getWidth()-1-lod); // <-- THIS caused holes at the end! 34159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 34259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 34359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(getWidth() * getWidth() - 1); 34459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 34559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println("\nbuffer bottom: "+(buffer.getCount()-runningBufferCount)); 34659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //runningBufferCount = buffer.getCount(); 34759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 34859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println("\nBuffer size: "+buffer.getCount()); 34959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 35059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // fill in the rest of the buffer with degenerates, there should only be a couple 35159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int i = buffer.getCount(); i < numIndexes; i++) { 35259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(getWidth() * getWidth() - 1); 35359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 35459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 35559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return buffer.delegate; 35659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 35759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 35859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public IntBuffer writeIndexArrayLodVariable(IntBuffer store, int lod, int rightLod, int topLod, int leftLod, int bottomLod) { 35959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 36059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta IntBuffer buffer2 = store; 36159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int numIndexes = calculateNumIndexesLodDiff(lod); 36259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (store == null) { 36359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer2 = BufferUtils.createIntBuffer(numIndexes); 36459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 36559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta VerboseIntBuffer buffer = new VerboseIntBuffer(buffer2); 36659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 36759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 36859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // generate center squares minus the edges 36959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println("for (x="+lod+"; x<"+(getWidth()-(2*lod))+"; x+="+lod+")"); 37059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println(" for (z="+lod+"; z<"+(getWidth()-(1*lod))+"; z+="+lod+")"); 37159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int r = lod; r < getWidth() - (2 * lod); r += lod) { // row 37259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int rowIdx = r * getWidth(); 37359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int nextRowIdx = (r + 1 * lod) * getWidth(); 37459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int c = lod; c < getWidth() - (1 * lod); c += lod) { // column 37559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int idx = rowIdx + c; 37659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 37759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta idx = nextRowIdx + c; 37859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 37959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 38059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 38159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // add degenerate triangles 38259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (r < getWidth() - (3 * lod)) { 38359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int idx = nextRowIdx + getWidth() - (1 * lod) - 1; 38459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 38559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta idx = nextRowIdx + (1 * lod); // inset by 1 38659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 38759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println(""); 38859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 38959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 39059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println("\nright:"); 39159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 39259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //int runningBufferCount = buffer.getCount(); 39359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println("buffer start: "+runningBufferCount); 39459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 39559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 39659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // right 39759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int br = getWidth() * (getWidth() - lod) - 1 - lod; 39859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(br); // bottom right -1 39959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int corner = getWidth() * getWidth() - 1; 40059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(corner); // bottom right corner 40159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (rightLod > lod) { // if lower LOD 40259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int idx = corner; 40359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int it = (getWidth() - 1) / rightLod; // iterations 40459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int lodDiff = rightLod / lod; 40559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int i = it; i > 0; i--) { // for each lod level of the neighbour 40659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta idx = getWidth() * (i * rightLod + 1) - 1; 40759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int j = 1; j <= lodDiff; j++) { // for each section in that lod level 40859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int idxB = idx - (getWidth() * (j * lod)) - lod; 40959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 41059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (j == lodDiff && i == 1) {// the last one 41159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(getWidth() - 1); 41259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (j == lodDiff) { 41359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idxB); 41459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idxB + lod); 41559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 41659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idxB); 41759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 41859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 41959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 42059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 42159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // reset winding order 42259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(getWidth() * (lod + 1) - lod - 1); // top-right +1row 42359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(getWidth() - 1);// top-right 42459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 42559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 42659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(corner);//br+1);//degenerate to flip winding order 42759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int row = getWidth() - lod; row > lod; row -= lod) { 42859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int idx = row * getWidth() - 1; // mult to get row 42959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 43059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx - lod); 43159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 43259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(getWidth() - 1); 43359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 43459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 43559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 43659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println("\nbuffer right: "+(buffer.getCount()-runningBufferCount)); 43759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //runningBufferCount = buffer.getCount(); 43859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 43959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 44059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println("\ntop:"); 44159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 44259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // top (the order gets reversed here so the diagonals line up) 44359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (topLod > lod) { // if lower LOD 44459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (rightLod > lod) { 44559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // need to flip winding order 44659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(getWidth() - 1); 44759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(getWidth() * lod - 1); 44859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(getWidth() - 1); 44959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 45059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int idx = getWidth() - 1; 45159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int it = (getWidth() - 1) / topLod; // iterations 45259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int lodDiff = topLod / lod; 45359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int i = it; i > 0; i--) { // for each lod level of the neighbour 45459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta idx = (i * topLod); 45559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int j = 1; j <= lodDiff; j++) { // for each section in that lod level 45659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int idxB = lod * getWidth() + (i * topLod) - (j * lod); 45759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 45859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (j == lodDiff && i == 1) {// the last one 45959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(0); 46059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (j == lodDiff) { 46159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idxB); 46259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx - topLod); 46359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 46459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idxB); 46559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 46659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 46759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 46859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 46959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 47059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (rightLod > lod) { 47159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(getWidth() - 1); 47259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 47359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int col = getWidth() - 1 - lod; col > 0; col -= lod) { 47459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int idx = col + (lod * getWidth()); 47559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 47659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta idx = col; 47759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 47859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 47959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(0); 48059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 48159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(0); 48259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 48359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println("\nbuffer top: "+(buffer.getCount()-runningBufferCount)); 48459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //runningBufferCount = buffer.getCount(); 48559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 48659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println("\nleft:"); 48759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 48859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // left 48959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (leftLod > lod) { // if lower LOD 49059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 49159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int idx = 0; 49259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int it = (getWidth() - 1) / leftLod; // iterations 49359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int lodDiff = leftLod / lod; 49459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int i = 0; i < it; i++) { // for each lod level of the neighbour 49559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta idx = getWidth() * (i * leftLod); 49659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int j = 1; j <= lodDiff; j++) { // for each section in that lod level 49759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int idxB = idx + (getWidth() * (j * lod)) + lod; 49859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 49959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (j == lodDiff && i == it - 1) {// the last one 50059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(getWidth() * getWidth() - getWidth()); 50159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (j == lodDiff) { 50259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idxB); 50359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idxB - lod); 50459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 50559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idxB); 50659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 50759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 50859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 50959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 51059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 51159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 51259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(0); 51359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(getWidth() * lod + lod); 51459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(0); 51559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int row = lod; row < getWidth() - lod; row += lod) { 51659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int idx = row * getWidth(); 51759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 51859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta idx = row * getWidth() + lod; 51959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 52059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 52159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(getWidth() * (getWidth() - 1)); 52259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 52359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //buffer.put(getWidth()*(getWidth()-1)); 52459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 52559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 52659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println("\nbuffer left: "+(buffer.getCount()-runningBufferCount)); 52759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //runningBufferCount = buffer.getCount(); 52859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 52959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //if (true) return buffer.delegate; 53059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println("\nbottom"); 53159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 53259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // bottom 53359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (bottomLod > lod) { // if lower LOD 53459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (leftLod > lod) { 53559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(getWidth() * (getWidth() - 1)); 53659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(getWidth() * (getWidth() - lod)); 53759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(getWidth() * (getWidth() - 1)); 53859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 53959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 54059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int idx = getWidth() * getWidth() - getWidth(); 54159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int it = (getWidth() - 1) / bottomLod; // iterations 54259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int lodDiff = bottomLod / lod; 54359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int i = 0; i < it; i++) { // for each lod level of the neighbour 54459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta idx = getWidth() * getWidth() - getWidth() + (i * bottomLod); 54559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int j = 1; j <= lodDiff; j++) { // for each section in that lod level 54659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int idxB = idx - (getWidth() * lod) + j * lod; 54759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 54859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (j == lodDiff && i == it - 1) {// the last one 54959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(getWidth() * getWidth() - 1); 55059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (j == lodDiff) { 55159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idxB); 55259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx + bottomLod); 55359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 55459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idxB); 55559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 55659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 55759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 55859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 55959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 56059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (leftLod > lod) { 56159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(getWidth() * (getWidth() - 1)); 56259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(getWidth() * getWidth() - (getWidth() * lod) + lod); 56359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(getWidth() * (getWidth() - 1)); 56459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 56559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int col = lod; col < getWidth() - lod; col += lod) { 56659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int idx = getWidth() * (getWidth() - 1 - lod) + col; // up 56759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 56859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta idx = getWidth() * (getWidth() - 1) + col; // down 56959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(idx); 57059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 57159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //buffer.put(getWidth()*getWidth()-1-lod); // <-- THIS caused holes at the end! 57259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 57359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 57459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(getWidth() * getWidth() - 1); 57559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 57659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println("\nbuffer bottom: "+(buffer.getCount()-runningBufferCount)); 57759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //runningBufferCount = buffer.getCount(); 57859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 57959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println("\nBuffer size: "+buffer.getCount()); 58059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 58159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // fill in the rest of the buffer with degenerates, there should only be a couple 58259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int i = buffer.getCount(); i < numIndexes; i++) { 58359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta buffer.put(getWidth() * getWidth() - 1); 58459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 58559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 58659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return buffer.delegate; 58759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 58859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 58959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 59059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /*private int calculateNumIndexesNormal(int lod) { 59159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int length = getWidth()-1; 59259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int num = ((length/lod)+1)*((length/lod)+1)*2; 59359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta System.out.println("num: "+num); 59459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta num -= 2*((length/lod)+1); 59559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta System.out.println("num2: "+num); 59659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // now get the degenerate indexes that exist between strip rows 59759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta num += 2*(((length/lod)+1)-2); // every row except the first and last 59859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta System.out.println("Index buffer size: "+num); 59959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return num; 60059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta }*/ 60159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 60259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * calculate how many indexes there will be. 60359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * This isn't that precise and there might be a couple extra. 60459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 60559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private int calculateNumIndexesLodDiff(int lod) { 60659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (lod == 0) { 60759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta lod = 1; 60859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 60959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int length = getWidth() - 1; // make it even for lod calc 61059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int side = (length / lod) + 1 - (2); 61159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println("side: "+side); 61259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int num = side * side * 2; 61359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println("num: "+num); 61459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta num -= 2 * side; // remove one first row and one last row (they are only hit once each) 61559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println("num2: "+num); 61659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // now get the degenerate indexes that exist between strip rows 61759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int degenerates = 2 * (side - (2)); // every row except the first and last 61859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta num += degenerates; 61959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println("degenerates: "+degenerates); 62059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 62159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println("center, before edges: "+num); 62259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 62359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta num += (getWidth() / lod) * 2 * 4; 62459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta num++; 62559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 62659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta num += 10;// TODO remove me: extra 62759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println("Index buffer size: "+num); 62859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return num; 62959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 63059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 631a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta public FloatBuffer[] writeTangentArray(FloatBuffer normalBuffer, FloatBuffer tangentStore, FloatBuffer binormalStore, FloatBuffer textureBuffer, Vector3f scale) { 63259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (!isLoaded()) { 63359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta throw new NullPointerException(); 63459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 63559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 63659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (tangentStore != null) { 63759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (tangentStore.remaining() < getWidth() * getHeight() * 3) { 63859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta throw new BufferUnderflowException(); 63959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 64059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 64159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tangentStore = BufferUtils.createFloatBuffer(getWidth() * getHeight() * 3); 64259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 64359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tangentStore.rewind(); 64459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 64559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (binormalStore != null) { 64659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (binormalStore.remaining() < getWidth() * getHeight() * 3) { 64759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta throw new BufferUnderflowException(); 64859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 64959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 65059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta binormalStore = BufferUtils.createFloatBuffer(getWidth() * getHeight() * 3); 65159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 65259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta binormalStore.rewind(); 65359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 654a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta Vector3f normal = new Vector3f(); 65559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f tangent = new Vector3f(); 65659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f binormal = new Vector3f(); 657a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta /*Vector3f v1 = new Vector3f(); 65859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f v2 = new Vector3f(); 65959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f v3 = new Vector3f(); 66059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector2f t1 = new Vector2f(); 66159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector2f t2 = new Vector2f(); 662a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta Vector2f t3 = new Vector2f();*/ 66359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 66459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int r = 0; r < getHeight(); r++) { 66559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int c = 0; c < getWidth(); c++) { 666a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta 667a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta int idx = (r * getWidth() + c) * 3; 668a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta normal.set(normalBuffer.get(idx), normalBuffer.get(idx+1), normalBuffer.get(idx+2)); 669a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta tangent.set(normal.cross(new Vector3f(0,0,1))); 670a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta binormal.set(new Vector3f(1,0,0).cross(normal)); 671a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta 672a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta BufferUtils.setInBuffer(tangent.normalizeLocal(), tangentStore, (r * getWidth() + c)); // save the tangent 673a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta BufferUtils.setInBuffer(binormal.normalizeLocal(), binormalStore, (r * getWidth() + c)); // save the binormal 674a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta } 675a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta } 676a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta 677a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta/* for (int r = 0; r < getHeight(); r++) { 678a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta for (int c = 0; c < getWidth(); c++) { 67959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 68059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int texIdx = ((getHeight() - 1 - r) * getWidth() + c) * 2; // pull from the end 68159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int texIdxAbove = ((getHeight() - 1 - (r - 1)) * getWidth() + c) * 2; // pull from the end 68259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int texIdxNext = ((getHeight() - 1 - (r + 1)) * getWidth() + c) * 2; // pull from the end 68359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 68459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta v1.set(c, getValue(c, r), r); 68559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t1.set(textureBuffer.get(texIdx), textureBuffer.get(texIdx + 1)); 68659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 68759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // below 68859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (r == getHeight()-1) { // last row 68959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta v3.set(c, getValue(c, r), r + 1); 69059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float u = textureBuffer.get(texIdx) - textureBuffer.get(texIdxAbove); 69159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta u += textureBuffer.get(texIdx); 69259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float v = textureBuffer.get(texIdx + 1) - textureBuffer.get(texIdxAbove + 1); 69359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta v += textureBuffer.get(texIdx + 1); 69459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t3.set(u, v); 69559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 69659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta v3.set(c, getValue(c, r + 1), r + 1); 69759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t3.set(textureBuffer.get(texIdxNext), textureBuffer.get(texIdxNext + 1)); 69859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 69959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 70059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //right 70159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (c == getWidth()-1) { // last column 70259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta v2.set(c + 1, getValue(c, r), r); 70359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float u = textureBuffer.get(texIdx) - textureBuffer.get(texIdx - 2); 70459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta u += textureBuffer.get(texIdx); 70559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float v = textureBuffer.get(texIdx + 1) - textureBuffer.get(texIdx - 1); 70659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta v += textureBuffer.get(texIdx - 1); 70759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t2.set(u, v); 70859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 70959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta v2.set(c + 1, getValue(c + 1, r), r); // one to the right 71059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t2.set(textureBuffer.get(texIdx + 2), textureBuffer.get(texIdx + 3)); 71159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 71259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 71359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta calculateTangent(new Vector3f[]{v1.mult(scale), v2.mult(scale), v3.mult(scale)}, new Vector2f[]{t1, t2, t3}, tangent, binormal); 71459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta BufferUtils.setInBuffer(tangent, tangentStore, (r * getWidth() + c)); // save the tangent 71559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta BufferUtils.setInBuffer(binormal, binormalStore, (r * getWidth() + c)); // save the binormal 71659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 71759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 718a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta */ 71959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return new FloatBuffer[]{tangentStore, binormalStore}; 72059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 72159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 72259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 72359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 72459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param v Takes 3 vertices: root, right, bottom 72559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param t Takes 3 tex coords: root, right, bottom 72659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param tangent that will store the result 72759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @return the tangent store 72859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 72959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static Vector3f calculateTangent(Vector3f[] v, Vector2f[] t, Vector3f tangent, Vector3f binormal) { 73059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f edge1 = new Vector3f(); // y=0 73159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f edge2 = new Vector3f(); // x=0 73259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector2f edge1uv = new Vector2f(); // y=0 73359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector2f edge2uv = new Vector2f(); // x=0 73459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 73559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t[2].subtract(t[0], edge2uv); 73659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t[1].subtract(t[0], edge1uv); 73759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 73859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float det = edge1uv.x * edge2uv.y;// - edge1uv.y*edge2uv.x; = 0 73959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 74059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta boolean normalize = true; 74159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (Math.abs(det) < 0.0000001f) { 74259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta det = 1; 74359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta normalize = true; 74459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 74559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 74659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta v[1].subtract(v[0], edge1); 74759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta v[2].subtract(v[0], edge2); 74859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 74959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tangent.set(edge1); 75059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tangent.normalizeLocal(); 75159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta binormal.set(edge2); 75259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta binormal.normalizeLocal(); 75359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 75459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float factor = 1 / det; 75559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tangent.x = (edge2uv.y * edge1.x) * factor; 75659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tangent.y = 0; 75759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tangent.z = (edge2uv.y * edge1.z) * factor; 75859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (normalize) { 75959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tangent.normalizeLocal(); 76059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 76159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 76259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta binormal.x = 0; 76359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta binormal.y = (edge1uv.x * edge2.y) * factor; 76459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta binormal.z = (edge1uv.x * edge2.z) * factor; 76559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (normalize) { 76659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta binormal.normalizeLocal(); 76759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 76859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 76959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return tangent; 77059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 77159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 77259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta @Override 77359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public FloatBuffer writeNormalArray(FloatBuffer store, Vector3f scale) { 77459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (!isLoaded()) { 77559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta throw new NullPointerException(); 77659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 77759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 77859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (store != null) { 77959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (store.remaining() < getWidth() * getHeight() * 3) { 78059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta throw new BufferUnderflowException(); 78159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 78259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 78359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta store = BufferUtils.createFloatBuffer(getWidth() * getHeight() * 3); 78459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 78559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta store.rewind(); 78659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 78759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta TempVars vars = TempVars.get(); 78859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 78959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f rootPoint = vars.vect1; 79059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f rightPoint = vars.vect2; 79159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f leftPoint = vars.vect3; 79259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f topPoint = vars.vect4; 79359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f bottomPoint = vars.vect5; 79459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 79559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f tmp1 = vars.vect6; 79659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 79759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // calculate normals for each polygon 79859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int r = 0; r < getHeight(); r++) { 79959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int c = 0; c < getWidth(); c++) { 80059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 80159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta rootPoint.set(c, getValue(c, r), r); 80259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f normal = vars.vect8; 80359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 80459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (r == 0) { // first row 80559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (c == 0) { // first column 80659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta rightPoint.set(c + 1, getValue(c + 1, r), r); 80759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta bottomPoint.set(c, getValue(c, r + 1), r + 1); 80859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta getNormal(bottomPoint, rootPoint, rightPoint, scale, normal); 80959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (c == getWidth() - 1) { // last column 81059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta leftPoint.set(c - 1, getValue(c - 1, r), r); 81159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta bottomPoint.set(c, getValue(c, r + 1), r + 1); 81259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta getNormal(leftPoint, rootPoint, bottomPoint, scale, normal); 81359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { // all middle columns 81459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta leftPoint.set(c - 1, getValue(c - 1, r), r); 81559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta rightPoint.set(c + 1, getValue(c + 1, r), r); 81659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta bottomPoint.set(c, getValue(c, r + 1), r + 1); 81759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 81859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta normal.set( getNormal(leftPoint, rootPoint, bottomPoint, scale, tmp1) ); 81959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta normal.add( getNormal(bottomPoint, rootPoint, rightPoint, scale, tmp1) ); 82059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta normal.normalizeLocal(); 82159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 82259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (r == getHeight() - 1) { // last row 82359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (c == 0) { // first column 82459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta topPoint.set(c, getValue(c, r - 1), r - 1); 82559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta rightPoint.set(c + 1, getValue(c + 1, r), r); 82659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta getNormal(rightPoint, rootPoint, topPoint, scale, normal); 82759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (c == getWidth() - 1) { // last column 82859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta topPoint.set(c, getValue(c, r - 1), r - 1); 82959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta leftPoint.set(c - 1, getValue(c - 1, r), r); 83059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta getNormal(topPoint, rootPoint, leftPoint, scale, normal); 83159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { // all middle columns 83259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta topPoint.set(c, getValue(c, r - 1), r - 1); 83359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta leftPoint.set(c - 1, getValue(c - 1, r), r); 83459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta rightPoint.set(c + 1, getValue(c + 1, r), r); 83559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 83659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta normal.set( getNormal(topPoint, rootPoint, leftPoint, scale, tmp1) ); 83759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta normal.add( getNormal(rightPoint, rootPoint, topPoint, scale, tmp1) ); 83859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta normal.normalizeLocal(); 83959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 84059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { // all middle rows 84159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (c == 0) { // first column 84259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta topPoint.set(c, getValue(c, r - 1), r - 1); 84359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta rightPoint.set(c + 1, getValue(c + 1, r), r); 84459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta bottomPoint.set(c, getValue(c, r + 1), r + 1); 84559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 84659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta normal.set( getNormal(rightPoint, rootPoint, topPoint, scale, tmp1) ); 84759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta normal.add( getNormal(bottomPoint, rootPoint, rightPoint, scale, tmp1) ); 84859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta normal.normalizeLocal(); 84959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (c == getWidth() - 1) { // last column 85059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta topPoint.set(c, getValue(c, r - 1), r - 1); 85159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta leftPoint.set(c - 1, getValue(c - 1, r), r); 85259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta bottomPoint.set(c, getValue(c, r + 1), r + 1); //XXX wrong 85359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 85459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta normal.set( getNormal(topPoint, rootPoint, leftPoint, scale, tmp1) ); 85559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta normal.add( getNormal(leftPoint, rootPoint, bottomPoint, scale, tmp1) ); 85659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta normal.normalizeLocal(); 85759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { // all middle columns 85859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta topPoint.set(c, getValue(c, r - 1), r - 1); 85959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta leftPoint.set(c - 1, getValue(c - 1, r), r); 86059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta rightPoint.set(c + 1, getValue(c + 1, r), r); 86159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta bottomPoint.set(c, getValue(c, r + 1), r + 1); 86259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 86359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta normal.set( getNormal(topPoint, rootPoint, leftPoint, scale, tmp1 ) ); 86459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta normal.add( getNormal(leftPoint, rootPoint, bottomPoint, scale, tmp1) ); 86559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta normal.add( getNormal(bottomPoint, rootPoint, rightPoint, scale, tmp1) ); 86659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta normal.add( getNormal(rightPoint, rootPoint, topPoint, scale, tmp1) ); 86759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta normal.normalizeLocal(); 86859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 86959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 87059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 87159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta BufferUtils.setInBuffer(normal, store, (r * getWidth() + c)); // save the normal 87259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 87359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 87459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.release(); 87559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 87659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return store; 87759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 87859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 87959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private Vector3f getNormal(Vector3f firstPoint, Vector3f rootPoint, Vector3f secondPoint, Vector3f scale, Vector3f store) { 88059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float x1 = firstPoint.x - rootPoint.x; 88159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float y1 = firstPoint.y - rootPoint.y; 88259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float z1 = firstPoint.z - rootPoint.z; 88359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta x1 *= scale.x; 88459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta y1 *= scale.y; 88559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta z1 *= scale.z; 88659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float x2 = secondPoint.x - rootPoint.x; 88759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float y2 = secondPoint.y - rootPoint.y; 88859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float z2 = secondPoint.z - rootPoint.z; 88959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta x2 *= scale.x; 89059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta y2 *= scale.y; 89159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta z2 *= scale.z; 89259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float x3 = (y1 * z2) - (z1 * y2); 89359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float y3 = (z1 * x2) - (x1 * z2); 89459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float z3 = (x1 * y2) - (y1 * x2); 89559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 89659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float inv = 1.0f / FastMath.sqrt(x3 * x3 + y3 * y3 + z3 * z3); 89759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta store.x = x3 * inv; 89859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta store.y = y3 * inv; 89959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta store.z = z3 * inv; 90059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return store; 90159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 90259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /*store.set( firstPoint.subtractLocal(rootPoint).multLocal(scale).crossLocal(secondPoint.subtractLocal(rootPoint).multLocal(scale)).normalizeLocal() ); 90359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return store;*/ 90459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 90559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 90659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 90759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 90859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Keeps a count of the number of indexes, good for debugging 90959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 91059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public class VerboseIntBuffer { 91159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 91259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private IntBuffer delegate; 91359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int count = 0; 91459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 91559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public VerboseIntBuffer(IntBuffer d) { 91659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta delegate = d; 91759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 91859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 91959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void put(int value) { 92059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta try { 92159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta delegate.put(value); 92259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta count++; 92359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } catch (BufferOverflowException e) { 92459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println("err buffer size: "+delegate.capacity()); 92559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 92659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 92759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 92859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public int getCount() { 92959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return count; 93059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 93159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 93259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 93359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 93459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Get a representation of the underlying triangle at the given point, 93559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * translated to world coordinates. 93659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 93759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param x local x coordinate 93859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param z local z coordinate 93959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @return a triangle in world space not local space 94059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 94159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta protected Triangle getTriangleAtPoint(float x, float z, Vector3f scale, Vector3f translation) { 94259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Triangle tri = getTriangleAtPoint(x, z); 94359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (tri != null) { 94459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tri.get1().multLocal(scale).addLocal(translation); 94559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tri.get2().multLocal(scale).addLocal(translation); 94659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tri.get3().multLocal(scale).addLocal(translation); 94759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 94859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return tri; 94959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 95059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 95159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 95259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Get the two triangles that make up the grid section at the specified point, 95359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * translated to world coordinates. 95459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 95559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param x local x coordinate 95659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param z local z coordinate 95759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param scale 95859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param translation 95959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @return two triangles in world space not local space 96059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 96159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta protected Triangle[] getGridTrianglesAtPoint(float x, float z, Vector3f scale, Vector3f translation) { 96259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Triangle[] tris = getGridTrianglesAtPoint(x, z); 96359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (tris != null) { 96459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tris[0].get1().multLocal(scale).addLocal(translation); 96559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tris[0].get2().multLocal(scale).addLocal(translation); 96659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tris[0].get3().multLocal(scale).addLocal(translation); 96759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tris[1].get1().multLocal(scale).addLocal(translation); 96859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tris[1].get2().multLocal(scale).addLocal(translation); 96959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tris[1].get3().multLocal(scale).addLocal(translation); 97059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 97159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return tris; 97259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 97359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 97459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 97559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Get the two triangles that make up the grid section at the specified point. 97659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 97759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * For every grid space there are two triangles oriented like this: 97859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * *----* 97959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * |a / | 98059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * | / b| 98159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * *----* 98259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * The corners of the mesh have differently oriented triangles. The two 98359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * corners that we have to special-case are the top left and bottom right 98459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * corners. They are oriented inversely: 98559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * *----* 98659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * | \ b| 98759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * |a \ | 98859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * *----* 98959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 99059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param x local x coordinate 99159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param z local z coordinate 99259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param scale 99359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param translation 99459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @return 99559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 99659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta protected Triangle[] getGridTrianglesAtPoint(float x, float z) { 99759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int gridX = (int) x; 99859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int gridY = (int) z; 99959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 100059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int index = findClosestHeightIndex(gridX, gridY); 100159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (index < 0) { 100259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return null; 100359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 100459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 100559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Triangle t = new Triangle(new Vector3f(), new Vector3f(), new Vector3f()); 100659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Triangle t2 = new Triangle(new Vector3f(), new Vector3f(), new Vector3f()); 100759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 100859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float h1 = hdata[index]; // top left 100959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float h2 = hdata[index + 1]; // top right 101059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float h3 = hdata[index + width]; // bottom left 101159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float h4 = hdata[index + width + 1]; // bottom right 101259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 101359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 101459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if ((gridX == 0 && gridY == 0) || (gridX == width - 1 && gridY == width - 1)) { 101559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // top left or bottom right grid point 101659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t.get(0).x = (gridX); 101759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t.get(0).y = (h1); 101859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t.get(0).z = (gridY); 101959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 102059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t.get(1).x = (gridX); 102159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t.get(1).y = (h3); 102259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t.get(1).z = (gridY + 1); 102359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 102459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t.get(2).x = (gridX + 1); 102559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t.get(2).y = (h4); 102659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t.get(2).z = (gridY + 1); 102759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 102859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t2.get(0).x = (gridX); 102959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t2.get(0).y = (h1); 103059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t2.get(0).z = (gridY); 103159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 103259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t2.get(1).x = (gridX + 1); 103359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t2.get(1).y = (h4); 103459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t2.get(1).z = (gridY + 1); 103559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 103659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t2.get(2).x = (gridX + 1); 103759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t2.get(2).y = (h2); 103859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t2.get(2).z = (gridY); 103959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 104059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // all other grid points 104159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t.get(0).x = (gridX); 104259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t.get(0).y = (h1); 104359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t.get(0).z = (gridY); 104459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 104559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t.get(1).x = (gridX); 104659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t.get(1).y = (h3); 104759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t.get(1).z = (gridY + 1); 104859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 104959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t.get(2).x = (gridX + 1); 105059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t.get(2).y = (h2); 105159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t.get(2).z = (gridY); 105259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 105359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t2.get(0).x = (gridX + 1); 105459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t2.get(0).y = (h2); 105559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t2.get(0).z = (gridY); 105659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 105759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t2.get(1).x = (gridX); 105859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t2.get(1).y = (h3); 105959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t2.get(1).z = (gridY + 1); 106059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 106159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t2.get(2).x = (gridX + 1); 106259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t2.get(2).y = (h4); 106359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t2.get(2).z = (gridY + 1); 106459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 106559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 106659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return new Triangle[]{t, t2}; 106759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 106859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 106959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 107059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Get the triangle that the point is on. 107159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 107259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param x coordinate in local space to the geomap 107359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param z coordinate in local space to the geomap 107459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @return triangle in local space to the geomap 107559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 107659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta protected Triangle getTriangleAtPoint(float x, float z) { 107759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Triangle[] triangles = getGridTrianglesAtPoint(x, z); 107859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (triangles == null) { 107959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //System.out.println("x,z: " + x + "," + z); 108059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return null; 108159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 108259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector2f point = new Vector2f(x, z); 108359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector2f t1 = new Vector2f(triangles[0].get1().x, triangles[0].get1().z); 108459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector2f t2 = new Vector2f(triangles[0].get2().x, triangles[0].get2().z); 108559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector2f t3 = new Vector2f(triangles[0].get3().x, triangles[0].get3().z); 108659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 108759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (0 != FastMath.pointInsideTriangle(t1, t2, t3, point)) { 108859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return triangles[0]; 108959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 109059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 109159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t1.set(triangles[1].get1().x, triangles[1].get1().z); 109259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t1.set(triangles[1].get2().x, triangles[1].get2().z); 109359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t1.set(triangles[1].get3().x, triangles[1].get3().z); 109459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 109559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (0 != FastMath.pointInsideTriangle(t1, t2, t3, point)) { 109659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return triangles[1]; 109759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 109859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 109959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return null; 110059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 110159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 110259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta protected int findClosestHeightIndex(int x, int z) { 110359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 110459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (x < 0 || x >= width - 1) { 110559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return -1; 110659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 110759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (z < 0 || z >= width - 1) { 110859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return -1; 110959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 111059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 111159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return z * width + x; 111259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 111359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 111459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta @Override 111559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void write(JmeExporter ex) throws IOException { 111659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta super.write(ex); 111759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 111859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 111959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta @Override 112059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void read(JmeImporter im) throws IOException { 112159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta super.read(im); 112259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 112359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta} 1124