Hallo, ich versuche momentan die surface nets Methode dieser Website Smooth Voxel Terrain (Part 2) | 0 FPS zur Generierung von Mesh aus Voxel daten zu implementieren. Leider verstehe ich die Javascript Implementierung des Autors überhaupt nicht, und musste mir daher selbstständig etwas ausdenken um die Methode zu implementieren.
Wie man hier sieht funktioniert sie generell auch recht gut solange ich FaceCulling ausgeschaltet lasse. Sobald ich es nämlich einschalte gibt es dieses Bild:
Alle Polygone sind in positive Achsenrichtungen ausgerichtet, und nicht wie gewünscht “nach außen”. Ich hab mir jetzt schon stundenlang den Kopf zerbrochen wie ich das Problem löse, aber ich komm nicht drauf.
Das ist mein Code:
vertices = new ArrayList<>();
indices = new ArrayList<>();
HashMap<Vector3f, Integer> indexMap = new HashMap<>();
Vector3f[] edgepositions = Util.getInitializedArray(8);
int index = vertices.size();
for(int x = 0; x < world.length-1; x++){
for(int y = 0; y < world[0].length-1; y++){
for(int z = 0; z < world[0][0].length-1; z++){
edgepositions[0].set(x + 0, y + 1, z + 0);
edgepositions[1].set(x + 0, y + 0, z + 0);
edgepositions[2].set(x + 1, y + 0, z + 0);
edgepositions[3].set(x + 1, y + 1, z + 0);
edgepositions[4].set(x + 0, y + 1, z + 1);
edgepositions[5].set(x + 0, y + 0, z + 1);
edgepositions[6].set(x + 1, y + 0, z + 1);
edgepositions[7].set(x + 1, y + 1, z + 1);
boolean v0 = world[(int)edgepositions[0].x][(int)edgepositions[0].y][(int)edgepositions[0].z] > 0;
boolean v1 = world[(int)edgepositions[1].x][(int)edgepositions[1].y][(int)edgepositions[1].z] > 0;
boolean v2 = world[(int)edgepositions[2].x][(int)edgepositions[2].y][(int)edgepositions[2].z] > 0;
boolean v3 = world[(int)edgepositions[3].x][(int)edgepositions[3].y][(int)edgepositions[3].z] > 0;
boolean v4 = world[(int)edgepositions[4].x][(int)edgepositions[4].y][(int)edgepositions[4].z] > 0;
boolean v5 = world[(int)edgepositions[5].x][(int)edgepositions[5].y][(int)edgepositions[5].z] > 0;
boolean v6 = world[(int)edgepositions[6].x][(int)edgepositions[6].y][(int)edgepositions[6].z] > 0;
boolean v7 = world[(int)edgepositions[7].x][(int)edgepositions[7].y][(int)edgepositions[7].z] > 0;
if((v0 && v1 && v2 && v3 && v4 && v5 && v6 && v7) || (!v0 && !v1 && !v2 && !v3 && !v4 && !v5 && !v6 && !v7)) {
continue;
}
indexMap.put(new Vector3f(x, y, z), index);
index++;
vertices.add(new Vertex(new Vector3f(x+0.5f,y+0.5f,z+0.5f), new Vector3f(0, 1, 0)));
}
}
}
for(int x = 0; x < world.length-1; x++){
for(int y = 0; y < world[0].length-1; y++){
for(int z = 0; z < world[0][0].length-1; z++){
if(!indexMap.containsKey(new Vector3f(x,y,z))){
continue;
}
Vector3f pos0 = new Vector3f(x,y,z);
for(int i = 0; i < 3; i++){
for(int j = 0; j < i; j++){
Vector3f pos1 = new Vector3f(pos0).add(dirs**);
Vector3f pos2 = new Vector3f(pos0).add(dirs[j]);
Vector3f pos3 = new Vector3f(pos0).add(dirs**).add(dirs[j]);
if(indexMap.containsKey(pos1) && indexMap.containsKey(pos2) && indexMap.containsKey(pos3)){
if(/** hier muss eine Bedingung hin **/){
indices.add(indexMap.get(pos0));
indices.add(indexMap.get(pos1));
indices.add(indexMap.get(pos2));
indices.add(indexMap.get(pos3));
indices.add(indexMap.get(pos2));
indices.add(indexMap.get(pos1));
}else{
indices.add(indexMap.get(pos1));
indices.add(indexMap.get(pos0));
indices.add(indexMap.get(pos2));
indices.add(indexMap.get(pos3));
indices.add(indexMap.get(pos1));
indices.add(indexMap.get(pos2));
}
}
}
}
}
}
}
Mein bisher bester Ansatz war es eine 2. Hashmap zu erstellen die den wert von v6 speichert, der dann als Bedingung genutzt wird. Das hat bei den meisten Polygonen funktioniert, aber nicht bei allen.
Hat jemand eine Idee was ich als Bedingung verwenden kann? (Ein alternativer Surface Nets Algorithmus ist mir auch recht Hauptsache es funktioniert)