Terrain work
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit

This commit is contained in:
austin 2024-11-20 11:14:39 -05:00
parent 8284697812
commit 047e6af24f
5 changed files with 456 additions and 137 deletions

View File

@ -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

View File

@ -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)

View File

@ -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/

View File

@ -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<Triangle> triangles,
List<Vector3f> samplerIndices,
Map<String,Integer> vertMap,
List<Vector3f> verts,
List<Vector3f> normals,
List<Integer> trianglesSharingVert,
boolean invertNormals
){
GridCell grid,
double isolevel,
List<Triangle> triangles,
List<Vector3f> samplerIndices,
Map<Vector3f,Integer> vertMap,
List<Vector3f> verts,
List<Vector3f> normals,
List<Integer> 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<Triangle> triangles,
List<Vector3f> samplerIndices,
Map<String,Integer> vertMap,
Map<Vector3f,Integer> vertMap,
List<Vector3f> verts,
List<Vector3f> normals,
List<Integer> 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<String,Integer> vertMap, List<Vector3f> verts){
private static int getVertIndex(Vector3f vert, Map<Vector3f,Integer> vertMap, List<Vector3f> 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<Triangle> triangles = new LinkedList<Triangle>();
//the map of vertex to index
Map<String,Integer> vertMap = new HashMap<String,Integer>();
Map<Vector3f,Integer> vertMap = new HashMap<Vector3f,Integer>();
//the list of all verts
List<Vector3f> verts = new LinkedList<Vector3f>();
//the list of all normals
@ -1088,6 +1207,16 @@ public class TransvoxelModelGeneration {
//List of texture sampler values
List<Vector3f> samplerTriangles = new LinkedList<Vector3f>();
//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);
}
}

View File

@ -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);
}
}