Joined normals marching cubes
This commit is contained in:
parent
094831ba22
commit
edaa7c8ce2
@ -34,7 +34,7 @@ public class ClientTerrainManager {
|
||||
|
||||
ClientWorldData clientWorldData;
|
||||
|
||||
static List<TerrainChunkGenQueueItem> terrainChunkGenerationQueue = Collections.synchronizedList(new LinkedList<TerrainChunkGenQueueItem>());
|
||||
static List<TerrainChunkGenQueueItem> terrainChunkGenerationQueue = new CopyOnWriteArrayList<TerrainChunkGenQueueItem>();
|
||||
|
||||
|
||||
public ClientTerrainManager(ClientWorldData clientWorldData){
|
||||
|
||||
@ -322,12 +322,12 @@ public class TerrainChunkModelGeneration {
|
||||
};
|
||||
|
||||
static class Triangle {
|
||||
Vector3f[] points = new Vector3f[3]; //array of size 3
|
||||
int[] indices = new int[3]; //array of size 3
|
||||
|
||||
public Triangle(Vector3f point0,Vector3f point1,Vector3f point2){
|
||||
points[0] = point0;
|
||||
points[1] = point1;
|
||||
points[2] = point2;
|
||||
public Triangle(int index0, int index1, int index2){
|
||||
indices[0] = index0;
|
||||
indices[1] = index1;
|
||||
indices[2] = index2;
|
||||
}
|
||||
}
|
||||
|
||||
@ -347,7 +347,15 @@ public class TerrainChunkModelGeneration {
|
||||
}
|
||||
}
|
||||
|
||||
protected static int polygonize(GridCell grid, double isolevel, List<Triangle> triangles, Map<String,Integer> vertMap, List<Integer> indices){
|
||||
protected static int polygonize(
|
||||
GridCell grid,
|
||||
double isolevel,
|
||||
List<Triangle> triangles,
|
||||
Map<String,Integer> vertMap,
|
||||
List<Vector3f> verts,
|
||||
List<Vector3f> normals,
|
||||
List<Integer> trianglesSharingVert
|
||||
){
|
||||
int i;
|
||||
int ntriang;
|
||||
int cubeIndex = 0;
|
||||
@ -411,22 +419,88 @@ public class TerrainChunkModelGeneration {
|
||||
//Create the triangle
|
||||
ntriang = 0;
|
||||
for (i=0; triTable[cubeIndex][i]!=-1; i+=3) {
|
||||
//
|
||||
// Triangles calculation
|
||||
//
|
||||
//get indices
|
||||
Vector3f vert0 = vertList[triTable[cubeIndex][i+0]];
|
||||
Vector3f vert1 = vertList[triTable[cubeIndex][i+1]];
|
||||
Vector3f vert2 = vertList[triTable[cubeIndex][i+2]];
|
||||
getVertIndex(vert0,vertMap,indices);
|
||||
getVertIndex(vert1,vertMap,indices);
|
||||
getVertIndex(vert2,vertMap,indices);
|
||||
Triangle newTriangle = new Triangle(
|
||||
vertList[triTable[cubeIndex][i+0]],
|
||||
vertList[triTable[cubeIndex][i+1]],
|
||||
vertList[triTable[cubeIndex][i+2]]
|
||||
);
|
||||
int index0 = getVertIndex(vert0,vertMap,verts);
|
||||
int index1 = getVertIndex(vert1,vertMap,verts);
|
||||
int index2 = getVertIndex(vert2,vertMap,verts);
|
||||
|
||||
//add 0's to normals until it matches vert count
|
||||
while(trianglesSharingVert.size() < verts.size()){
|
||||
trianglesSharingVert.add(0);
|
||||
normals.add(new Vector3f());
|
||||
}
|
||||
|
||||
|
||||
//add new triangle
|
||||
Triangle newTriangle = new Triangle(index0,index1,index2);
|
||||
triangles.add(newTriangle);
|
||||
// triangles[ntriang].points[0] = vertList[triTable[cubeIndex][i+0]];
|
||||
// triangles[ntriang].points[1] = vertList[triTable[cubeIndex][i+1]];
|
||||
// triangles[ntriang].points[2] = vertList[triTable[cubeIndex][i+2]];
|
||||
ntriang++;
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Normals calculation
|
||||
//
|
||||
|
||||
|
||||
//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();
|
||||
|
||||
|
||||
|
||||
//for each vertex, average the new normal with the normals that are already there
|
||||
int trianglesSharingIndex0 = trianglesSharingVert.get(index0);
|
||||
//calculate proportion of each normal
|
||||
float oldProportion = trianglesSharingIndex0 / (float)(trianglesSharingIndex0 + 1);
|
||||
float newProportion = 1.0f / (float)(trianglesSharingIndex0 + 1);
|
||||
//increment number of triangles sharing vert
|
||||
trianglesSharingVert.set(index0, trianglesSharingIndex0 + 1);
|
||||
|
||||
Vector3f currentNormal = normals.get(index0);
|
||||
currentNormal = averageNormals(currentNormal,oldProportion,n,newProportion);
|
||||
normals.get(index0).set(currentNormal);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int trianglesSharingIndex1 = trianglesSharingVert.get(index1);
|
||||
//calculate proportion of each normal
|
||||
oldProportion = trianglesSharingIndex1 / (float)(trianglesSharingIndex1 + 1);
|
||||
newProportion = 1.0f / (float)(trianglesSharingIndex1 + 1);
|
||||
//increment number of triangles sharing vert
|
||||
trianglesSharingVert.set(index1, trianglesSharingIndex1 + 1);
|
||||
|
||||
currentNormal = normals.get(index1);
|
||||
currentNormal = averageNormals(currentNormal,oldProportion,n,newProportion);
|
||||
normals.get(index1).set(currentNormal);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int trianglesSharingIndex2 = trianglesSharingVert.get(index2);
|
||||
//calculate proportion of each normal
|
||||
oldProportion = trianglesSharingIndex2 / (float)(trianglesSharingIndex2 + 1);
|
||||
newProportion = 1.0f / (float)(trianglesSharingIndex2 + 1);
|
||||
//increment number of triangles sharing vert
|
||||
trianglesSharingVert.set(index2, trianglesSharingIndex2 + 1);
|
||||
|
||||
currentNormal = normals.get(index2);
|
||||
currentNormal = averageNormals(currentNormal,oldProportion,n,newProportion);
|
||||
normals.get(index2).set(currentNormal);
|
||||
|
||||
}
|
||||
|
||||
return(ntriang);
|
||||
@ -475,10 +549,21 @@ public class TerrainChunkModelGeneration {
|
||||
// | / | / | / | /
|
||||
// 0 +-------------+ 3 +------3------+
|
||||
|
||||
//the current grid cell
|
||||
GridCell currentCell = new GridCell();
|
||||
//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>();
|
||||
List<Integer> indices = new LinkedList<Integer>();
|
||||
//the list of all verts
|
||||
List<Vector3f> verts = new LinkedList<Vector3f>();
|
||||
//the list of all normals
|
||||
List<Vector3f> normals = new LinkedList<Vector3f>();
|
||||
//the list of number of triangles that share a vert
|
||||
List<Integer> trianglesSharingVert = new LinkedList<Integer>();
|
||||
|
||||
|
||||
|
||||
for(int x = 0; x < terrainGrid.length - 1; x++){
|
||||
for(int y = 0; y < terrainGrid[0].length - 1; y++){
|
||||
for(int z = 0; z < terrainGrid[0][0].length - 1; z++){
|
||||
@ -490,7 +575,7 @@ public class TerrainChunkModelGeneration {
|
||||
terrainGrid[x+0][y+1][z+0], terrainGrid[x+0][y+1][z+1], terrainGrid[x+1][y+1][z+1], terrainGrid[x+1][y+1][z+0]
|
||||
);
|
||||
//polygonize the current gridcell
|
||||
polygonize(currentCell, 0, triangles, vertMap, indices);
|
||||
polygonize(currentCell, 0, triangles, vertMap, verts, normals, trianglesSharingVert);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -504,24 +589,13 @@ public class TerrainChunkModelGeneration {
|
||||
//
|
||||
|
||||
try {
|
||||
mesh.vertexCount = triangles.size() * 3;
|
||||
mesh.vertexCount = verts.size();
|
||||
FloatBuffer VertexArrayBufferData = BufferUtils.createFloatBuffer(mesh.vertexCount * 3);
|
||||
float[] temp = new float[3];
|
||||
for(Triangle triangle: triangles){
|
||||
//vertex 1
|
||||
temp[0] = triangle.points[0].x;
|
||||
temp[1] = triangle.points[0].y;
|
||||
temp[2] = triangle.points[0].z;
|
||||
VertexArrayBufferData.put(temp);
|
||||
//vertex 2
|
||||
temp[0] = triangle.points[1].x;
|
||||
temp[1] = triangle.points[1].y;
|
||||
temp[2] = triangle.points[1].z;
|
||||
VertexArrayBufferData.put(temp);
|
||||
//vertex 3
|
||||
temp[0] = triangle.points[2].x;
|
||||
temp[1] = triangle.points[2].y;
|
||||
temp[2] = triangle.points[2].z;
|
||||
for(Vector3f vert : verts){
|
||||
temp[0] = vert.x;
|
||||
temp[1] = vert.y;
|
||||
temp[2] = vert.z;
|
||||
VertexArrayBufferData.put(temp);
|
||||
}
|
||||
VertexArrayBufferData.flip();
|
||||
@ -539,14 +613,9 @@ public class TerrainChunkModelGeneration {
|
||||
mesh.elementCount = triangles.size() * 3;
|
||||
try {
|
||||
IntBuffer elementArrayBufferData = BufferUtils.createIntBuffer(mesh.elementCount);
|
||||
int i = 0;
|
||||
int[] temp = new int[3];
|
||||
for(Triangle triangle : triangles){
|
||||
temp[0] = i * 3 + 0;
|
||||
temp[1] = i * 3 + 1;
|
||||
temp[2] = i * 3 + 2;
|
||||
i++;
|
||||
elementArrayBufferData.put(temp);
|
||||
elementArrayBufferData.put(triangle.indices);
|
||||
}
|
||||
elementArrayBufferData.flip();
|
||||
mesh.buffer_faces(elementArrayBufferData);
|
||||
@ -561,33 +630,38 @@ public class TerrainChunkModelGeneration {
|
||||
// NORMALS
|
||||
//
|
||||
try {
|
||||
mesh.normalCount = triangles.size() * 3;
|
||||
mesh.normalCount = normals.size();
|
||||
FloatBuffer NormalArrayBufferData;
|
||||
if(mesh.normalCount > 0){
|
||||
NormalArrayBufferData = BufferUtils.createFloatBuffer(mesh.normalCount * 3);
|
||||
float[] temp = new float[3];
|
||||
for(Triangle triangle : triangles){
|
||||
//calculate normal vector
|
||||
Vector3f u = triangle.points[1].sub(triangle.points[0], new Vector3f());
|
||||
Vector3f v = triangle.points[2].sub(triangle.points[1], 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);
|
||||
//emit 3 normal vectors
|
||||
//normal 0
|
||||
temp[0] = n.x;
|
||||
temp[1] = n.y;
|
||||
temp[2] = n.z;
|
||||
NormalArrayBufferData.put(temp);
|
||||
//normal 1
|
||||
temp[0] = n.x;
|
||||
temp[1] = n.y;
|
||||
temp[2] = n.z;
|
||||
NormalArrayBufferData.put(temp);
|
||||
//normal 2
|
||||
temp[0] = n.x;
|
||||
temp[1] = n.y;
|
||||
temp[2] = n.z;
|
||||
for(Vector3f normal : normals){
|
||||
temp[0] = normal.x;
|
||||
temp[1] = normal.y;
|
||||
temp[2] = normal.z;
|
||||
NormalArrayBufferData.put(temp);
|
||||
}
|
||||
// for(Triangle triangle : triangles){
|
||||
// //emit 3 normal vectors
|
||||
// //normal 0
|
||||
// Vector3f normal = normals.get(triangle.indices[0]);
|
||||
// temp[0] = normal.x;
|
||||
// temp[1] = normal.y;
|
||||
// temp[2] = normal.z;
|
||||
// NormalArrayBufferData.put(temp);
|
||||
// //normal 1
|
||||
// normal = normals.get(triangle.indices[1]);
|
||||
// temp[0] = normal.x;
|
||||
// temp[1] = normal.y;
|
||||
// temp[2] = normal.z;
|
||||
// NormalArrayBufferData.put(temp);
|
||||
// //normal 2
|
||||
// normal = normals.get(triangle.indices[2]);
|
||||
// temp[0] = normal.x;
|
||||
// temp[1] = normal.y;
|
||||
// temp[2] = normal.z;
|
||||
// NormalArrayBufferData.put(temp);
|
||||
// }
|
||||
NormalArrayBufferData.flip();
|
||||
mesh.buffer_normals(NormalArrayBufferData, 3);
|
||||
}
|
||||
@ -653,21 +727,28 @@ public class TerrainChunkModelGeneration {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
//TODO: more optimal key creation
|
||||
private static String getVertKeyFromPoints(float x, float y, float z){
|
||||
return x + "-" + y + "-" + z;
|
||||
}
|
||||
|
||||
private static int getVertIndex(Vector3f vert, Map<String,Integer> vertMap, List<Integer> indices){
|
||||
private static int getVertIndex(Vector3f vert, Map<String,Integer> vertMap, List<Vector3f> verts){
|
||||
int rVal = -1;
|
||||
String vertKey = getVertKeyFromPoints(vert.x,vert.y,vert.z);
|
||||
if(vertMap.containsKey(vertKey)){
|
||||
return vertMap.get(vertKey);
|
||||
} else {
|
||||
rVal = indices.size();
|
||||
indices.add(rVal);
|
||||
rVal = verts.size();
|
||||
verts.add(vert);
|
||||
vertMap.put(vertKey,rVal);
|
||||
return rVal;
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user