fluid-sim/src/main/java/electrosphere/render/Mesh.java
2023-07-23 12:20:14 -04:00

1013 lines
46 KiB
Java

package electrosphere.render;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.joml.Matrix4f;
import org.joml.Vector3f;
import org.joml.Vector3i;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL33;
import org.lwjgl.opengl.GL44;
import org.lwjgl.opengl.GL45;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.system.MemoryUtil;
import electrosphere.FluidSim;
public class Mesh {
public int vaoPtr;
int vertBufferPtr;
int normBufferPtr;
int faceBufferPtr;
static int shaderProgram;
public int elementCount = 0;
Matrix4f viewMatrix = new Matrix4f();
Matrix4f projectionMatrix = new Matrix4f();
Matrix4f model = new Matrix4f().identity();
FluidSim sim;
Vector3i offset;
public Mesh(FluidSim sim, Vector3i offset){
this.sim = sim;
this.offset = offset;
}
public void meshInitially(){
//create and bind vao
vaoPtr = GL44.glGenVertexArrays();
GL44.glBindVertexArray(vaoPtr);
//generate verts
TerrainChunkData data = generateTerrainChunkData(sim.getData());
//
//Buffer data to GPU
//
vertBufferPtr = GL44.glGenBuffers();
GL44.glBindBuffer(GL44.GL_ARRAY_BUFFER, vertBufferPtr);
try {
int vertexCount = data.vertices.size();
FloatBuffer vertData = MemoryUtil.memAllocFloat(vertexCount);
for(float vertValue : data.vertices){
vertData.put(vertValue);
}
vertData.flip();
GL44.glBufferData(GL44.GL_ARRAY_BUFFER,vertData,GL44.GL_STATIC_DRAW);
GL44.glVertexAttribPointer(0, 3, GL44.GL_FLOAT, false, 0, 0);
GL44.glEnableVertexAttribArray(0);
MemoryUtil.memFree(vertData);
} catch (NullPointerException ex){
ex.printStackTrace();
}
//
// FACES
//
faceBufferPtr = GL44.glGenBuffers();
GL44.glBindBuffer(GL44.GL_ELEMENT_ARRAY_BUFFER, faceBufferPtr);
elementCount = data.elements.size();
try {
IntBuffer elementArrayBufferData = MemoryUtil.memAllocInt(elementCount);
for(int element : data.elements){
elementArrayBufferData.put(element);
}
elementArrayBufferData.flip();
GL44.glBufferData(GL45.GL_ELEMENT_ARRAY_BUFFER,elementArrayBufferData,GL44.GL_STATIC_DRAW);
MemoryUtil.memFree(elementArrayBufferData);
} catch (NullPointerException ex){
ex.printStackTrace();
}
//
// NORMALS
//
normBufferPtr = GL44.glGenBuffers();
GL44.glBindBuffer(GL44.GL_ARRAY_BUFFER, normBufferPtr);
try {
int normalCount = data.normals.size() / 3;
FloatBuffer NormalArrayBufferData;
if(normalCount > 0){
NormalArrayBufferData = MemoryUtil.memAllocFloat(normalCount * 3);
float[] temp = new float[3];
for(float normalValue : data.normals){
NormalArrayBufferData.put(normalValue);
}
NormalArrayBufferData.flip();
GL44.glBufferData(GL44.GL_ARRAY_BUFFER,NormalArrayBufferData,GL44.GL_STATIC_DRAW);
GL44.glVertexAttribPointer(1, 3, GL44.GL_FLOAT, false, 0, 0);
GL44.glEnableVertexAttribArray(1);
MemoryUtil.memFree(NormalArrayBufferData);
}
} catch (NullPointerException ex){
ex.printStackTrace();
}
viewMatrix = new Matrix4f();
viewMatrix.setLookAt(new Vector3f(0,20,16), new Vector3f(8,8,16), new Vector3f(0,1,0));
projectionMatrix = new Matrix4f();
projectionMatrix.setPerspective(90,1920.0f/1080.0f,0.0001f,1000f);
model = new Matrix4f().identity().translate(offset.x, offset.y, offset.z);
GL45.glUniformMatrix4fv(GL45.glGetUniformLocation(shaderProgram, "view"), false, viewMatrix.get(new float[16]));
GL45.glUniformMatrix4fv(GL45.glGetUniformLocation(shaderProgram, "projection"), false, projectionMatrix.get(new float[16]));
GL45.glUniformMatrix4fv(GL45.glGetUniformLocation(shaderProgram, "model"), false, model.get(new float[16]));
}
public void remesh(){
//generate verts
TerrainChunkData data = generateTerrainChunkData(sim.getData());
GL44.glBindVertexArray(vaoPtr);
// for(int i = 0; i < data.normals.size(); i+=3){
// // if(i > 100 && data.normals.get(i+1) < 0.7){
// data.normals.set(i+1, 1f);
// data.normals.set(i+2, 0f);
// System.out.printf("%.2f %.2f %.2f,\n",data.normals.get(i+0),data.normals.get(i+1),data.normals.get(i+2));
// // }
// }
//
//Buffer data to GPU
//
GL44.glBindBuffer(GL44.GL_ARRAY_BUFFER, vertBufferPtr);
try {
int vertexCount = data.vertices.size();
FloatBuffer vertData = MemoryUtil.memAllocFloat(vertexCount);
for(float vertValue : data.vertices){
vertData.put(vertValue);
}
vertData.flip();
GL44.glBufferData(GL44.GL_ARRAY_BUFFER,vertData,GL44.GL_STATIC_DRAW);
GL44.glVertexAttribPointer(0, 3, GL44.GL_FLOAT, false, 0, 0);
GL44.glEnableVertexAttribArray(0);
MemoryUtil.memFree(vertData);
} catch (NullPointerException ex){
ex.printStackTrace();
}
//
// FACES
//
GL44.glBindBuffer(GL44.GL_ELEMENT_ARRAY_BUFFER, faceBufferPtr);
elementCount = data.elements.size();
try {
IntBuffer elementArrayBufferData = MemoryUtil.memAllocInt(elementCount);
for(int element : data.elements){
elementArrayBufferData.put(element);
}
elementArrayBufferData.flip();
GL44.glBufferData(GL45.GL_ELEMENT_ARRAY_BUFFER,elementArrayBufferData,GL44.GL_STATIC_DRAW);
MemoryUtil.memFree(elementArrayBufferData);
} catch (NullPointerException ex){
ex.printStackTrace();
}
//
// NORMALS
//
GL44.glBindBuffer(GL44.GL_ARRAY_BUFFER, normBufferPtr);
try {
int normalCount = data.normals.size() / 3;
FloatBuffer NormalArrayBufferData;
if(normalCount > 0){
NormalArrayBufferData = MemoryUtil.memAllocFloat(normalCount * 3);
for(float normalValue : data.normals){
NormalArrayBufferData.put(normalValue);
}
NormalArrayBufferData.flip();
GL44.glBufferData(GL44.GL_ARRAY_BUFFER,NormalArrayBufferData,GL44.GL_STATIC_DRAW);
GL44.glVertexAttribPointer(1, 3, GL44.GL_FLOAT, false, 0, 0);
GL44.glEnableVertexAttribArray(1);
MemoryUtil.memFree(NormalArrayBufferData);
}
} catch (NullPointerException ex){
ex.printStackTrace();
}
}
static float angle = 0;
public void draw(){
GL45.glUseProgram(shaderProgram);
// GL45.glBindFramebuffer(GL45.GL_FRAMEBUFFER, 0);
GL44.glBindVertexArray(vaoPtr);
// angle = angle + 0.01f;
// viewMatrix.identity().setLookAt(
// new Vector3f(
// 10 * (float)Math.cos(angle),
// 10,
// 10 * (float)Math.sin(angle)),
// new Vector3f(8,8,8),
// new Vector3f(0,1,0));
GL45.glUniformMatrix4fv(GL45.glGetUniformLocation(shaderProgram, "view"), false, viewMatrix.get(new float[16]));
GL45.glUniformMatrix4fv(GL45.glGetUniformLocation(shaderProgram, "projection"), false, projectionMatrix.get(new float[16]));
GL45.glUniformMatrix4fv(GL45.glGetUniformLocation(shaderProgram, "model"), false, model.get(new float[16]));
GL44.glDrawElements(GL44.GL_TRIANGLES, elementCount, GL44.GL_UNSIGNED_INT, 0);
}
public static void initShaderProgram(){
String vsSrc = "";
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
try (BufferedReader is = new BufferedReader(new InputStreamReader(classloader.getResourceAsStream("shader.vs")))){
String temp;
while((temp = is.readLine())!=null){
vsSrc = vsSrc + temp + "\n";
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String fsSrc = "";
try (BufferedReader is = new BufferedReader(new InputStreamReader(classloader.getResourceAsStream("shader.fs")))){
String temp;
while((temp = is.readLine())!=null){
fsSrc = fsSrc + temp + "\n";
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//
//Create shader
//
int vertexShader = GL45.glCreateShader(GL45.GL_VERTEX_SHADER);
GL45.glShaderSource(vertexShader, vsSrc);
//Compiles the source for the vertex shader object
GL45.glCompileShader(vertexShader);
//The following tests if the vertex shader compiles successfully
int success;
success = GL45.glGetShaderi(vertexShader, GL45.GL_COMPILE_STATUS);
if (success != GL45.GL_TRUE) {
System.err.println("Vertex Shader failed to compile!");
System.err.println("Source is: ");
System.err.println(GL45.glGetShaderSource(vertexShader));
System.err.println(GL45.glGetShaderInfoLog(vertexShader));
}
//Creates and opengl object for a fragment shader and assigns its 'pointer' to the integer fragmentShader
int fragmentShader = GL45.glCreateShader(GL45.GL_FRAGMENT_SHADER);
//This points the opengl shadder object to its proper source
GL45.glShaderSource(fragmentShader, fsSrc);
//This compiles the shader object
GL45.glCompileShader(fragmentShader);
//This tests for the success of the compile attempt
success = GL45.glGetShaderi(fragmentShader, GL45.GL_COMPILE_STATUS);
if (success != GL45.GL_TRUE) {
System.err.println("Fragment Shader failed to compile!");
System.err.println("Source is: ");
System.err.println(GL45.glGetShaderSource(fragmentShader));
System.err.println(GL45.glGetShaderInfoLog(fragmentShader));
}
//This creates a shader program opengl object and assigns its 'pointer' to the integer shaderProgram
shaderProgram = GL45.glCreateProgram();
//This attaches the vertex and fragment shaders to the program
GL45.glAttachShader(shaderProgram, vertexShader);
GL45.glAttachShader(shaderProgram, fragmentShader);
//This links the program to the GPU (I think its to the GPU anyway)
GL45.glLinkProgram(shaderProgram);
//Tests for the success of the shader program creation
success = GL45.glGetProgrami(shaderProgram, GL45.GL_LINK_STATUS);
if (success != GL45.GL_TRUE) {
throw new RuntimeException(GL45.glGetProgramInfoLog(shaderProgram));
}
//Deletes the individual shader objects to free up memory
GL45.glDeleteShader(vertexShader);
GL45.glDeleteShader(fragmentShader);
//bind shader
GL45.glUseProgram(shaderProgram);
}
//http://paulbourke.net/geometry/polygonise/
static int edgeTable[]={
0x0 , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,
0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,
0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c,
0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac,
0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c,
0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc,
0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c,
0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc ,
0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc,
0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c,
0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc,
0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c,
0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460,
0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac,
0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0,
0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c,
0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230,
0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c,
0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190,
0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c,
0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0
};
//256 by 16
static int triTable[][] = {
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1},
{3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1},
{3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1},
{3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1},
{9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1},
{1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1},
{9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
{2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1},
{8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1},
{9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
{4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1},
{3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1},
{1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1},
{4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1},
{4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1},
{9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1},
{1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
{5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1},
{2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1},
{9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
{0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
{2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1},
{10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1},
{4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1},
{5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1},
{5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1},
{9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1},
{0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1},
{10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1},
{8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1},
{2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1},
{7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1},
{9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1},
{2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1},
{11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1},
{9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1},
{5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1},
{11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1},
{11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
{1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1},
{9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1},
{5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1},
{2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
{0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
{5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1},
{6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1},
{0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1},
{3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1},
{6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1},
{5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1},
{1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
{10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1},
{6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1},
{1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1},
{8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1},
{7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1},
{3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
{5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1},
{0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1},
{9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1},
{8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1},
{5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1},
{0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1},
{6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1},
{10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1},
{10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1},
{8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1},
{1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1},
{3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1},
{0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1},
{10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1},
{0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1},
{3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1},
{6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1},
{9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1},
{8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1},
{3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1},
{6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1},
{0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1},
{10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1},
{10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1},
{1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1},
{2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1},
{7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1},
{7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1},
{2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1},
{1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1},
{11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1},
{8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1},
{0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1},
{7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
{10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
{2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
{6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1},
{7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1},
{2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1},
{1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1},
{10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1},
{10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1},
{0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1},
{7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1},
{6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1},
{8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1},
{9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1},
{6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1},
{1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1},
{4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1},
{10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1},
{8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1},
{0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1},
{1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1},
{8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1},
{10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1},
{4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1},
{10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
{5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
{11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1},
{9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
{6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1},
{7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1},
{3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1},
{7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1},
{9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1},
{3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1},
{6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1},
{9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1},
{1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1},
{4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1},
{7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1},
{6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1},
{3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1},
{0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1},
{6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1},
{1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1},
{0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1},
{11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1},
{6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1},
{5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1},
{9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1},
{1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1},
{10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1},
{0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1},
{5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1},
{10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1},
{11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1},
{0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1},
{9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1},
{7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1},
{2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1},
{8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1},
{9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1},
{9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1},
{1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1},
{9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1},
{9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1},
{5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1},
{0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1},
{10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1},
{2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1},
{0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1},
{0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1},
{9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1},
{5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1},
{3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1},
{5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1},
{8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1},
{0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1},
{9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1},
{0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1},
{1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1},
{3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1},
{4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1},
{9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1},
{11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1},
{11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1},
{2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1},
{9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1},
{3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1},
{1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1},
{4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1},
{4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1},
{0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1},
{3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1},
{3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1},
{0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1},
{9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1},
{1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}
};
private static final byte[] BLOCK_PICK_BITS_BY_VERT_INDEX = new byte[]{
(byte)0x67,
(byte)0x26,
(byte)0x23,
(byte)0x37,
(byte)0x45,
(byte)0x04,
(byte)0x01,
(byte)0x15,
(byte)0x57,
(byte)0x46,
(byte)0x02,
(byte)0x13
};
//allows reverse lookup where vertList index returns the points that vert is concerned with
static final int[][] vertIndexInverseTable = new int[][]{
{0,1},
{1,2},
{2,3},
{3,0},
{4,5},
{5,6},
{6,7},
{7,4},
{0,4},
{1,5},
{2,6},
{3,7},
};
//Lookup for the direction vectors for every vertex pair
static final Vector3f[] indexVectorLookupTable = new Vector3f[]{
new Vector3f(0,0,1),
new Vector3f(1,0,0),
new Vector3f(0,0,-1),
new Vector3f(-1,0,0),
new Vector3f(0,0,1),
new Vector3f(1,0,0),
new Vector3f(0,0,-1),
new Vector3f(-1,0,0),
new Vector3f(0,1,0),
new Vector3f(0,1,0),
new Vector3f(0,1,0),
new Vector3f(0,1,0),
};
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;
Vector3f[] vertList = new Vector3f[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;
//Cube is entirely in/out of the surface
if (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 ((edgeTable[cubeIndex] & 1) > 0)
vertList[0] =
VertexInterp(isolevel,grid.points[0],grid.points[1],grid.val[0],grid.val[1]);
if ((edgeTable[cubeIndex] & 2) > 0)
vertList[1] =
VertexInterp(isolevel,grid.points[1],grid.points[2],grid.val[1],grid.val[2]);
if ((edgeTable[cubeIndex] & 4) > 0)
vertList[2] =
VertexInterp(isolevel,grid.points[2],grid.points[3],grid.val[2],grid.val[3]);
if ((edgeTable[cubeIndex] & 8) > 0)
vertList[3] =
VertexInterp(isolevel,grid.points[3],grid.points[0],grid.val[3],grid.val[0]);
if ((edgeTable[cubeIndex] & 16) > 0)
vertList[4] =
VertexInterp(isolevel,grid.points[4],grid.points[5],grid.val[4],grid.val[5]);
if ((edgeTable[cubeIndex] & 32) > 0)
vertList[5] =
VertexInterp(isolevel,grid.points[5],grid.points[6],grid.val[5],grid.val[6]);
if ((edgeTable[cubeIndex] & 64) > 0)
vertList[6] =
VertexInterp(isolevel,grid.points[6],grid.points[7],grid.val[6],grid.val[7]);
if ((edgeTable[cubeIndex] & 128) > 0)
vertList[7] =
VertexInterp(isolevel,grid.points[7],grid.points[4],grid.val[7],grid.val[4]);
if ((edgeTable[cubeIndex] & 256) > 0)
vertList[8] =
VertexInterp(isolevel,grid.points[0],grid.points[4],grid.val[0],grid.val[4]);
if ((edgeTable[cubeIndex] & 512) > 0)
vertList[9] =
VertexInterp(isolevel,grid.points[1],grid.points[5],grid.val[1],grid.val[5]);
if ((edgeTable[cubeIndex] & 1024) > 0)
vertList[10] =
VertexInterp(isolevel,grid.points[2],grid.points[6],grid.val[2],grid.val[6]);
if ((edgeTable[cubeIndex] & 2048) > 0)
vertList[11] =
VertexInterp(isolevel,grid.points[3],grid.points[7],grid.val[3],grid.val[7]);
//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]];
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);
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();
// Vector3f alignmentVector = new Vector3f();
// for(int j = 0; j < 3; j++){
// int[] points = vertIndexInverseTable[triTable[cubeIndex][i+j]];
// float factor = 1.0f / Math.abs(points[1] - points[0]);
// //if point two is greater than point one, flip vector
// if(points[0] < points[1]){
// alignmentVector.add(
// -indexVectorLookupTable[triTable[cubeIndex][i+j]].x * factor,
// -indexVectorLookupTable[triTable[cubeIndex][i+j]].y * factor,
// -indexVectorLookupTable[triTable[cubeIndex][i+j]].z * factor
// );
// } else {
// alignmentVector.add(
// indexVectorLookupTable[triTable[cubeIndex][i+j]].z * factor,
// indexVectorLookupTable[triTable[cubeIndex][i+j]].y * factor,
// indexVectorLookupTable[triTable[cubeIndex][i+j]].z * factor
// );
// }
// }
// n.x = 0;
// n.y = 1;
// // n.z = 0;
// n.normalize();
// // n.set(alignmentVector.normalize().mul(-1));
// // if(n.dot(alignmentVector.normalize()) >= 0){
// // n.add(alignmentVector.normalize()).div(2.0f);
// // }
float oldProportion;
float newProportion;
Vector3f currentNormal;
//for each vertex, average the new normal with the normals that are already there
int trianglesSharingIndex0 = trianglesSharingVert.get(index0);
if(trianglesSharingIndex0 > 0){
//calculate proportion of each normal
oldProportion = trianglesSharingIndex0 / (float)(trianglesSharingIndex0 + 1);
newProportion = 1.0f / (float)(trianglesSharingIndex0 + 1);
//increment number of triangles sharing vert
trianglesSharingVert.set(index0, trianglesSharingIndex0 + 1);
currentNormal = normals.get(index0);
currentNormal = averageNormals(currentNormal,oldProportion,n,newProportion);
normals.get(index0).set(currentNormal);
} else {
trianglesSharingVert.set(index0, trianglesSharingIndex0 + 1);
normals.get(index0).set(n);
}
int trianglesSharingIndex1 = trianglesSharingVert.get(index1);
if(trianglesSharingIndex1 > 0){
//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);
} else {
trianglesSharingVert.set(index1, trianglesSharingIndex1 + 1);
normals.get(index1).set(n);
}
int trianglesSharingIndex2 = trianglesSharingVert.get(index2);
if(trianglesSharingIndex2 > 0){
//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);
} else {
trianglesSharingVert.set(index2, trianglesSharingIndex2 + 1);
normals.get(index2).set(n);
}
}
return(ntriang);
}
//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){
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);
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));
return new Vector3f(x,y,z);
}
public static TerrainChunkData generateTerrainChunkData(float[] data){
// 5 6
// +-------------+ +-----5-------+ ^ Y
// / | / | / | /| | _
// / | / | 4 9 6 10 | /\ Z
// 4 +-----+-------+ 7 | +-----+7------+ | | /
// | 1 +-------+-----+ 2 | +-----1-+-----+ | /
// | / | / 8 0 11 2 | /
// | / | / | / | / |/
// 0 +-------------+ 3 +------3------+ +---------------> X
//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>();
//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>();
//List of elements in order
List<Integer> faceElements = new LinkedList<Integer>();
for(int x = 1; x < FluidSim.DIM - 1; x++){
for(int y = 1; y < FluidSim.DIM - 1; y++){
for(int z = 1; z < FluidSim.DIM - 1; z++){
//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),
data[FluidSim.IX(x+0,y+0,z+0)], data[FluidSim.IX(x+0,y+0,z+1)], data[FluidSim.IX(x+1,y+0,z+1)], data[FluidSim.IX(x+1,y+0,z+0)],
data[FluidSim.IX(x+0,y+1,z+0)], data[FluidSim.IX(x+0,y+1,z+1)], data[FluidSim.IX(x+1,y+1,z+1)], data[FluidSim.IX(x+1,y+1,z+0)]
);
//polygonize the current gridcell
polygonize(currentCell, 0.01, triangles, vertMap, verts, normals, trianglesSharingVert);
}
}
}
//all verts in order, flattened as an array of floats instead of vecs
List<Float> vertsFlat = new LinkedList<Float>();
//all normals in order, flattened as an array of floats instead of vecs
List<Float> normalsFlat = new LinkedList<Float>();
//all elements of faces in order
List<Integer> elementsFlat = new LinkedList<Integer>();
//flatten verts + normals
for(Vector3f vert : verts){
vertsFlat.add(vert.x);
vertsFlat.add(vert.y);
vertsFlat.add(vert.z);
}
for(Vector3f normal : normals){
normalsFlat.add(normal.x);
normalsFlat.add(normal.y);
normalsFlat.add(normal.z);
}
for(Triangle triangle : triangles){
elementsFlat.add(triangle.indices[0]);
elementsFlat.add(triangle.indices[1]);
elementsFlat.add(triangle.indices[2]);
}
//List<Float> vertices, List<Float> normals, List<Integer> faceElements, List<Float> uvs
TerrainChunkData rVal = new TerrainChunkData(vertsFlat, normalsFlat, elementsFlat);
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<Vector3f> verts){
int rVal = -1;
String vertKey = getVertKeyFromPoints(vert.x,vert.y,vert.z);
if(vertMap.containsKey(vertKey)){
return vertMap.get(vertKey);
} else {
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)).normalize();
if(Float.isNaN(rVal.x)){
rVal.x = 0;
}
if(Float.isNaN(rVal.y)){
rVal.y = 0;
}
if(Float.isNaN(rVal.z)){
rVal.z = 0;
}
return rVal;
}
static TerrainChunkData data = generateTerrainChunkData(new float[FluidSim.DIM * FluidSim.DIM * FluidSim.DIM]);
}