From 047e6af24f0396361bf5b0dfad5f39a9a207ca2d Mon Sep 17 00:00:00 2001 From: austin Date: Wed, 20 Nov 2024 11:14:39 -0500 Subject: [PATCH] Terrain work --- docs/src/progress/renderertodo.md | 2 + .../collision/CollisionEngine.java | 2 +- .../meshgen/TerrainChunkModelGeneration.java | 2 +- .../meshgen/TransvoxelModelGeneration.java | 511 +++++++++++++----- .../TransvoxelModelGenerationTests.java | 76 +++ 5 files changed, 456 insertions(+), 137 deletions(-) create mode 100644 src/test/java/electrosphere/renderer/meshgen/TransvoxelModelGenerationTests.java diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index d819cf84..4e2e88b9 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -1083,6 +1083,8 @@ Fix server data cells unloading before ready state Fix terrain chunk generation trying to generate rigid body for no-vertex cell Fix server homogenous chunk check on generation with variadic weights Optimize data passing from voxel rasterizer to model generation +Vector pooling in transvoxel rasterizer +Fix invalid normals from transvoxel rasterizer diff --git a/src/main/java/electrosphere/collision/CollisionEngine.java b/src/main/java/electrosphere/collision/CollisionEngine.java index f68e39d0..5a81a056 100644 --- a/src/main/java/electrosphere/collision/CollisionEngine.java +++ b/src/main/java/electrosphere/collision/CollisionEngine.java @@ -88,7 +88,7 @@ public class CollisionEngine { /** * Threshold after which the engine warns about collidable count */ - public static final int COLLIDABLE_COUNT_WARNING_THRESHOLD = 1000; + public static final int COLLIDABLE_COUNT_WARNING_THRESHOLD = 5000; /** * Default distance to interact with collidables at (ie picking where to place things) diff --git a/src/main/java/electrosphere/renderer/meshgen/TerrainChunkModelGeneration.java b/src/main/java/electrosphere/renderer/meshgen/TerrainChunkModelGeneration.java index 863ad70b..763094bc 100644 --- a/src/main/java/electrosphere/renderer/meshgen/TerrainChunkModelGeneration.java +++ b/src/main/java/electrosphere/renderer/meshgen/TerrainChunkModelGeneration.java @@ -25,7 +25,7 @@ public class TerrainChunkModelGeneration { /** * The minimum iso value */ - public static final float MIN_ISO_VALUE = 0.01f; + public static final float MIN_ISO_VALUE = 0.0f; //http://paulbourke.net/geometry/polygonise/ diff --git a/src/main/java/electrosphere/renderer/meshgen/TransvoxelModelGeneration.java b/src/main/java/electrosphere/renderer/meshgen/TransvoxelModelGeneration.java index 973843e3..f65b6cd7 100644 --- a/src/main/java/electrosphere/renderer/meshgen/TransvoxelModelGeneration.java +++ b/src/main/java/electrosphere/renderer/meshgen/TransvoxelModelGeneration.java @@ -60,6 +60,21 @@ public class TransvoxelModelGeneration { */ static final int SAMPLER_VALUES_PER_VERT = 3; + /** + * Size of the vector pool + */ + static final int VECTOR_POOL_SIZE = 11; + + /** + * Threshold of normal dot product + */ + static final float NORMAL_DOT_THRESHOLD = 0.99f; + + /** + * The min dist to check + */ + static final double MIN_DIST = 0.00001; + //this is the width of the transition cell //it should be between 0 and 1, exclusive @@ -107,16 +122,11 @@ public class TransvoxelModelGeneration { double[] val = new double[8]; //array of size 8 int[] atlasValues = new int[8]; //array of size 8 public void setValues( - Vector3f p1, Vector3f p2, Vector3f p3, Vector3f p4, - Vector3f p5, Vector3f p6, Vector3f p7, Vector3f p8, double val1, double val2, double val3, double val4, double val5, double val6, double val7, double val8, int atl1, int atl2, int atl3, int atl4, int atl5, int atl6, int atl7, int atl8 ){ - //triangle points - points[0] = p1; points[1] = p2; points[2] = p3; points[3] = p4; - points[4] = p5; points[5] = p6; points[6] = p7; points[7] = p8; //iso values val[0] = val1; val[1] = val2; val[2] = val3; val[3] = val4; val[4] = val5; val[5] = val6; val[6] = val7; val[7] = val8; @@ -124,6 +134,14 @@ public class TransvoxelModelGeneration { atlasValues[0] = atl1; atlasValues[1] = atl2; atlasValues[2] = atl3; atlasValues[3] = atl4; atlasValues[4] = atl5; atlasValues[5] = atl6; atlasValues[6] = atl7; atlasValues[7] = atl8; } + public void setVectors( + Vector3f p1, Vector3f p2, Vector3f p3, Vector3f p4, + Vector3f p5, Vector3f p6, Vector3f p7, Vector3f p8 + ){ + //triangle points + points[0] = p1; points[1] = p2; points[2] = p3; points[3] = p4; + points[4] = p5; points[5] = p6; points[6] = p7; points[7] = p8; + } } /** @@ -214,75 +232,93 @@ public class TransvoxelModelGeneration { * @return */ protected static int polygonize( - GridCell grid, - double isolevel, - List triangles, - List samplerIndices, - Map vertMap, - List verts, - List normals, - List trianglesSharingVert, - boolean invertNormals - ){ + GridCell grid, + double isolevel, + List triangles, + List samplerIndices, + Map vertMap, + List verts, + List normals, + List trianglesSharingVert, + boolean invertNormals + ){ int i; int ntriang; int cubeIndex = 0; Vector3f[] vertList = new Vector3f[12]; int[] samplerIndex = new int[12]; + //essentially, because the iso level is 0, we can end up generating weird midpoints between 0 and negative values + //in order to not actually generate triangles for these edge cases, the skip table is populated if the current edge is between 0 and a negative value + //when storing triangles, all skip edges trigger the loop to skip to the next triangle set + boolean[] skip = new boolean[12]; + //get lookup key (index) for edge table //edge table tells us which vertices are inside of the surface - if (grid.val[0] < isolevel) cubeIndex |= 1; - if (grid.val[1] < isolevel) cubeIndex |= 2; - if (grid.val[2] < isolevel) cubeIndex |= 4; - if (grid.val[3] < isolevel) cubeIndex |= 8; - if (grid.val[4] < isolevel) cubeIndex |= 16; - if (grid.val[5] < isolevel) cubeIndex |= 32; - if (grid.val[6] < isolevel) cubeIndex |= 64; - if (grid.val[7] < isolevel) cubeIndex |= 128; + if(grid.val[0] < isolevel) cubeIndex |= 1; + if(grid.val[1] < isolevel) cubeIndex |= 2; + if(grid.val[2] < isolevel) cubeIndex |= 4; + if(grid.val[3] < isolevel) cubeIndex |= 8; + if(grid.val[4] < isolevel) cubeIndex |= 16; + if(grid.val[5] < isolevel) cubeIndex |= 32; + if(grid.val[6] < isolevel) cubeIndex |= 64; + if(grid.val[7] < isolevel) cubeIndex |= 128; //Cube is entirely in/out of the surface - if (TerrainChunkModelGeneration.edgeTable[cubeIndex] == 0) - return(0); + if(TerrainChunkModelGeneration.edgeTable[cubeIndex] == 0){ + return 0; + } //instead of having all intersections be perfectly at the midpoint, //for each edge this code calculates where along the edge to place the vertex //this should dramatically smooth the surface if((TerrainChunkModelGeneration.edgeTable[cubeIndex] & 1) > 0){ - vertList[0] = VertexInterp(isolevel,grid.points[0],grid.points[1],grid.val[0],grid.val[1]); + vertList[0] = TransvoxelModelGeneration.VertexInterp(isolevel,grid.points[0],grid.points[1],grid.val[0],grid.val[1]); + if(grid.val[0] <= 0 && grid.val[1] <= 0){ skip[0] = true; } } if((TerrainChunkModelGeneration.edgeTable[cubeIndex] & 2) > 0){ - vertList[1] = VertexInterp(isolevel,grid.points[1],grid.points[2],grid.val[1],grid.val[2]); + vertList[1] = TransvoxelModelGeneration.VertexInterp(isolevel,grid.points[1],grid.points[2],grid.val[1],grid.val[2]); + if(grid.val[1] <= 0 && grid.val[2] <= 0){ skip[1] = true; } } if((TerrainChunkModelGeneration.edgeTable[cubeIndex] & 4) > 0){ - vertList[2] = VertexInterp(isolevel,grid.points[2],grid.points[3],grid.val[2],grid.val[3]); + vertList[2] = TransvoxelModelGeneration.VertexInterp(isolevel,grid.points[2],grid.points[3],grid.val[2],grid.val[3]); + if(grid.val[2] <= 0 && grid.val[3] <= 0){ skip[2] = true; } } if((TerrainChunkModelGeneration.edgeTable[cubeIndex] & 8) > 0){ - vertList[3] = VertexInterp(isolevel,grid.points[3],grid.points[0],grid.val[3],grid.val[0]); + vertList[3] = TransvoxelModelGeneration.VertexInterp(isolevel,grid.points[3],grid.points[0],grid.val[3],grid.val[0]); + if(grid.val[3] <= 0 && grid.val[0] <= 0){ skip[3] = true; } } if((TerrainChunkModelGeneration.edgeTable[cubeIndex] & 16) > 0){ - vertList[4] = VertexInterp(isolevel,grid.points[4],grid.points[5],grid.val[4],grid.val[5]); + vertList[4] = TransvoxelModelGeneration.VertexInterp(isolevel,grid.points[4],grid.points[5],grid.val[4],grid.val[5]); + if(grid.val[4] <= 0 && grid.val[5] <= 0){ skip[4] = true; } } if((TerrainChunkModelGeneration.edgeTable[cubeIndex] & 32) > 0){ - vertList[5] = VertexInterp(isolevel,grid.points[5],grid.points[6],grid.val[5],grid.val[6]); + vertList[5] = TransvoxelModelGeneration.VertexInterp(isolevel,grid.points[5],grid.points[6],grid.val[5],grid.val[6]); + if(grid.val[5] <= 0 && grid.val[6] <= 0){ skip[5] = true; } } if((TerrainChunkModelGeneration.edgeTable[cubeIndex] & 64) > 0){ - vertList[6] = VertexInterp(isolevel,grid.points[6],grid.points[7],grid.val[6],grid.val[7]); + vertList[6] = TransvoxelModelGeneration.VertexInterp(isolevel,grid.points[6],grid.points[7],grid.val[6],grid.val[7]); + if(grid.val[6] <= 0 && grid.val[7] <= 0){ skip[6] = true; } } if((TerrainChunkModelGeneration.edgeTable[cubeIndex] & 128) > 0){ - vertList[7] = VertexInterp(isolevel,grid.points[7],grid.points[4],grid.val[7],grid.val[4]); + vertList[7] = TransvoxelModelGeneration.VertexInterp(isolevel,grid.points[7],grid.points[4],grid.val[7],grid.val[4]); + if(grid.val[7] <= 0 && grid.val[4] <= 0){ skip[7] = true; } } if((TerrainChunkModelGeneration.edgeTable[cubeIndex] & 256) > 0){ - vertList[8] = VertexInterp(isolevel,grid.points[0],grid.points[4],grid.val[0],grid.val[4]); + vertList[8] = TransvoxelModelGeneration.VertexInterp(isolevel,grid.points[0],grid.points[4],grid.val[0],grid.val[4]); + if(grid.val[0] <= 0 && grid.val[4] <= 0){ skip[8] = true; } } if((TerrainChunkModelGeneration.edgeTable[cubeIndex] & 512) > 0){ - vertList[9] = VertexInterp(isolevel,grid.points[1],grid.points[5],grid.val[1],grid.val[5]); + vertList[9] = TransvoxelModelGeneration.VertexInterp(isolevel,grid.points[1],grid.points[5],grid.val[1],grid.val[5]); + if(grid.val[1] <= 0 && grid.val[5] <= 0){ skip[9] = true; } } if((TerrainChunkModelGeneration.edgeTable[cubeIndex] & 1024) > 0){ - vertList[10] = VertexInterp(isolevel,grid.points[2],grid.points[6],grid.val[2],grid.val[6]); + vertList[10] = TransvoxelModelGeneration.VertexInterp(isolevel,grid.points[2],grid.points[6],grid.val[2],grid.val[6]); + if(grid.val[2] <= 0 && grid.val[6] <= 0){ skip[10] = true; } } if((TerrainChunkModelGeneration.edgeTable[cubeIndex] & 2048) > 0){ - vertList[11] = VertexInterp(isolevel,grid.points[3],grid.points[7],grid.val[3],grid.val[7]); + vertList[11] = TransvoxelModelGeneration.VertexInterp(isolevel,grid.points[3],grid.points[7],grid.val[3],grid.val[7]); + if(grid.val[3] <= 0 && grid.val[7] <= 0){ skip[11] = true; } } if(grid.val[0] > isolevel){ samplerIndex[0] = 0; } else { samplerIndex[0] = 1; } @@ -300,7 +336,16 @@ public class TransvoxelModelGeneration { //Create the triangle ntriang = 0; - for (i=0; TerrainChunkModelGeneration.triTable[cubeIndex][i]!=-1; i+=3) { + for(i=0; TerrainChunkModelGeneration.triTable[cubeIndex][i]!=-1; i+=3){ + + //check skip table + if( + skip[TerrainChunkModelGeneration.triTable[cubeIndex][i+0]] || + skip[TerrainChunkModelGeneration.triTable[cubeIndex][i+1]] || + skip[TerrainChunkModelGeneration.triTable[cubeIndex][i+2]] + ){ + continue; + } // // Triangles calculation // @@ -308,9 +353,37 @@ public class TransvoxelModelGeneration { Vector3f vert0 = vertList[TerrainChunkModelGeneration.triTable[cubeIndex][i+0]]; Vector3f vert1 = vertList[TerrainChunkModelGeneration.triTable[cubeIndex][i+1]]; Vector3f vert2 = vertList[TerrainChunkModelGeneration.triTable[cubeIndex][i+2]]; - int index0 = getVertIndex(vert0,vertMap,verts); - int index1 = getVertIndex(vert1,vertMap,verts); - int index2 = getVertIndex(vert2,vertMap,verts); + int index0 = TransvoxelModelGeneration.getVertIndex(vert0,vertMap,verts); + int index1 = TransvoxelModelGeneration.getVertIndex(vert1,vertMap,verts); + int index2 = TransvoxelModelGeneration.getVertIndex(vert2,vertMap,verts); + if(index0 == index1 || index1 == index2 || index0 == index2){ + TransvoxelModelGeneration.VertexInterp(isolevel,grid.points[6],grid.points[7],grid.val[6],grid.val[7]); + TransvoxelModelGeneration.VertexInterp(isolevel,grid.points[2],grid.points[6],grid.val[2],grid.val[6]); + String message = "Identical indices!\n" + + "edge table: " + TerrainChunkModelGeneration.edgeTable[cubeIndex] + "\n" + + "cube index: " + cubeIndex + "\n" + + "triTable: " + TerrainChunkModelGeneration.triTable[cubeIndex][i+0] + "\n" + + "triTable: " + TerrainChunkModelGeneration.triTable[cubeIndex][i+1] + "\n" + + "triTable: " + TerrainChunkModelGeneration.triTable[cubeIndex][i+2] + "\n" + + vert0 + "\n" + + vert1 + "\n" + + vert2 + "\n" + + index0 + "\n" + + index1 + "\n" + + index2 + "\n"; + for(int j = 0; j < 12; j++){ + message = message + "vertList[" + j + "]" + vertList[j] + "\n"; + } + for(int j = 0; j < 8; j++){ + message = message + "grid.points[" + j + "] " + grid.points[j] + "\n"; + } + for(int j = 0; j < 8; j++){ + message = message + "grid.val[" + j + "] " + grid.val[j] + "\n"; + } + throw new Error( + message + ); + } //add 0's to normals until it matches vert count while(trianglesSharingVert.size() < verts.size()){ @@ -352,12 +425,30 @@ public class TransvoxelModelGeneration { //calculate normal for new triangle - Vector3f u = verts.get(index1).sub(verts.get(index0), new Vector3f()); - Vector3f v = verts.get(index2).sub(verts.get(index1), new Vector3f()); - Vector3f n = new Vector3f(u.y * v.z - u.z * v.y, u.z * v.x - u.x * v.z, u.x * v.y - u.y * v.x).normalize(); + Vector3f u = new Vector3f(verts.get(index1)).sub(verts.get(index0)); + Vector3f v = new Vector3f(verts.get(index2)).sub(verts.get(index1)); + float dotVal = u.dot(v); + Vector3f n = new Vector3f(); + // if(dotVal > NORMAL_DOT_THRESHOLD || dotVal < -NORMAL_DOT_THRESHOLD){ + // n.set(u); + // } else { + n = new Vector3f(u.y * v.z - u.z * v.y, u.z * v.x - u.x * v.z, u.x * v.y - u.y * v.x).normalize(); + // } if(invertNormals){ n = n.mul(-1); } + if(!Float.isFinite(n.length())){ + throw new Error("Invalid normal!\n" + + verts.get(index0) + "\n" + + verts.get(index1) + "\n" + + verts.get(index2) + "\n" + + u + "\n" + + v + "\n" + + n + "\n" + + n.length() + "\n" + + dotVal + ); + } @@ -370,7 +461,7 @@ public class TransvoxelModelGeneration { trianglesSharingVert.set(index0, trianglesSharingIndex0 + 1); Vector3f currentNormal = normals.get(index0); - currentNormal = averageNormals(currentNormal,oldProportion,n,newProportion); + currentNormal = TransvoxelModelGeneration.averageNormals(currentNormal,oldProportion,n,newProportion); normals.get(index0).set(currentNormal); @@ -385,7 +476,7 @@ public class TransvoxelModelGeneration { trianglesSharingVert.set(index1, trianglesSharingIndex1 + 1); currentNormal = normals.get(index1); - currentNormal = averageNormals(currentNormal,oldProportion,n,newProportion); + currentNormal = TransvoxelModelGeneration.averageNormals(currentNormal,oldProportion,n,newProportion); normals.get(index1).set(currentNormal); @@ -403,7 +494,7 @@ public class TransvoxelModelGeneration { trianglesSharingVert.set(index2, trianglesSharingIndex2 + 1); currentNormal = normals.get(index2); - currentNormal = averageNormals(currentNormal,oldProportion,n,newProportion); + currentNormal = TransvoxelModelGeneration.averageNormals(currentNormal,oldProportion,n,newProportion); normals.get(index2).set(currentNormal); } @@ -431,7 +522,7 @@ public class TransvoxelModelGeneration { double isolevel, List triangles, List samplerIndices, - Map vertMap, + Map vertMap, List verts, List normals, List trianglesSharingVert, @@ -673,12 +764,12 @@ public class TransvoxelModelGeneration { LoggerInterface.loggerRenderer.DEBUG("Corner indices: " + firstCornerSampleIndex + " " + secondCornerSampleIndex); //get the iso sample values - float firstSample = getTransvoxelSampleValue(transitionCell.simpleFaceValues,transitionCell.complexFaceValues,firstCornerSampleIndex); - float secondSample = getTransvoxelSampleValue(transitionCell.simpleFaceValues,transitionCell.complexFaceValues,secondCornerSampleIndex); + float firstSample = TransvoxelModelGeneration.getTransvoxelSampleValue(transitionCell.simpleFaceValues,transitionCell.complexFaceValues,firstCornerSampleIndex); + float secondSample = TransvoxelModelGeneration.getTransvoxelSampleValue(transitionCell.simpleFaceValues,transitionCell.complexFaceValues,secondCornerSampleIndex); // //Sample check -- we should never be interpolating between two samples of 0 value - if(firstSample <= 0 && secondSample <= 0){ + if(firstSample < 0 && secondSample < 0){ String message = "" + transitionCell.complexFaceValues[0][2] + " " + transitionCell.complexFaceValues[1][2] + " " + transitionCell.complexFaceValues[2][2] + "\n" + transitionCell.complexFaceValues[0][1] + " " + transitionCell.complexFaceValues[1][1] + " " + transitionCell.complexFaceValues[2][1] + "\n" + @@ -692,17 +783,17 @@ public class TransvoxelModelGeneration { //get the vertices we're interpolating //we need to map 0x0 through 0xC to the coordinates we're actually modifying - Vector3f firstVertex = getTransvoxelVectorByIndex(transitionCell,firstCornerSampleIndex); - Vector3f secondVertex = getTransvoxelVectorByIndex(transitionCell,secondCornerSampleIndex); + Vector3f firstVertex = TransvoxelModelGeneration.getTransvoxelVectorByIndex(transitionCell,firstCornerSampleIndex); + Vector3f secondVertex = TransvoxelModelGeneration.getTransvoxelVectorByIndex(transitionCell,secondCornerSampleIndex); //calculate interpolated vertex between the two samples such that it lies on the edge of the isosurface - vertList[i] = VertexInterp(isolevel,firstVertex,secondVertex,firstSample,secondSample); + vertList[i] = TransvoxelModelGeneration.VertexInterp(isolevel,firstVertex,secondVertex,firstSample,secondSample); //figure out what sample we're pulling texture from if(firstSample > isolevel){ - samplerIndex[i] = getTransvoxelTextureValue(transitionCell.simpleFaceAtlasValues,transitionCell.complexFaceAtlasValues,firstCornerSampleIndex); + samplerIndex[i] = TransvoxelModelGeneration.getTransvoxelTextureValue(transitionCell.simpleFaceAtlasValues,transitionCell.complexFaceAtlasValues,firstCornerSampleIndex); } else { - samplerIndex[i] = getTransvoxelTextureValue(transitionCell.simpleFaceAtlasValues,transitionCell.complexFaceAtlasValues,secondCornerSampleIndex); + samplerIndex[i] = TransvoxelModelGeneration.getTransvoxelTextureValue(transitionCell.simpleFaceAtlasValues,transitionCell.complexFaceAtlasValues,secondCornerSampleIndex); } } } @@ -746,13 +837,13 @@ public class TransvoxelModelGeneration { LoggerInterface.loggerRenderer.DEBUG(vert0 + ""); LoggerInterface.loggerRenderer.DEBUG(vert1 + ""); LoggerInterface.loggerRenderer.DEBUG(vert2 + ""); - int index0 = getVertIndex(vert0,vertMap,verts); - int index1 = getVertIndex(vert1,vertMap,verts); - int index2 = getVertIndex(vert2,vertMap,verts); + int index0 = TransvoxelModelGeneration.getVertIndex(vert0,vertMap,verts); + int index1 = TransvoxelModelGeneration.getVertIndex(vert1,vertMap,verts); + int index2 = TransvoxelModelGeneration.getVertIndex(vert2,vertMap,verts); if(windingOrder == 1){ - index0 = getVertIndex(vert2,vertMap,verts); - index2 = getVertIndex(vert0,vertMap,verts); + index0 = TransvoxelModelGeneration.getVertIndex(vert2,vertMap,verts); + index2 = TransvoxelModelGeneration.getVertIndex(vert0,vertMap,verts); } //add 0's to normals until it matches vert count @@ -813,7 +904,7 @@ public class TransvoxelModelGeneration { trianglesSharingVert.set(index0, trianglesSharingIndex0 + 1); Vector3f currentNormal = normals.get(index0); - currentNormal = averageNormals(currentNormal,oldProportion,n,newProportion); + currentNormal = TransvoxelModelGeneration.averageNormals(currentNormal,oldProportion,n,newProportion); normals.get(index0).set(currentNormal); @@ -828,7 +919,7 @@ public class TransvoxelModelGeneration { trianglesSharingVert.set(index1, trianglesSharingIndex1 + 1); currentNormal = normals.get(index1); - currentNormal = averageNormals(currentNormal,oldProportion,n,newProportion); + currentNormal = TransvoxelModelGeneration.averageNormals(currentNormal,oldProportion,n,newProportion); normals.get(index1).set(currentNormal); @@ -846,7 +937,7 @@ public class TransvoxelModelGeneration { trianglesSharingVert.set(index2, trianglesSharingIndex2 + 1); currentNormal = normals.get(index2); - currentNormal = averageNormals(currentNormal,oldProportion,n,newProportion); + currentNormal = TransvoxelModelGeneration.averageNormals(currentNormal,oldProportion,n,newProportion); normals.get(index2).set(currentNormal); } @@ -993,17 +1084,44 @@ public class TransvoxelModelGeneration { } //interpolates the location that the edge gets cut based on the magnitudes of the scalars of the vertices at either end of the edge - static Vector3f VertexInterp(double isolevel, Vector3f p1, Vector3f p2, double valp1, double valp2){ + protected static Vector3f VertexInterp(double isolevel, Vector3f p1, Vector3f p2, double valp1, double valp2){ double mu; float x, y, z; - if (Math.abs(isolevel-valp1) < 0.00001) - return(p1); - if (Math.abs(isolevel-valp2) < 0.00001) - return(p2); - if (Math.abs(valp1-valp2) < 0.00001) - return(p1); - mu = (isolevel - valp1) / (valp2 - valp1); + if(valp1 == 0){ + if(valp2 == 0){ + mu = 0.5f; + } else if(valp2 > 0){ + return p2; + } else { + mu = 0.5; + } + } else if(valp2 == 0){ + if(valp1 > 0){ + return p1; + } else { + mu = 0.5; + } + } else { + if(Math.abs(valp1-valp2) < MIN_DIST){ + mu = 0.5; + } else { + mu = (isolevel - valp1) / (valp2 - valp1); + } + } + + if(valp1 > 0 && valp2 > 0){ + throw new Error("Both values are positive! " + valp1 + " " + valp2); + } else if(valp1 < 0 && valp2 < 0){ + throw new Error("Both values are negative! " + valp1 + " " + valp2); + } + + // if(Math.abs(valp1-valp2) < MIN_DIST){ + // mu = 0.5; + // } else { + // mu = (isolevel - valp1) / (valp2 - valp1); + // } + x = (float)(p1.x + mu * (p2.x - p1.x)); y = (float)(p1.y + mu * (p2.y - p1.y)); z = (float)(p1.z + mu * (p2.z - p1.z)); @@ -1011,11 +1129,6 @@ public class TransvoxelModelGeneration { return new Vector3f(x,y,z); } - //TODO: more optimal key creation - private static String getVertKeyFromPoints(float x, float y, float z){ - return x + "_" + y + "_" + z; - } - /** * Gets the already existing index of this point * @param vert the vertex's raw position @@ -1023,15 +1136,18 @@ public class TransvoxelModelGeneration { * @param verts * @return */ - private static int getVertIndex(Vector3f vert, Map vertMap, List verts){ + private static int getVertIndex(Vector3f vert, Map vertMap, List verts){ + if(vert == null){ + throw new Error("Provided null value! " + vert); + } int rVal = -1; - String vertKey = getVertKeyFromPoints(vert.x,vert.y,vert.z); - if(vertMap.containsKey(vertKey)){ - return vertMap.get(vertKey); + // String vertKey = TransvoxelModelGeneration.getVertKeyFromPoints(vert.x,vert.y,vert.z); + if(vertMap.containsKey(vert)){ + return vertMap.get(vert); } else { rVal = verts.size(); verts.add(vert); - vertMap.put(vertKey,rVal); + vertMap.put(vert,rVal); return rVal; } } @@ -1045,8 +1161,11 @@ public class TransvoxelModelGeneration { * @return The mixed vector */ private static Vector3f averageNormals(Vector3f normal0, float proportion0, Vector3f normal1, float proportion1){ - Vector3f rVal = new Vector3f(normal0); - rVal = rVal.mul(proportion0).add(new Vector3f(normal1).mul(proportion1)); + Vector3f rVal = new Vector3f( + normal0.x * proportion0 + normal1.x * proportion1, + normal0.y * proportion0 + normal1.y * proportion1, + normal0.z * proportion0 + normal1.z * proportion1 + ); return rVal; } @@ -1078,7 +1197,7 @@ public class TransvoxelModelGeneration { //the list of all triangles List triangles = new LinkedList(); //the map of vertex to index - Map vertMap = new HashMap(); + Map vertMap = new HashMap(); //the list of all verts List verts = new LinkedList(); //the list of all normals @@ -1088,6 +1207,16 @@ public class TransvoxelModelGeneration { //List of texture sampler values List samplerTriangles = new LinkedList(); + //the vector pool + Vector3f[] vecPool = new Vector3f[VECTOR_POOL_SIZE]; + for(int i = 0; i < VECTOR_POOL_SIZE; i++){ + vecPool[i] = new Vector3f(); + } + + currentCell.setVectors( + vecPool[0], vecPool[1], vecPool[2], vecPool[3], + vecPool[4], vecPool[5], vecPool[6], vecPool[7] + ); // @@ -1095,17 +1224,25 @@ public class TransvoxelModelGeneration { for(int x = 1; x < chunkData.terrainGrid.length - 2; x++){ for(int y = 1; y < chunkData.terrainGrid[0].length - 2; y++){ for(int z = 1; z < chunkData.terrainGrid[0][0].length - 2; z++){ + vecPool[0].set(x+0,y+0,z+0); + vecPool[1].set(x+0,y+0,z+1); + vecPool[2].set(x+1,y+0,z+1); + vecPool[3].set(x+1,y+0,z+0); + vecPool[4].set(x+0,y+1,z+0); + vecPool[5].set(x+0,y+1,z+1); + vecPool[6].set(x+1,y+1,z+1); + vecPool[7].set(x+1,y+1,z+0); //push the current cell's values into the gridcell currentCell.setValues( - new Vector3f(x+0,y+0,z+0), new Vector3f(x+0,y+0,z+1), new Vector3f(x+1,y+0,z+1), new Vector3f(x+1,y+0,z+0), - new Vector3f(x+0,y+1,z+0), new Vector3f(x+0,y+1,z+1), new Vector3f(x+1,y+1,z+1), new Vector3f(x+1,y+1,z+0), + // vecPool[0], vecPool[1], vecPool[2], vecPool[3], + // vecPool[4], vecPool[5], vecPool[6], vecPool[7], chunkData.terrainGrid[x+0][y+0][z+0], chunkData.terrainGrid[x+0][y+0][z+1], chunkData.terrainGrid[x+1][y+0][z+1], chunkData.terrainGrid[x+1][y+0][z+0], chunkData.terrainGrid[x+0][y+1][z+0], chunkData.terrainGrid[x+0][y+1][z+1], chunkData.terrainGrid[x+1][y+1][z+1], chunkData.terrainGrid[x+1][y+1][z+0], chunkData.textureGrid[x+0][y+0][z+0], chunkData.textureGrid[x+0][y+0][z+1], chunkData.textureGrid[x+1][y+0][z+1], chunkData.textureGrid[x+1][y+0][z+0], chunkData.textureGrid[x+0][y+1][z+0], chunkData.textureGrid[x+0][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+0] ); //polygonize the current gridcell - polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); + TransvoxelModelGeneration.polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); } } } @@ -1155,38 +1292,54 @@ public class TransvoxelModelGeneration { chunkData.xPositiveEdgeAtlas[(y+0)*2+0][(z+0)*2+0], chunkData.xPositiveEdgeAtlas[(y+1)*2+0][(z+0)*2+0], chunkData.xPositiveEdgeAtlas[(y+0)*2+0][(z+1)*2+0], chunkData.xPositiveEdgeAtlas[(y+1)*2+0][(z+1)*2+0] ); - polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, true); + TransvoxelModelGeneration.polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, true); // //Generate the normal cell with half width // + vecPool[0].set(x+0,y+0,z+0); + vecPool[1].set(x+0,y+0,z+1); + vecPool[2].set(x+TRANSITION_CELL_WIDTH,y+0,z+1); + vecPool[3].set(x+TRANSITION_CELL_WIDTH,y+0,z+0); + vecPool[4].set(x+0,y+1,z+0); + vecPool[5].set(x+0,y+1,z+1); + vecPool[6].set(x+TRANSITION_CELL_WIDTH,y+1,z+1); + vecPool[7].set(x+TRANSITION_CELL_WIDTH,y+1,z+0); currentCell.setValues( - new Vector3f(x+0,y+0,z+0), new Vector3f(x+0,y+0,z+1), new Vector3f(x+TRANSITION_CELL_WIDTH,y+0,z+1), new Vector3f(x+TRANSITION_CELL_WIDTH,y+0,z+0), - new Vector3f(x+0,y+1,z+0), new Vector3f(x+0,y+1,z+1), new Vector3f(x+TRANSITION_CELL_WIDTH,y+1,z+1), new Vector3f(x+TRANSITION_CELL_WIDTH,y+1,z+0), + // new Vector3f(x+0,y+0,z+0), new Vector3f(x+0,y+0,z+1), new Vector3f(x+TRANSITION_CELL_WIDTH,y+0,z+1), new Vector3f(x+TRANSITION_CELL_WIDTH,y+0,z+0), + // new Vector3f(x+0,y+1,z+0), new Vector3f(x+0,y+1,z+1), new Vector3f(x+TRANSITION_CELL_WIDTH,y+1,z+1), new Vector3f(x+TRANSITION_CELL_WIDTH,y+1,z+0), chunkData.terrainGrid[x+0][y+0][z+0], chunkData.terrainGrid[x+0][y+0][z+1], chunkData.xPositiveEdgeIso[(y+0)*2+0][(z+1)*2+0], chunkData.xPositiveEdgeIso[(y+0)*2+0][(z+0)*2+0], chunkData.terrainGrid[x+0][y+1][z+0], chunkData.terrainGrid[x+0][y+1][z+1], chunkData.xPositiveEdgeIso[(y+1)*2+0][(z+1)*2+0], chunkData.xPositiveEdgeIso[(y+1)*2+0][(z+0)*2+0], chunkData.textureGrid[x+0][y+0][z+0], chunkData.textureGrid[x+0][y+0][z+1], chunkData.xPositiveEdgeAtlas[(y+0)*2+0][(z+1)*2+0], chunkData.xPositiveEdgeAtlas[(y+0)*2+0][(z+0)*2+0], chunkData.textureGrid[x+0][y+1][z+0], chunkData.textureGrid[x+0][y+1][z+1], chunkData.xPositiveEdgeAtlas[(y+1)*2+0][(z+1)*2+0], chunkData.xPositiveEdgeAtlas[(y+1)*2+0][(z+0)*2+0] ); //polygonize the current gridcell - polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); + TransvoxelModelGeneration.polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); } } } else { int x = ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE - 2; for(int y = yStartIndex; y < yEndIndex; y++){ for(int z = zStartIndex; z < zEndIndex; z++){ + vecPool[0].set(x+0,y+0,z+0); + vecPool[1].set(x+0,y+0,z+1); + vecPool[2].set(x+1,y+0,z+1); + vecPool[3].set(x+1,y+0,z+0); + vecPool[4].set(x+0,y+1,z+0); + vecPool[5].set(x+0,y+1,z+1); + vecPool[6].set(x+1,y+1,z+1); + vecPool[7].set(x+1,y+1,z+0); //push the current cell's values into the gridcell currentCell.setValues( - new Vector3f(x+0,y+0,z+0), new Vector3f(x+0,y+0,z+1), new Vector3f(x+1,y+0,z+1), new Vector3f(x+1,y+0,z+0), - new Vector3f(x+0,y+1,z+0), new Vector3f(x+0,y+1,z+1), new Vector3f(x+1,y+1,z+1), new Vector3f(x+1,y+1,z+0), + // vecPool[0], vecPool[1], vecPool[2], vecPool[3], + // vecPool[4], vecPool[5], vecPool[6], vecPool[7], chunkData.terrainGrid[x+0][y+0][z+0], chunkData.terrainGrid[x+0][y+0][z+1], chunkData.terrainGrid[x+1][y+0][z+1], chunkData.terrainGrid[x+1][y+0][z+0], chunkData.terrainGrid[x+0][y+1][z+0], chunkData.terrainGrid[x+0][y+1][z+1], chunkData.terrainGrid[x+1][y+1][z+1], chunkData.terrainGrid[x+1][y+1][z+0], chunkData.textureGrid[x+0][y+0][z+0], chunkData.textureGrid[x+0][y+0][z+1], chunkData.textureGrid[x+1][y+0][z+1], chunkData.textureGrid[x+1][y+0][z+0], chunkData.textureGrid[x+0][y+1][z+0], chunkData.textureGrid[x+0][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+0] ); //polygonize the current gridcell - polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); + TransvoxelModelGeneration.polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); } } } @@ -1229,38 +1382,54 @@ public class TransvoxelModelGeneration { chunkData.xNegativeEdgeAtlas[(y+0)*2+0][(z+0)*2+0], chunkData.xNegativeEdgeAtlas[(y+1)*2+0][(z+0)*2+0], chunkData.xNegativeEdgeAtlas[(y+0)*2+0][(z+1)*2+0], chunkData.xNegativeEdgeAtlas[(y+1)*2+0][(z+1)*2+0] ); - polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); + TransvoxelModelGeneration.polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); // //Generate the normal cell with half width // + vecPool[0].set(x+TRANSITION_CELL_WIDTH,y+0,z+0); + vecPool[1].set(x+TRANSITION_CELL_WIDTH,y+0,z+1); + vecPool[2].set(x+1,y+0,z+1); + vecPool[3].set(x+1,y+0,z+0); + vecPool[4].set(x+TRANSITION_CELL_WIDTH,y+1,z+0); + vecPool[5].set(x+TRANSITION_CELL_WIDTH,y+1,z+1); + vecPool[6].set(x+1,y+1,z+1); + vecPool[7].set(x+1,y+1,z+0); currentCell.setValues( - new Vector3f(x+TRANSITION_CELL_WIDTH,y+0,z+0), new Vector3f(x+TRANSITION_CELL_WIDTH,y+0,z+1), new Vector3f(x+1,y+0,z+1), new Vector3f(x+1,y+0,z+0), - new Vector3f(x+TRANSITION_CELL_WIDTH,y+1,z+0), new Vector3f(x+TRANSITION_CELL_WIDTH,y+1,z+1), new Vector3f(x+1,y+1,z+1), new Vector3f(x+1,y+1,z+0), + // new Vector3f(x+TRANSITION_CELL_WIDTH,y+0,z+0), new Vector3f(x+TRANSITION_CELL_WIDTH,y+0,z+1), new Vector3f(x+1,y+0,z+1), new Vector3f(x+1,y+0,z+0), + // new Vector3f(x+TRANSITION_CELL_WIDTH,y+1,z+0), new Vector3f(x+TRANSITION_CELL_WIDTH,y+1,z+1), new Vector3f(x+1,y+1,z+1), new Vector3f(x+1,y+1,z+0), chunkData.xNegativeEdgeIso[(y+0)*2+0][(z+0)*2+0], chunkData.xNegativeEdgeIso[(y+0)*2+0][(z+1)*2+0], chunkData.terrainGrid[x+1][y+0][z+1], chunkData.terrainGrid[x+1][y+0][z+0], chunkData.xNegativeEdgeIso[(y+1)*2+0][(z+0)*2+0], chunkData.xNegativeEdgeIso[(y+1)*2+0][(z+1)*2+0], chunkData.terrainGrid[x+1][y+1][z+1], chunkData.terrainGrid[x+1][y+1][z+0], chunkData.xNegativeEdgeAtlas[(y+0)*2+0][(z+0)*2+0], chunkData.xNegativeEdgeAtlas[(y+0)*2+0][(z+1)*2+0], chunkData.textureGrid[x+1][y+0][z+1], chunkData.textureGrid[x+1][y+0][z+0], chunkData.xNegativeEdgeAtlas[(y+1)*2+0][(z+0)*2+0], chunkData.xNegativeEdgeAtlas[(y+1)*2+0][(z+1)*2+0], chunkData.textureGrid[x+1][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+0] ); //polygonize the current gridcell - polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); + TransvoxelModelGeneration.polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); } } } else { int x = 0; for(int y = yStartIndex; y < yEndIndex; y++){ for(int z = zStartIndex; z < zEndIndex; z++){ + vecPool[0].set(x+0,y+0,z+0); + vecPool[1].set(x+0,y+0,z+1); + vecPool[2].set(x+1,y+0,z+1); + vecPool[3].set(x+1,y+0,z+0); + vecPool[4].set(x+0,y+1,z+0); + vecPool[5].set(x+0,y+1,z+1); + vecPool[6].set(x+1,y+1,z+1); + vecPool[7].set(x+1,y+1,z+0); //push the current cell's values into the gridcell currentCell.setValues( - new Vector3f(x+0,y+0,z+0), new Vector3f(x+0,y+0,z+1), new Vector3f(x+1,y+0,z+1), new Vector3f(x+1,y+0,z+0), - new Vector3f(x+0,y+1,z+0), new Vector3f(x+0,y+1,z+1), new Vector3f(x+1,y+1,z+1), new Vector3f(x+1,y+1,z+0), + // vecPool[0], vecPool[1], vecPool[2], vecPool[3], + // vecPool[4], vecPool[5], vecPool[6], vecPool[7], chunkData.terrainGrid[x+0][y+0][z+0], chunkData.terrainGrid[x+0][y+0][z+1], chunkData.terrainGrid[x+1][y+0][z+1], chunkData.terrainGrid[x+1][y+0][z+0], chunkData.terrainGrid[x+0][y+1][z+0], chunkData.terrainGrid[x+0][y+1][z+1], chunkData.terrainGrid[x+1][y+1][z+1], chunkData.terrainGrid[x+1][y+1][z+0], chunkData.textureGrid[x+0][y+0][z+0], chunkData.textureGrid[x+0][y+0][z+1], chunkData.textureGrid[x+1][y+0][z+1], chunkData.textureGrid[x+1][y+0][z+0], chunkData.textureGrid[x+0][y+1][z+0], chunkData.textureGrid[x+0][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+0] ); //polygonize the current gridcell - polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); + TransvoxelModelGeneration.polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); } } } @@ -1302,38 +1471,54 @@ public class TransvoxelModelGeneration { chunkData.yPositiveEdgeAtlas[(x+0)*2+0][(z+0)*2+0], chunkData.yPositiveEdgeAtlas[(x+1)*2+0][(z+0)*2+0], chunkData.yPositiveEdgeAtlas[(x+0)*2+0][(z+1)*2+0], chunkData.yPositiveEdgeAtlas[(x+1)*2+0][(z+1)*2+0] ); - polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); + TransvoxelModelGeneration.polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); // //Generate the normal cell with half width // + vecPool[0].set(x+0,y+0,z+0); + vecPool[1].set(x+0,y+0,z+1); + vecPool[2].set(x+1,y+0,z+1); + vecPool[3].set(x+1,y+0,z+0); + vecPool[4].set(x+0,y+TRANSITION_CELL_WIDTH,z+0); + vecPool[5].set(x+0,y+TRANSITION_CELL_WIDTH,z+1); + vecPool[6].set(x+1,y+TRANSITION_CELL_WIDTH,z+1); + vecPool[7].set(x+1,y+TRANSITION_CELL_WIDTH,z+0); currentCell.setValues( - new Vector3f(x+0,y+0,z+0), new Vector3f(x+0,y+0,z+1), new Vector3f(x+1,y,z+1), new Vector3f(x+1,y,z+0), - new Vector3f(x+0,y+TRANSITION_CELL_WIDTH,z+0), new Vector3f(x+0,y+TRANSITION_CELL_WIDTH,z+1), new Vector3f(x+1,y+TRANSITION_CELL_WIDTH,z+1), new Vector3f(x+1,y+TRANSITION_CELL_WIDTH,z+0), + // new Vector3f(x+0,y+0,z+0), new Vector3f(x+0,y+0,z+1), new Vector3f(x+1,y,z+1), new Vector3f(x+1,y,z+0), + // new Vector3f(x+0,y+TRANSITION_CELL_WIDTH,z+0), new Vector3f(x+0,y+TRANSITION_CELL_WIDTH,z+1), new Vector3f(x+1,y+TRANSITION_CELL_WIDTH,z+1), new Vector3f(x+1,y+TRANSITION_CELL_WIDTH,z+0), chunkData.terrainGrid[x+0][y+0][z+0], chunkData.terrainGrid[x+0][y+0][z+1], chunkData.terrainGrid[x+1][y+0][z+1], chunkData.terrainGrid[x+1][y+0][z+0], chunkData.yPositiveEdgeIso[(x+0)*2+0][(z+0)*2+0], chunkData.yPositiveEdgeIso[(x+0)*2+0][(z+1)*2+0], chunkData.yPositiveEdgeIso[(x+1)*2+0][(z+1)*2+0], chunkData.yPositiveEdgeIso[(x+1)*2+0][(z+0)*2+0], chunkData.textureGrid[x+0][y+0][z+0], chunkData.textureGrid[x+0][y+0][z+1], chunkData.textureGrid[x+1][y+0][z+1], chunkData.textureGrid[x+1][y+0][z+0], chunkData.yPositiveEdgeAtlas[(x+0)*2+0][(z+0)*2+0], chunkData.yPositiveEdgeAtlas[(x+0)*2+0][(z+1)*2+0], chunkData.yPositiveEdgeAtlas[(x+1)*2+0][(z+1)*2+0], chunkData.yPositiveEdgeAtlas[(x+1)*2+0][(z+0)*2+0] ); //polygonize the current gridcell - polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); + TransvoxelModelGeneration.polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); } } } else { int y = ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE - 2; for(int x = xStartIndex; x < xEndIndex; x++){ for(int z = zStartIndex; z < zEndIndex; z++){ + vecPool[0].set(x+0,y+0,z+0); + vecPool[1].set(x+0,y+0,z+1); + vecPool[2].set(x+1,y+0,z+1); + vecPool[3].set(x+1,y+0,z+0); + vecPool[4].set(x+0,y+1,z+0); + vecPool[5].set(x+0,y+1,z+1); + vecPool[6].set(x+1,y+1,z+1); + vecPool[7].set(x+1,y+1,z+0); //push the current cell's values into the gridcell currentCell.setValues( - new Vector3f(x+0,y+0,z+0), new Vector3f(x+0,y+0,z+1), new Vector3f(x+1,y+0,z+1), new Vector3f(x+1,y+0,z+0), - new Vector3f(x+0,y+1,z+0), new Vector3f(x+0,y+1,z+1), new Vector3f(x+1,y+1,z+1), new Vector3f(x+1,y+1,z+0), + // vecPool[0], vecPool[1], vecPool[2], vecPool[3], + // vecPool[4], vecPool[5], vecPool[6], vecPool[7], chunkData.terrainGrid[x+0][y+0][z+0], chunkData.terrainGrid[x+0][y+0][z+1], chunkData.terrainGrid[x+1][y+0][z+1], chunkData.terrainGrid[x+1][y+0][z+0], chunkData.terrainGrid[x+0][y+1][z+0], chunkData.terrainGrid[x+0][y+1][z+1], chunkData.terrainGrid[x+1][y+1][z+1], chunkData.terrainGrid[x+1][y+1][z+0], chunkData.textureGrid[x+0][y+0][z+0], chunkData.textureGrid[x+0][y+0][z+1], chunkData.textureGrid[x+1][y+0][z+1], chunkData.textureGrid[x+1][y+0][z+0], chunkData.textureGrid[x+0][y+1][z+0], chunkData.textureGrid[x+0][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+0] ); //polygonize the current gridcell - polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); + TransvoxelModelGeneration.polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); } } } @@ -1375,38 +1560,54 @@ public class TransvoxelModelGeneration { chunkData.yNegativeEdgeAtlas[(x+0)*2+0][(z+0)*2+0], chunkData.yNegativeEdgeAtlas[(x+1)*2+0][(z+0)*2+0], chunkData.yNegativeEdgeAtlas[(x+0)*2+0][(z+1)*2+0], chunkData.yNegativeEdgeAtlas[(x+1)*2+0][(z+1)*2+0] ); - polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, true); + TransvoxelModelGeneration.polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, true); // //Generate the normal cell with half width // + vecPool[0].set(x+0,y+1,z+0); + vecPool[1].set(x+0,y+1,z+1); + vecPool[2].set(x+1,y+1,z+1); + vecPool[3].set(x+1,y+1,z+0); + vecPool[4].set(x+0,y+TRANSITION_CELL_WIDTH,z+0); + vecPool[5].set(x+0,y+TRANSITION_CELL_WIDTH,z+1); + vecPool[6].set(x+1,y+TRANSITION_CELL_WIDTH,z+1); + vecPool[7].set(x+1,y+TRANSITION_CELL_WIDTH,z+0); currentCell.setValues( - new Vector3f(x+0,y+1,z+0), new Vector3f(x+0,y+1,z+1), new Vector3f(x+1,y+1,z+1), new Vector3f(x+1,y+1,z+0), - new Vector3f(x+0,y+TRANSITION_CELL_WIDTH,z+0), new Vector3f(x+0,y+TRANSITION_CELL_WIDTH,z+1), new Vector3f(x+1,y+TRANSITION_CELL_WIDTH,z+1), new Vector3f(x+1,y+TRANSITION_CELL_WIDTH,z+0), + // new Vector3f(x+0,y+1,z+0), new Vector3f(x+0,y+1,z+1), new Vector3f(x+1,y+1,z+1), new Vector3f(x+1,y+1,z+0), + // new Vector3f(x+0,y+TRANSITION_CELL_WIDTH,z+0), new Vector3f(x+0,y+TRANSITION_CELL_WIDTH,z+1), new Vector3f(x+1,y+TRANSITION_CELL_WIDTH,z+1), new Vector3f(x+1,y+TRANSITION_CELL_WIDTH,z+0), chunkData.terrainGrid[x+0][y+1][z+0], chunkData.terrainGrid[x+0][y+1][z+1], chunkData.terrainGrid[x+1][y+1][z+1], chunkData.terrainGrid[x+1][y+1][z+0], chunkData.yNegativeEdgeIso[(x+0)*2+0][(z+0)*2+0], chunkData.yNegativeEdgeIso[(x+0)*2+0][(z+1)*2+0], chunkData.yNegativeEdgeIso[(x+1)*2+0][(z+1)*2+0], chunkData.yNegativeEdgeIso[(x+1)*2+0][(z+0)*2+0], chunkData.textureGrid[x+0][y+1][z+0], chunkData.textureGrid[x+0][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+0], chunkData.yNegativeEdgeAtlas[(x+0)*2+0][(z+0)*2+0], chunkData.yNegativeEdgeAtlas[(x+0)*2+0][(z+1)*2+0], chunkData.yNegativeEdgeAtlas[(x+1)*2+0][(z+1)*2+0], chunkData.yNegativeEdgeAtlas[(x+1)*2+0][(z+0)*2+0] ); //polygonize the current gridcell - polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, true); + TransvoxelModelGeneration.polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, true); } } } else { int y = 0; for(int x = xStartIndex; x < xEndIndex; x++){ for(int z = zStartIndex; z < zEndIndex; z++){ + vecPool[0].set(x+0,y+0,z+0); + vecPool[1].set(x+0,y+0,z+1); + vecPool[2].set(x+1,y+0,z+1); + vecPool[3].set(x+1,y+0,z+0); + vecPool[4].set(x+0,y+1,z+0); + vecPool[5].set(x+0,y+1,z+1); + vecPool[6].set(x+1,y+1,z+1); + vecPool[7].set(x+1,y+1,z+0); //push the current cell's values into the gridcell currentCell.setValues( - new Vector3f(x+0,y+0,z+0), new Vector3f(x+0,y+0,z+1), new Vector3f(x+1,y+0,z+1), new Vector3f(x+1,y+0,z+0), - new Vector3f(x+0,y+1,z+0), new Vector3f(x+0,y+1,z+1), new Vector3f(x+1,y+1,z+1), new Vector3f(x+1,y+1,z+0), + // vecPool[0], vecPool[1], vecPool[2], vecPool[3], + // vecPool[4], vecPool[5], vecPool[6], vecPool[7], chunkData.terrainGrid[x+0][y+0][z+0], chunkData.terrainGrid[x+0][y+0][z+1], chunkData.terrainGrid[x+1][y+0][z+1], chunkData.terrainGrid[x+1][y+0][z+0], chunkData.terrainGrid[x+0][y+1][z+0], chunkData.terrainGrid[x+0][y+1][z+1], chunkData.terrainGrid[x+1][y+1][z+1], chunkData.terrainGrid[x+1][y+1][z+0], chunkData.textureGrid[x+0][y+0][z+0], chunkData.textureGrid[x+0][y+0][z+1], chunkData.textureGrid[x+1][y+0][z+1], chunkData.textureGrid[x+1][y+0][z+0], chunkData.textureGrid[x+0][y+1][z+0], chunkData.textureGrid[x+0][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+0] ); //polygonize the current gridcell - polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); + TransvoxelModelGeneration.polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); } } } @@ -1449,38 +1650,54 @@ public class TransvoxelModelGeneration { chunkData.zPositiveEdgeAtlas[(x+0)*2+0][(y+0)*2+0], chunkData.zPositiveEdgeAtlas[(x+0)*2+0][(y+1)*2+0], chunkData.zPositiveEdgeAtlas[(x+1)*2+0][(y+0)*2+0], chunkData.zPositiveEdgeAtlas[(x+1)*2+0][(y+1)*2+0] ); - polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); + TransvoxelModelGeneration.polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); // //Generate the normal cell with half width // + vecPool[0].set(x+0,y+0,z+0); + vecPool[1].set(x+0,y+0,z+TRANSITION_CELL_WIDTH); + vecPool[2].set(x+1,y+0,z+TRANSITION_CELL_WIDTH); + vecPool[3].set(x+1,y+0,z+0); + vecPool[4].set(x+0,y+1,z+0); + vecPool[5].set(x+0,y+1,z+TRANSITION_CELL_WIDTH); + vecPool[6].set(x+1,y+1,z+TRANSITION_CELL_WIDTH); + vecPool[7].set(x+1,y+1,z+0); currentCell.setValues( - new Vector3f(x+0,y+0,z+0), new Vector3f(x+0,y+0,z+TRANSITION_CELL_WIDTH), new Vector3f(x+1,y+0,z+TRANSITION_CELL_WIDTH), new Vector3f(x+1,y+0,z+0), - new Vector3f(x+0,y+1,z+0), new Vector3f(x+0,y+1,z+TRANSITION_CELL_WIDTH), new Vector3f(x+1,y+1,z+TRANSITION_CELL_WIDTH), new Vector3f(x+1,y+1,z+0), + // new Vector3f(x+0,y+0,z+0), new Vector3f(x+0,y+0,z+TRANSITION_CELL_WIDTH), new Vector3f(x+1,y+0,z+TRANSITION_CELL_WIDTH), new Vector3f(x+1,y+0,z+0), + // new Vector3f(x+0,y+1,z+0), new Vector3f(x+0,y+1,z+TRANSITION_CELL_WIDTH), new Vector3f(x+1,y+1,z+TRANSITION_CELL_WIDTH), new Vector3f(x+1,y+1,z+0), chunkData.terrainGrid[x+0][y+0][z+0], chunkData.zPositiveEdgeIso[(x+0)*2+0][(y+0)*2+0], chunkData.zPositiveEdgeIso[(x+1)*2+0][(y+0)*2+0], chunkData.terrainGrid[x+1][y+0][z+0], chunkData.terrainGrid[x+0][y+1][z+0], chunkData.zPositiveEdgeIso[(x+0)*2+0][(y+1)*2+0], chunkData.zPositiveEdgeIso[(x+1)*2+0][(y+1)*2+0], chunkData.terrainGrid[x+1][y+1][z+0], chunkData.textureGrid[x+0][y+0][z+0], chunkData.zPositiveEdgeAtlas[(x+0)*2+0][(y+0)*2+0], chunkData.zPositiveEdgeAtlas[(x+1)*2+0][(y+0)*2+0], chunkData.textureGrid[x+1][y+0][z+0], chunkData.textureGrid[x+0][y+1][z+0], chunkData.zPositiveEdgeAtlas[(x+0)*2+0][(y+1)*2+0], chunkData.zPositiveEdgeAtlas[(x+1)*2+0][(y+1)*2+0], chunkData.textureGrid[x+1][y+1][z+0] ); //polygonize the current gridcell - polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); + TransvoxelModelGeneration.polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); } } } else { int z = ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE - 2; for(int x = xStartIndex; x < xEndIndex; x++){ for(int y = yStartIndex; y < yEndIndex; y++){ + vecPool[0].set(x+0,y+0,z+0); + vecPool[1].set(x+0,y+0,z+1); + vecPool[2].set(x+1,y+0,z+1); + vecPool[3].set(x+1,y+0,z+0); + vecPool[4].set(x+0,y+1,z+0); + vecPool[5].set(x+0,y+1,z+1); + vecPool[6].set(x+1,y+1,z+1); + vecPool[7].set(x+1,y+1,z+0); //push the current cell's values into the gridcell currentCell.setValues( - new Vector3f(x+0,y+0,z+0), new Vector3f(x+0,y+0,z+1), new Vector3f(x+1,y+0,z+1), new Vector3f(x+1,y+0,z+0), - new Vector3f(x+0,y+1,z+0), new Vector3f(x+0,y+1,z+1), new Vector3f(x+1,y+1,z+1), new Vector3f(x+1,y+1,z+0), + // vecPool[0], vecPool[1], vecPool[2], vecPool[3], + // vecPool[4], vecPool[5], vecPool[6], vecPool[7], chunkData.terrainGrid[x+0][y+0][z+0], chunkData.terrainGrid[x+0][y+0][z+1], chunkData.terrainGrid[x+1][y+0][z+1], chunkData.terrainGrid[x+1][y+0][z+0], chunkData.terrainGrid[x+0][y+1][z+0], chunkData.terrainGrid[x+0][y+1][z+1], chunkData.terrainGrid[x+1][y+1][z+1], chunkData.terrainGrid[x+1][y+1][z+0], chunkData.textureGrid[x+0][y+0][z+0], chunkData.textureGrid[x+0][y+0][z+1], chunkData.textureGrid[x+1][y+0][z+1], chunkData.textureGrid[x+1][y+0][z+0], chunkData.textureGrid[x+0][y+1][z+0], chunkData.textureGrid[x+0][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+0] ); //polygonize the current gridcell - polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); + TransvoxelModelGeneration.polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); } } } @@ -1523,38 +1740,54 @@ public class TransvoxelModelGeneration { chunkData.zNegativeEdgeAtlas[(x+0)*2+0][(y+0)*2+0], chunkData.zNegativeEdgeAtlas[(x+0)*2+0][(y+1)*2+0], chunkData.zNegativeEdgeAtlas[(x+1)*2+0][(y+0)*2+0], chunkData.zNegativeEdgeAtlas[(x+1)*2+0][(y+1)*2+0] ); - polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, true); + TransvoxelModelGeneration.polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, true); // //Generate the normal cell with half width // + vecPool[0].set(x+0,y+0,z+1); + vecPool[1].set(x+0,y+0,z+TRANSITION_CELL_WIDTH); + vecPool[2].set(x+1,y+0,z+TRANSITION_CELL_WIDTH); + vecPool[3].set(x+1,y+0,z+1); + vecPool[4].set(x+0,y+1,z+1); + vecPool[5].set(x+0,y+1,z+TRANSITION_CELL_WIDTH); + vecPool[6].set(x+1,y+1,z+TRANSITION_CELL_WIDTH); + vecPool[7].set(x+1,y+1,z+1); currentCell.setValues( - new Vector3f(x+0,y+0,z+1), new Vector3f(x+0,y+0,z+TRANSITION_CELL_WIDTH), new Vector3f(x+1,y+0,z+TRANSITION_CELL_WIDTH), new Vector3f(x+1,y+0,z+1), - new Vector3f(x+0,y+1,z+1), new Vector3f(x+0,y+1,z+TRANSITION_CELL_WIDTH), new Vector3f(x+1,y+1,z+TRANSITION_CELL_WIDTH), new Vector3f(x+1,y+1,z+1), + // new Vector3f(x+0,y+0,z+1), new Vector3f(x+0,y+0,z+TRANSITION_CELL_WIDTH), new Vector3f(x+1,y+0,z+TRANSITION_CELL_WIDTH), new Vector3f(x+1,y+0,z+1), + // new Vector3f(x+0,y+1,z+1), new Vector3f(x+0,y+1,z+TRANSITION_CELL_WIDTH), new Vector3f(x+1,y+1,z+TRANSITION_CELL_WIDTH), new Vector3f(x+1,y+1,z+1), chunkData.terrainGrid[x+0][y+0][z+1], chunkData.zNegativeEdgeIso[(x+0)*2+0][(y+0)*2+0], chunkData.zNegativeEdgeIso[(x+1)*2+0][(y+0)*2+0], chunkData.terrainGrid[x+1][y+0][z+1], chunkData.terrainGrid[x+0][y+1][z+1], chunkData.zNegativeEdgeIso[(x+0)*2+0][(y+1)*2+0], chunkData.zNegativeEdgeIso[(x+1)*2+0][(y+1)*2+0], chunkData.terrainGrid[x+1][y+1][z+1], chunkData.textureGrid[x+0][y+0][z+1], chunkData.zNegativeEdgeAtlas[(x+0)*2+0][(y+0)*2+0], chunkData.zNegativeEdgeAtlas[(x+1)*2+0][(y+0)*2+0], chunkData.textureGrid[x+1][y+0][z+1], chunkData.textureGrid[x+0][y+1][z+1], chunkData.zNegativeEdgeAtlas[(x+0)*2+0][(y+1)*2+0], chunkData.zNegativeEdgeAtlas[(x+1)*2+0][(y+1)*2+0], chunkData.textureGrid[x+1][y+1][z+1] ); //polygonize the current gridcell - polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, true); + TransvoxelModelGeneration.polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, true); } } } else { int z = 0; for(int x = xStartIndex; x < xEndIndex; x++){ for(int y = yStartIndex; y < yEndIndex; y++){ + vecPool[0].set(x+0,y+0,z+0); + vecPool[1].set(x+0,y+0,z+1); + vecPool[2].set(x+1,y+0,z+1); + vecPool[3].set(x+1,y+0,z+0); + vecPool[4].set(x+0,y+1,z+0); + vecPool[5].set(x+0,y+1,z+1); + vecPool[6].set(x+1,y+1,z+1); + vecPool[7].set(x+1,y+1,z+0); //push the current cell's values into the gridcell currentCell.setValues( - new Vector3f(x+0,y+0,z+0), new Vector3f(x+0,y+0,z+1), new Vector3f(x+1,y+0,z+1), new Vector3f(x+1,y+0,z+0), - new Vector3f(x+0,y+1,z+0), new Vector3f(x+0,y+1,z+1), new Vector3f(x+1,y+1,z+1), new Vector3f(x+1,y+1,z+0), + // vecPool[0], vecPool[1], vecPool[2], vecPool[3], + // vecPool[4], vecPool[5], vecPool[6], vecPool[7], chunkData.terrainGrid[x+0][y+0][z+0], chunkData.terrainGrid[x+0][y+0][z+1], chunkData.terrainGrid[x+1][y+0][z+1], chunkData.terrainGrid[x+1][y+0][z+0], chunkData.terrainGrid[x+0][y+1][z+0], chunkData.terrainGrid[x+0][y+1][z+1], chunkData.terrainGrid[x+1][y+1][z+1], chunkData.terrainGrid[x+1][y+1][z+0], chunkData.textureGrid[x+0][y+0][z+0], chunkData.textureGrid[x+0][y+0][z+1], chunkData.textureGrid[x+1][y+0][z+1], chunkData.textureGrid[x+1][y+0][z+0], chunkData.textureGrid[x+0][y+1][z+0], chunkData.textureGrid[x+0][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+0] ); //polygonize the current gridcell - polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); + TransvoxelModelGeneration.polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); } } } @@ -1594,7 +1827,7 @@ public class TransvoxelModelGeneration { chunkData.xNegativeEdgeAtlas[(y+0)*2+0][(z+0)*2+0], chunkData.xNegativeEdgeAtlas[(y+1)*2+0][(z+0)*2+0], chunkData.xNegativeEdgeAtlas[(y+0)*2+0][(z+1)*2+0], chunkData.xNegativeEdgeAtlas[(y+1)*2+0][(z+1)*2+0] ); - polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); + TransvoxelModelGeneration.polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); // //Generate the z-side transition cell @@ -1622,21 +1855,29 @@ public class TransvoxelModelGeneration { chunkData.zNegativeEdgeAtlas[(x+0)*2+0][(y+0)*2+0], chunkData.zNegativeEdgeAtlas[(x+0)*2+0][(y+1)*2+0], chunkData.zNegativeEdgeAtlas[(x+1)*2+0][(y+0)*2+0], chunkData.zNegativeEdgeAtlas[(x+1)*2+0][(y+1)*2+0] ); - polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, true); + TransvoxelModelGeneration.polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, true); // //Generate the normal cell with half width // + vecPool[0].set(x+TRANSITION_CELL_WIDTH,y+0,z+TRANSITION_CELL_WIDTH); + vecPool[1].set(x+TRANSITION_CELL_WIDTH,y+0,z+1); + vecPool[2].set(x+1,y+0,z+1); + vecPool[3].set(x+1,y+0,z+TRANSITION_CELL_WIDTH); + vecPool[4].set(x+TRANSITION_CELL_WIDTH,y+1,z+TRANSITION_CELL_WIDTH); + vecPool[5].set(x+TRANSITION_CELL_WIDTH,y+1,z+1); + vecPool[6].set(x+1,y+1,z+1); + vecPool[7].set(x+1,y+1,z+TRANSITION_CELL_WIDTH); currentCell.setValues( - new Vector3f(x+TRANSITION_CELL_WIDTH,y+0,z+TRANSITION_CELL_WIDTH), new Vector3f(x+TRANSITION_CELL_WIDTH,y+0,z+1), new Vector3f(x+1,y+0,z+1), new Vector3f(x+1,y+0,z+TRANSITION_CELL_WIDTH), - new Vector3f(x+TRANSITION_CELL_WIDTH,y+1,z+TRANSITION_CELL_WIDTH), new Vector3f(x+TRANSITION_CELL_WIDTH,y+1,z+1), new Vector3f(x+1,y+1,z+1), new Vector3f(x+1,y+1,z+TRANSITION_CELL_WIDTH), + // new Vector3f(x+TRANSITION_CELL_WIDTH,y+0,z+TRANSITION_CELL_WIDTH), new Vector3f(x+TRANSITION_CELL_WIDTH,y+0,z+1), new Vector3f(x+1,y+0,z+1), new Vector3f(x+1,y+0,z+TRANSITION_CELL_WIDTH), + // new Vector3f(x+TRANSITION_CELL_WIDTH,y+1,z+TRANSITION_CELL_WIDTH), new Vector3f(x+TRANSITION_CELL_WIDTH,y+1,z+1), new Vector3f(x+1,y+1,z+1), new Vector3f(x+1,y+1,z+TRANSITION_CELL_WIDTH), chunkData.xNegativeEdgeIso[(y+0)*2+0][(z+0)*2+0], chunkData.xNegativeEdgeIso[(y+0)*2+0][(z+1)*2+0], chunkData.terrainGrid[x+1][y+0][z+1], chunkData.terrainGrid[x+1][y+0][z+0], chunkData.xNegativeEdgeIso[(y+1)*2+0][(z+0)*2+0], chunkData.xNegativeEdgeIso[(y+1)*2+0][(z+1)*2+0], chunkData.terrainGrid[x+1][y+1][z+1], chunkData.terrainGrid[x+1][y+1][z+0], chunkData.xNegativeEdgeAtlas[(y+0)*2+0][(z+0)*2+0], chunkData.xNegativeEdgeAtlas[(y+0)*2+0][(z+1)*2+0], chunkData.textureGrid[x+1][y+0][z+1], chunkData.textureGrid[x+1][y+0][z+0], chunkData.xNegativeEdgeAtlas[(y+1)*2+0][(z+0)*2+0], chunkData.xNegativeEdgeAtlas[(y+1)*2+0][(z+1)*2+0], chunkData.textureGrid[x+1][y+1][z+1], chunkData.textureGrid[x+1][y+1][z+0] ); //polygonize the current gridcell - polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, true); + TransvoxelModelGeneration.polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, true); } } diff --git a/src/test/java/electrosphere/renderer/meshgen/TransvoxelModelGenerationTests.java b/src/test/java/electrosphere/renderer/meshgen/TransvoxelModelGenerationTests.java new file mode 100644 index 00000000..f64215ef --- /dev/null +++ b/src/test/java/electrosphere/renderer/meshgen/TransvoxelModelGenerationTests.java @@ -0,0 +1,76 @@ +package electrosphere.renderer.meshgen; + +import static org.junit.jupiter.api.Assertions.*; + +import org.joml.Vector3f; + +import electrosphere.test.annotations.UnitTest; + +/** + * Tests for the transvoxel model generation functions + */ +public class TransvoxelModelGenerationTests { + + + @UnitTest + public void testVertexInterp1(){ + assertThrows(Error.class, () -> { + TransvoxelModelGeneration.VertexInterp( + TerrainChunkModelGeneration.MIN_ISO_VALUE, + new Vector3f(15, 0, 6), + new Vector3f(16, 0, 6), + 0.08262646198272705, + 0.009999990463256836 + ); + }); + // Vector3f vec2 = TransvoxelModelGeneration.VertexInterp( + // TerrainChunkModelGeneration.MIN_ISO_VALUE, + // new Vector3f(16, 0, 6), + // new Vector3f(16, 0, 5), + // 0.009999990463256836, + // 0.05369114875793457 + // ); + // assertNotEquals(vec1, vec2); + } + + @UnitTest + public void testVertexInterp2(){ + Vector3f vec1 = TransvoxelModelGeneration.VertexInterp( + TerrainChunkModelGeneration.MIN_ISO_VALUE, + new Vector3f(1, 2, 0), + new Vector3f(0, 2, 0), + -0.338376522064209, + 0.0 + ); + Vector3f vec2 = TransvoxelModelGeneration.VertexInterp( + TerrainChunkModelGeneration.MIN_ISO_VALUE, + new Vector3f(0, 2, 0), + new Vector3f(0, 3, 0), + 0, + -1.0 + ); + assertNotEquals(vec1, vec2); + } + + @UnitTest + public void testVertexInterp3(){ + //vertList[1] = TransvoxelModelGeneration.VertexInterp(isolevel,grid.points[1],grid.points[2],grid.val[1],grid.val[2]); + //vertList[10] = TransvoxelModelGeneration.VertexInterp(isolevel,grid.points[2],grid.points[6],grid.val[2],grid.val[6]); + Vector3f vec1 = TransvoxelModelGeneration.VertexInterp( + TerrainChunkModelGeneration.MIN_ISO_VALUE, + new Vector3f(8, 8, 15.5f), + new Vector3f(9, 8, 15.5f), + 0.0, + -1.0 + ); + Vector3f vec2 = TransvoxelModelGeneration.VertexInterp( + TerrainChunkModelGeneration.MIN_ISO_VALUE, + new Vector3f(9, 8, 15.5f), + new Vector3f(9, 9, 15.5f), + -1.0, + 0.0 + ); + assertNotEquals(vec1, vec2); + } + +}