Ausrichten von Polygonen (Surface Nets)

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)

Nach flüchtigem Vergleich der Grafiken hätte ich gesagt, Du brauchst mehr Farben…
Die Farbwechsel scheinen an den richtigen Stellen zu sein, aber Du musst mindestens 4 Flächen-Lagen farblich unterscheiden, damit der 3d-Eindruk entsteht:

bye
TT

[QUOTE=Timothy_Truckle;126973]Nach flüchtigem Vergleich der Grafiken hätte ich gesagt, Du brauchst mehr Farben…
Die Farbwechsel scheinen an den richtigen Stellen zu sein, aber Du musst mindestens 4 Flächen-Lagen farblich unterscheiden, damit der 3d-Eindruk entsteht:

bye
TT[/QUOTE]
Daran liegt es leider nicht. Das erste Bild war nur mit dem polygon mode auf GL_Lines, da man so das mesh besser erkennt. Da ich ohne korrekte indices keine normals berechnen kann funktioniert meine Licht Berechnung nicht. Die relevante info liegt im 2. Bild. Eigentlich sollte nämlich kaum was zu sehen sein, weil ich mich in der Kugel befinde und FaceCull die Innenseiten weg schneiden sollte.

Die Kugel ist btw komplett grün, das blaue ist mein Hintergrund.

[ot]
Hm. Hattest DU den Thread als “solved” markiert? Das letzte klang jetzt, als wäre es noch offen…
[/ot]

[QUOTE=Marco13][ot]
Hm. Hattest DU den Thread als “solved” markiert? Das letzte klang jetzt, als wäre es noch offen…
[/ot][/QUOTE]
Ja, das klingt jetzt wahrscheinlich mega dumm, aber nachdem ich 2 volle Nachmittage und Abende keine Lösung gefunden habe und daher diesen Thread erstellt habe, finde ich an nächsten Morgen in der Schule die Lösung. Ich fühle mich irgendwie echt verflucht. Sobald ich andere mit meinen Problemen belästige finde ich selbst die Lösung.

wäre nett, wenn Du kurz die Lösung andeutest…

bye
TT

[QUOTE=Timothy_Truckle;127086]wäre nett, wenn Du kurz die Lösung andeutest…

bye
TT[/QUOTE]
Mein Ansatz oben war schon richtig. Das Problem war das einerseits das ein paar Eckpunkte vertauscht waren und zu anderen musste ich im Fall, dass das Viereck waagrecht ist, das Ergebnis negieren.
Also if((i+j==2)? !v2 : v2).

andere Schreibweise:
if ((i + j == 2) != v2)