Mesh erzeugen aus TriangleStripArray und VertexArray

Started by webster, February 27, 2013, 08:24:23 PM

Previous topic - Next topic

webster

Hallo,

beim parsen einer m3g Datei kann ich folgende Daten auslesen:
*********nur ein Beispiel**********
TriangleStripArray (IndexBuffer)
indices: 3, 2, 0, 1, 7, 4, 6, 5
stripLengths: 4, 4

VertexArray(Positions)
(-10,-10,-10)(10,-10,-10)(10,10,-10)(-10,10,-10)(0,-10,-20)(0,-10,20)(0,10,20)(0,10,-20)
**********ende Beispiel**********

ist es möglich mit der jpct api daraus ein Mesh Objekt zu erzeugen.
Von der Java3D api weis ich dass sowas geht. Aber irgendwie hab ich das Gefühl, ein JPCT-Mesh lässt sich auf diese weise nicht erzeugen.
Die Normal-Vectoren sind übrings auch vorhanden, war nur zu faul sie auch noch abzuschrieben ;)

viele Grüsse
Roland

EgonOlsen

Klar lässt sich daraus was erzeugen. Du kannst die Daten nur nicht direkt verwenden. Du müsstest die Datei parsen und entsprechend den Angaben einzelne Dreiecke erstellen. Die kannst du dann mit addTriangle() einem Object3D hinzufügen. Alternativ gibt es auch eine Art Bulk-Konstruktor für ein Object3D, aber da ist es komplizierter, das Format richtig zu bekommen.

Wenn das Format so sehe, dann weiß ich wieder, wieso Importer schreiben so unschön ist...wieso speichern die die Daten als Triangle-Strips ab? Im blödesten Fall haben die dann wohl alle die Länge 1 und außer gesteigerter Komplexität ist nichts mehr gewonnen...naja... ::)

webster

Hi Egon,
einerseits ermunternd - irgendwie sollte es funktionieren.
Andererseits habe ich jetzt keine Ahnung wie ich daraus einzelne Dreiecke gewinnen kann.

Trotzdem vielen Dank für die Info - hab schon schlimmes befürchtet mit meinem 666. Posting in der German Corner ;)

Beste Grüsse

EgonOlsen

Üblicherweise ist ein Trianglestrip eine Abfolge von Dreiecken, bei der sich die Eckpunkte aller Dreiecke außer dem ersten aus zwei Eckpunkten des vorherigen plus einem neuen Eckpunkt ergeben. Also z.B. Dreieck 1 hat die Eckpunkte 1,2,3 und Dreieck 2 die Punkte 2,3,4. Dann wäre der Trianglestrip 1,2,3,4. Kommt dann Dreieck 3 mit den Punkten 3,4,5 hinzu, wäre der Strip 1,2,3,4,5 usw...Wenn diese Aufbauregel nicht mehr einzuhalten ist, muss der Strip enden. Das ist vermutlich in der Datei mit stripLengths gemeint. Ich persönlich finden diesen Aufbau unnötig kompliziert, aber wenn das Format halt so ist...

webster

Hi Egon,

ganau so sollte es eigentlich funktionieren. Leider sehen meine Object3D Ergebnisse nicht wie eine (Nokia)Ameise oder ein Känguru aus, sondern sind irgendwelche löchrigen Gebilde :-\. Naja, ich probier es noch mal mit den skalierungs und translations  bzw. rotations Parametern aus den m3g Dateien.
Auf jeden Fall schon mal vielen Dank für deine Hilfe.

viele Grüße
Roland

webster

Hallo,

ich habe jetzt doch noch ein Problem ähnlich dem http://www.jpct.net/forum2/index.php/topic,1488.msg10577.html#msg10577

Ich habe meinem Object3D also die Dreiecke hinzugefügt und jetzt sollte das ganze noch gezoomt, gedreht und verschoben werden.
Verschieben mach ich mit diesem Code:
private void setTranslate(Object3D obj, Node node) {
float[] trans = new float[3];
node.getTranslation(trans);
obj.translate(trans[0], trans[1], trans[2]);
}


Das sollte eigentlich funktionieren.
Aber mit dem zoomen und rotieren da bin ich mir gar nicht sicher.
Also ich erzeuge mir eine 4X4 Einheitsmatrix und bearbeite sie mit folgenden Code:

private void setOrientationAndScale(Object3D obj, Node node) {
float[] orientation = new float[4];
node.getOrientation(orientation);
float[] scale = new float[3];
node.getScale(scale);
// eine Einheits-Matrix
Matrix m = getMatrix();
// vertausche Zeilen mit Spalten
m.set(0, 3, scale[0]);
m.set(1, 3, scale[1]);
m.set(2, 3, scale[2]);
float orientationAngle = orientation[0];
Logger.log("orientationAngle: " + orientationAngle);
orientationAngle = (float) (orientationAngle * Math.PI / 180);
float orientationAxisX = orientation[1];
Logger.log("orientationAxisX: " + orientationAxisX);
float orientationAxisY = orientation[2];
Logger.log("orientationAxisY: " + orientationAxisY);
float orientationAxisZ = orientation[3];
Logger.log("orientationAxisZ: " + orientationAxisZ);
// ab hier wird es richtig fragwürdig
orientationAxisX = orientationAxisX * m.get(0, 0) * orientationAngle;
m.set(0, 0, orientationAxisX);
orientationAxisY = orientationAxisY * m.get(1, 1) * orientationAngle;
m.set(1, 1, orientationAxisY);
orientationAxisZ = orientationAxisZ * m.get(2, 2) * orientationAngle;
m.set(2, 2, orientationAxisZ);
// kann das funktionieren?
Matrix m2 = obj.getRotationMatrix();
m2.matMul(m);
obj.setRotationMatrix(m2);
}

Noch zum Verständniss das float-array orientation enthält an position 0 einen Winkel in Grad, die anderen 3 float Werte sind wahrscheinlich dafür verantwortlch in wie weit die 3 Achsen von der Rotation betroffen sind und haben immer den Wert 1.0 oder 0.0.
Leider fehlt mir die Mathematik um da durch zu steigen.
Auch bei den letzten drei Codezeilen dürfte ich was nicht verstanden haben.

Da ich in dem oben erwähnten Posting gelesen habe, dass die JPCT-Matrix row major ist habe ich die Werte für die Skalierung in die letzte Spalte geschrieben, bei OpenGL würden diese Werte wohl in der 4. Reihe der Matrix auftauchen.

Und noch eine andere Frage

Object3D plane = Primitives.getPlane(1, 8);
plane.rotateX(PI / 2f);
world.addObject(plane);

Welche XYZ-Koordinaten hätten in diesem Fall eigentlich die Eckpunkte der plane?
Etwa so:
hinten links: 0,0,8
hinten rechts: 8,0,8
vorne links: 0,0,0
vorne rechts: 8,0,0
???

Viele Grüße
Roland

EgonOlsen

Du solltest eine Rotationsmatrix in jPCT auch als solche behandeln, d.h. nur die obere 3x3-Matrix füllen. Andere Bereiche werden wohl Translationen sein, die du besser in einen Translate-Aufruf packst.

Was die Plane angeht...ja, ich glaube, das stimmt so. Zur Not lass dir vom Mesh die Bounding-Box-Koordinaten geben und gibt die aus, dann siehst du es genau.

webster

Hallo Egon,

ich habe nicht kapiert wie man das  row major und column major zu verstehen hat. Aber macht nichts, hab ein bischen rumprobiert und auch mal bei Wikipedia nachgelesen und jetzt funktioniert rotieren und scalieren.:)
Nochmals vielen Dank für die schnelle Hilfe, vor allem wegen der oberen 3x3-Matrix :-[

Viele Grüße
Roland

EgonOlsen

Row Major ist das, was man "hier" in der Schule oder im Studium lernt. Also das, was jeder Mitteleuropäer erwarten würde. Column Major ist das, was OpenGL verwendet und was den angesprochenen Mitteleuropäer extrem verwirrt, wenn er sich entsprechende Berechnungen mit diesen Matrizen anschaut, denn die Reihenfolge der Operation dreht sich um. Natürlich sagt einem üblicherweise niemand, welche Variante verwendet wird und das vergrößert den Spass noch... ;D

Ich habe da mal irgendwo im Forum ausgiebiger mit rumgerechnet, aber ich finde den Thread nicht. Aber hier steht ein klein wenig drin:

http://www.jpct.net/forum2/index.php/topic,1549.msg11148.html#msg11148

Letztendlich meint das alles nur, wie die Vektoren in der Matrix abgelegt sind, spalten- oder zeilenweise.

webster

Hallo Egon,
eigentlich habe ich mir gedacht dass m3g ein nettes Format ist. Es speichert einen kompletten Scenegraphen samt annimierten Objekten und Texturen auf recht kompakte weise. Es ist allerdings  auf OpenGL zugeschnitten. Wenn ich dein Framework benutze, brauche ich keine Flächen-Normalen. Und jetzt weis ich nicht was ich mit Texture-Koordinaten (m3g speichert für jeden Vertex auch eine Texture-Koordinate, 3 byte oder 3 short) in Zusammenhang mit jpct anfangen soll. Eigentlich sollte ich mal für ein paar Prüfungen lernen :(
Immerhin funktioniert das auslesen der Geometrien(mist - hab keine Ahnung wie man hier images einfügt)



Viele Grüße
Roland

EgonOlsen

Die Texturkoordinaten kannst du genauso wie die Dreicksdaten bei addTriangle() übergeben.