Joined normals marching cubes
This commit is contained in:
parent
094831ba22
commit
edaa7c8ce2
@ -34,7 +34,7 @@ public class ClientTerrainManager {
|
|||||||
|
|
||||||
ClientWorldData clientWorldData;
|
ClientWorldData clientWorldData;
|
||||||
|
|
||||||
static List<TerrainChunkGenQueueItem> terrainChunkGenerationQueue = Collections.synchronizedList(new LinkedList<TerrainChunkGenQueueItem>());
|
static List<TerrainChunkGenQueueItem> terrainChunkGenerationQueue = new CopyOnWriteArrayList<TerrainChunkGenQueueItem>();
|
||||||
|
|
||||||
|
|
||||||
public ClientTerrainManager(ClientWorldData clientWorldData){
|
public ClientTerrainManager(ClientWorldData clientWorldData){
|
||||||
|
|||||||
@ -322,12 +322,12 @@ public class TerrainChunkModelGeneration {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static class Triangle {
|
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){
|
public Triangle(int index0, int index1, int index2){
|
||||||
points[0] = point0;
|
indices[0] = index0;
|
||||||
points[1] = point1;
|
indices[1] = index1;
|
||||||
points[2] = point2;
|
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 i;
|
||||||
int ntriang;
|
int ntriang;
|
||||||
int cubeIndex = 0;
|
int cubeIndex = 0;
|
||||||
@ -411,22 +419,88 @@ public class TerrainChunkModelGeneration {
|
|||||||
//Create the triangle
|
//Create the triangle
|
||||||
ntriang = 0;
|
ntriang = 0;
|
||||||
for (i=0; triTable[cubeIndex][i]!=-1; i+=3) {
|
for (i=0; triTable[cubeIndex][i]!=-1; i+=3) {
|
||||||
|
//
|
||||||
|
// Triangles calculation
|
||||||
|
//
|
||||||
|
//get indices
|
||||||
Vector3f vert0 = vertList[triTable[cubeIndex][i+0]];
|
Vector3f vert0 = vertList[triTable[cubeIndex][i+0]];
|
||||||
Vector3f vert1 = vertList[triTable[cubeIndex][i+1]];
|
Vector3f vert1 = vertList[triTable[cubeIndex][i+1]];
|
||||||
Vector3f vert2 = vertList[triTable[cubeIndex][i+2]];
|
Vector3f vert2 = vertList[triTable[cubeIndex][i+2]];
|
||||||
getVertIndex(vert0,vertMap,indices);
|
int index0 = getVertIndex(vert0,vertMap,verts);
|
||||||
getVertIndex(vert1,vertMap,indices);
|
int index1 = getVertIndex(vert1,vertMap,verts);
|
||||||
getVertIndex(vert2,vertMap,indices);
|
int index2 = getVertIndex(vert2,vertMap,verts);
|
||||||
Triangle newTriangle = new Triangle(
|
|
||||||
vertList[triTable[cubeIndex][i+0]],
|
//add 0's to normals until it matches vert count
|
||||||
vertList[triTable[cubeIndex][i+1]],
|
while(trianglesSharingVert.size() < verts.size()){
|
||||||
vertList[triTable[cubeIndex][i+2]]
|
trianglesSharingVert.add(0);
|
||||||
);
|
normals.add(new Vector3f());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//add new triangle
|
||||||
|
Triangle newTriangle = new Triangle(index0,index1,index2);
|
||||||
triangles.add(newTriangle);
|
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++;
|
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);
|
return(ntriang);
|
||||||
@ -475,10 +549,21 @@ public class TerrainChunkModelGeneration {
|
|||||||
// | / | / | / | /
|
// | / | / | / | /
|
||||||
// 0 +-------------+ 3 +------3------+
|
// 0 +-------------+ 3 +------3------+
|
||||||
|
|
||||||
|
//the current grid cell
|
||||||
GridCell currentCell = new GridCell();
|
GridCell currentCell = new GridCell();
|
||||||
|
//the list of all triangles
|
||||||
List<Triangle> triangles = new LinkedList<Triangle>();
|
List<Triangle> triangles = new LinkedList<Triangle>();
|
||||||
|
//the map of vertex to index
|
||||||
Map<String,Integer> vertMap = new HashMap<String,Integer>();
|
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 x = 0; x < terrainGrid.length - 1; x++){
|
||||||
for(int y = 0; y < terrainGrid[0].length - 1; y++){
|
for(int y = 0; y < terrainGrid[0].length - 1; y++){
|
||||||
for(int z = 0; z < terrainGrid[0][0].length - 1; z++){
|
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]
|
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 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 {
|
try {
|
||||||
mesh.vertexCount = triangles.size() * 3;
|
mesh.vertexCount = verts.size();
|
||||||
FloatBuffer VertexArrayBufferData = BufferUtils.createFloatBuffer(mesh.vertexCount * 3);
|
FloatBuffer VertexArrayBufferData = BufferUtils.createFloatBuffer(mesh.vertexCount * 3);
|
||||||
float[] temp = new float[3];
|
float[] temp = new float[3];
|
||||||
for(Triangle triangle: triangles){
|
for(Vector3f vert : verts){
|
||||||
//vertex 1
|
temp[0] = vert.x;
|
||||||
temp[0] = triangle.points[0].x;
|
temp[1] = vert.y;
|
||||||
temp[1] = triangle.points[0].y;
|
temp[2] = vert.z;
|
||||||
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;
|
|
||||||
VertexArrayBufferData.put(temp);
|
VertexArrayBufferData.put(temp);
|
||||||
}
|
}
|
||||||
VertexArrayBufferData.flip();
|
VertexArrayBufferData.flip();
|
||||||
@ -539,14 +613,9 @@ public class TerrainChunkModelGeneration {
|
|||||||
mesh.elementCount = triangles.size() * 3;
|
mesh.elementCount = triangles.size() * 3;
|
||||||
try {
|
try {
|
||||||
IntBuffer elementArrayBufferData = BufferUtils.createIntBuffer(mesh.elementCount);
|
IntBuffer elementArrayBufferData = BufferUtils.createIntBuffer(mesh.elementCount);
|
||||||
int i = 0;
|
|
||||||
int[] temp = new int[3];
|
int[] temp = new int[3];
|
||||||
for(Triangle triangle : triangles){
|
for(Triangle triangle : triangles){
|
||||||
temp[0] = i * 3 + 0;
|
elementArrayBufferData.put(triangle.indices);
|
||||||
temp[1] = i * 3 + 1;
|
|
||||||
temp[2] = i * 3 + 2;
|
|
||||||
i++;
|
|
||||||
elementArrayBufferData.put(temp);
|
|
||||||
}
|
}
|
||||||
elementArrayBufferData.flip();
|
elementArrayBufferData.flip();
|
||||||
mesh.buffer_faces(elementArrayBufferData);
|
mesh.buffer_faces(elementArrayBufferData);
|
||||||
@ -561,33 +630,38 @@ public class TerrainChunkModelGeneration {
|
|||||||
// NORMALS
|
// NORMALS
|
||||||
//
|
//
|
||||||
try {
|
try {
|
||||||
mesh.normalCount = triangles.size() * 3;
|
mesh.normalCount = normals.size();
|
||||||
FloatBuffer NormalArrayBufferData;
|
FloatBuffer NormalArrayBufferData;
|
||||||
if(mesh.normalCount > 0){
|
if(mesh.normalCount > 0){
|
||||||
NormalArrayBufferData = BufferUtils.createFloatBuffer(mesh.normalCount * 3);
|
NormalArrayBufferData = BufferUtils.createFloatBuffer(mesh.normalCount * 3);
|
||||||
float[] temp = new float[3];
|
float[] temp = new float[3];
|
||||||
for(Triangle triangle : triangles){
|
for(Vector3f normal : normals){
|
||||||
//calculate normal vector
|
temp[0] = normal.x;
|
||||||
Vector3f u = triangle.points[1].sub(triangle.points[0], new Vector3f());
|
temp[1] = normal.y;
|
||||||
Vector3f v = triangle.points[2].sub(triangle.points[1], new Vector3f());
|
temp[2] = normal.z;
|
||||||
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;
|
|
||||||
NormalArrayBufferData.put(temp);
|
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();
|
NormalArrayBufferData.flip();
|
||||||
mesh.buffer_normals(NormalArrayBufferData, 3);
|
mesh.buffer_normals(NormalArrayBufferData, 3);
|
||||||
}
|
}
|
||||||
@ -653,21 +727,28 @@ public class TerrainChunkModelGeneration {
|
|||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: more optimal key creation
|
||||||
private static String getVertKeyFromPoints(float x, float y, float z){
|
private static String getVertKeyFromPoints(float x, float y, float z){
|
||||||
return x + "-" + y + "-" + 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;
|
int rVal = -1;
|
||||||
String vertKey = getVertKeyFromPoints(vert.x,vert.y,vert.z);
|
String vertKey = getVertKeyFromPoints(vert.x,vert.y,vert.z);
|
||||||
if(vertMap.containsKey(vertKey)){
|
if(vertMap.containsKey(vertKey)){
|
||||||
return vertMap.get(vertKey);
|
return vertMap.get(vertKey);
|
||||||
} else {
|
} else {
|
||||||
rVal = indices.size();
|
rVal = verts.size();
|
||||||
indices.add(rVal);
|
verts.add(vert);
|
||||||
vertMap.put(vertKey,rVal);
|
vertMap.put(vertKey,rVal);
|
||||||
return 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