ich schreibe gerade einen Collada Parser in C# .NET 3.5.
Mittels XPath und XmlDocument ist das nicht wirklich schwierig, aber allerdings hänge ich gerade, bzw. versteh die Struktur an einer Stelle nicht.
Den allgemeinen Aufbau von Collada versteh ich, also was url, source, id, name etc ist und wie man auf die jeweiligen Subelemente kommt.
Ich bin nun an der Stelle wo ich die "mesh" nodes auslese. Wenn ich direkt die vertices auslesen würde, ohne berücksichtigung der "polygons" funktioniert das, ich komm an meine Daten wunderbar dran.
Aber das ist ja nicht richtig, man muss die "polygons" node rausfinden, danach die "input" nodes durchlaufen und die Daten mit dem "semantic" attribute abgleichen.
Das ist auch alles klar, aber eine sache raffe ich nicht. Wozu gibt es einen "offset" in der "input" node ? Wofür steht der.
Das ist aktuell das einzige wo ich nicht verstehe und auch aus der Spec nicht herausfinden kann.
Bitte hier diejenigen um hilfe die sich ein wenig mit dem COLLADA XML Format schon auseinandergesetzt haben.
Registriert: Sa Aug 18, 2007 18:47 Beiträge: 694 Wohnort: Köln
Programmiersprache: Java
Ich weiß es nicht aber ich vermute mal, dass es vielleicht was mit dem VBO Format zu tun. Bzw dem Stride. Offset = 1 könnte da heissen: Ich bin das 2. Triple.
Warum man sowas ins Dateiformat packen sollte bleibt mir allerdings verschlossen.
_________________ Es werde Licht. glEnable(GL_LIGHTING); Und es ward Licht.
Zitat aus einem Java Buch: "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off"
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Hallo FinalSpace, Ich hab mir sogar mal das Buch zu Collada gekauft. Dort habe ich jetzt nachgelesen über das "Input"-Element, Attribut "Offset":
COLLADA - "Remi Arnaud et al. hat geschrieben:
The offset attribute indicates which indexes, contained in the <p> element, are to be used to index into the referenced source element. Multiple inputs can share the same index, and this is indicated by shared offset values between them. The offset attribute is therefore mandatory."
Wenn Du das nicht verstanden hast, macht es nichts. Ich hab's auch nicht verstanden. Aber ich meine, dass das, was Du da vor Dir hast, ein Index ist. Und zwar werden hier die Indizes von Vertex und Normal aufgelistet. Zuerst komme ein Vertex(der hat Offset "0"), dann kommt eine Normale (die hat Offset 1). Es sollte sich um ein Quad handeln.
Also so: die erste Teile lautet <p>0 4 2 4 3 4 1 4</p>
1. Punkt Nr.0 2. Normale Nr.4 3. Punkt Nr.2 4. Normale Nr.4 5. Punkt Nr.3 6. Normale Nr.4 7. Punkt Nr.1 8. Normale Nr.4
Vor allem woher weisse ich denn ob ich Vertex oder Polygon Normalen habe ?
Weil ich habe gerade die "VERTEX" source daten ausgelesen. Das klappt auch alles mit berücksichtigung von Strides und Offset.
Nun habe ich danach die "NORMAL" source daten ausgelesen, das klappt ebenfalls.
In dem Cube beispiel, oder auch in anderen DAE dateien ich ausprobiert habe, musste ich feststellen das VERTEX und NORMAL von der anzahl her nie identisch sind.
Ich will ja diese Daten in mein Mesh format packen. Bisher baue ich ein Mesh aus folgenden Komponenten zusammen:
Code:
Vertex[] Position (Vector3) Normal (Vector3) Texcoord (Vector2) NumVertices (Anzahl an Vertices)
Indices[] (Array of indices, Jeder index zeigt auf ein vertex) NumIndices
Triangles[] Normal (Triangle normal) Distance (Plane distance) NumTriangles (Anzahl an Triangles, sollte immer identisch mit Anzahl faces sein)
Faces[] StartIndex (Index start, kein Offset!) EndIndex (Index ende, keine länge!) Material (Material name) NumFaces (Anzahl an Faces)
Die anzahl an Positions/Normals und Texcoords müssen immer gleich sein laut diesem aufbau.
Jetzt stellt sich für mich die Frage, macht das sinn ein Mesh so zu definieren ?
Wie bekomm ich die Geometriedaten von Collada in dieses Format ?
Aber mal eine Frage zu den tags: Was hat es denn mit dem # in einem source-Attribut auf sich? Ist das wie bei HTML ein lokaler Verweis?
Im grunde ja, sobald du eine raute z.b. bei "source" oder "url" hast, dann weisst du, dieses zeigt auf ein anderes element und du musst dann auch dieses zu suchende element am einfachsten mit XPath selektieren, aber ohne Raute
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Finalspace hat geschrieben:
In dem Cube beispiel, oder auch in anderen DAE dateien ich ausprobiert habe, musste ich feststellen das VERTEX und NORMAL von der anzahl her nie identisch sind.
Nein, denn die Anzahl der Punkte in einem Würfel sind acht und die Anzahl der Normalen sind sechs, wenn man jedes Element nur einmal angibt.
In einem smoothen Mesh sollte tendenziell die Anzahl der Punkte gleich der Anzahl der Normalen sein. Bei einem Objekt mit harten Kanten ist das möglichweise anders.
Collada gibt offenbar alle Vertices und alle Normalen so an, dass keine Duplikate vorkommen. Dass die Collada-Polygone gemischt Vertex und Normale enthalten erinnert mich eher an das OBJ-Format, da war das so. Im VBO ist das ein wenig anders: da sind alle Vertexattribute von der Anzahl her gleich und der Index ist immer ein reiner Vertexindex.
Wenn Du möchtest, dass die Anzahl der Vertices und der Normalen gleich sind, musst Du das eben umrechnen, indem Du die z.B. die Polygone als Input nimmst und alle Pärchen VertexIndex/NormalenIndex nach VertexIndex sortierst und zum Schluß alle VertexIndex-Doubletten löschst. Dann bleibt eine Liste von Pärchen VertexIndex/NormalIndex übrig, wo jeder Vertex nur einmal vorkommt und jedem Vertex eine Normale zugeordnet ist.
Finalspace hat geschrieben:
Jetzt stellt sich für mich die Frage, macht das sinn ein Mesh so zu definieren ?
Das kann man so nicht beanworten, das kommt immer drauf an, was man so im allgemeinen laden will.
Grundsätzlich könntest Du mit der Definition von Vertex und Vertex-Indices schon bereits zeichnen.
Was ich nicht verstehe, warum Du sowohl Dreieck als auch Face definierst. Hat ein Face keine Normale? Plain-Distance sagt mir nichts.
Wäre es nicht vielleicht besser, das Face nur einmal zu definieren und dort alle Dinge unterzubringen, die man bei einem Face braucht? Man könnte dann die Faces mittels Enum unterscheiden:
TFaceType = (ftUnknown, ftTriangle, ftQuad,....
und könnte alles in einer Definition unterbringen.
In dem Cube beispiel, oder auch in anderen DAE dateien ich ausprobiert habe, musste ich feststellen das VERTEX und NORMAL von der anzahl her nie identisch sind.
Nein, denn die Anzahl der Punkte in einem Würfel sind acht und die Anzahl der Normalen sind sechs, wenn man jedes Element nur einmal angibt.
In einem smoothen Mesh sollte tendenziell die Anzahl der Punkte gleich der Anzahl der Normalen sein. Bei einem Objekt mit harten Kanten ist das möglichweise anders.
Collada gibt offenbar alle Vertices und alle Normalen so an, dass keine Duplikate vorkommen. Dass die Collada-Polygone gemischt Vertex und Normale enthalten erinnert mich eher an das OBJ-Format, da war das so. Im VBO ist das ein wenig anders: da sind alle Vertexattribute von der Anzahl her gleich und der Index ist immer ein reiner Vertexindex.
Ja du hast recht, ich sehs grad an dem Cube beispiel. Da haben wir 48 indices, 8 pro Polygon, 6 polygone in der anzahl.
Vertex hat ja den Offset 0 und Normal den Offset 1.
Jetzt würde ich nur gerne verstehen, wie ich nun die Polygon Indices für Vertex und Normalen herausfinden kann. Ich habe ja aus dem Cube Beispiel folgende Indices für Vertices und Normalen:
Was wären dann davon meine Vertice Indices und welche Normal indices ? Sollten ja beide 24 sein, da man ja keine Indices komprimiert.
Weil Offset von 0 bedeutet für mich, ich lese die Vertices so:
04243414 ... usw.
Das wäre aber doch falsch, weil dann hätte ich für meine Vertices 48 Indices, das kann ja nicht stimmen, ich brauche nur 24 für einen Würfel.
Da raucht irgendwie der kopf -.-
Traude hat geschrieben:
Was ich nicht verstehe, warum Du sowohl Dreieck als auch Face definierst. Hat ein Face keine Normale? Plain-Distance sagt mir nichts.
Wäre es nicht vielleicht besser, das Face nur einmal zu definieren und dort alle Dinge unterzubringen, die man bei einem Face braucht? Man könnte dann die Faces mittels Enum unterscheiden:
TFaceType = (ftUnknown, ftTriangle, ftQuad,....
und könnte alles in einer Definition unterbringen.
Ja das könnte man zusammenwerfen.
Die Plain Distance, ist die Distanz vom Ursprung. Um eine Plane zu definieren benötigt man ja eine Normale und einen Distanz wert.
Wobei der Facetype eigentlich immer Triangle sein sollte, weil es eigentlich keinen Sinn macht, hier Polygone oder Quads oder andere zu unterstützten. 3D API´s rechnen eh immer in Dreiecke, dann ist es eigentlich besser das selber von anfang auch in Dreiecke zu speichern !?
Das hat natürlich den Nachteil, das man Polygone erst wieder in Dreiecke umbasteln muss. Wie jetzt auch grad in meinem Collada Beispiel.
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Finalspace hat geschrieben:
Weil Offset von 0 bedeutet für mich, ich lese die Vertices so:
0 4 2 4 3 4 1 4 ... usw.
Das wäre aber doch falsch, weil dann hätte ich für meine Vertices 48 Indices, das kann ja nicht stimmen, ich brauche nur 24 für einen Würfel.
Da raucht irgendwie der kopf -.-
Öhm, hab ich doch oben schon geschrieben. Das <p>0 4 2 4 3 4 1 4</p>, also die erste Zeile von den Indices ist EIN Polygon. In dem Polygon sind 8 (ACHT!) Indizes drin. Würfel haben normalerweise keine Faces mit acht Vertices.
Logischerweise ist das, was zwischen <p> und </p> steht, also ein Face mit 4 Vertices und 4 Normalen.
Dass in den Polygonen zwei verschiedene Indices dristecken, siehst Du an den beiden Zeilen
Weil der Vertex das Offset 0 hat, kommt der VertexIndex zuerst und der NormalenIndex kommt gleich danach. Genau wie ich es oben geschrieben habe:
<p>0 4 2 4 3 4 1 4</p> bedeutet:
1. Punkt Nr.0 *********************2. Normale Nr.4 3. Punkt Nr.2 *********************4. Normale Nr.4 5. Punkt Nr.3 *********************6. Normale Nr.4 7. Punkt Nr.1 *********************8. Normale Nr.4
Das ist ein Quad mit den Vertices Nr.0,2,3,1 und für alle vier Vertices gilt die Normale Nr.4.
Finalspace hat geschrieben:
3D API´s rechnen eh immer in Dreiecke, dann ist es eigentlich besser das selber von anfang auch in Dreiecke zu speichern !?
Ja, ich denke schon. Wenn Du ein eigenes Meshformat hast, dient Collada ja nur dazu, die Daten zu importieren. Da macht es ja nichts, wenn die Umrechnung in Dreiecke nicht megaschnell ist. Dafür ist das Laden der Daten aus dem eigenen Meshformat schnell.
AH ok, jetzt hab ichs kapiert, es ist nicht nur ein Offset sondern gleichzeitig ein Stride und Offset zugleich. Gut dann habs ich gerafft, dann setzte ich das mal um.
Also wenn beide den gleichen Offset hätten, in der Theorie laut Spec ist das möglich. Dann wären es tatsächlich 48 indices für beide richtig ?
// Find highest offset int highestOffset = -1; List<int> offsets = new List<int>(); foreach (XmlNode thisInputNode in polygonsNode.ChildNodes) { if (thisInputNode.NodeType == XmlNodeType.Element && String.Compare(thisInputNode.Name, "input") == 0) { int offset = XMLHelper.GetAttributeValueInt(thisInputNode, "offset", 0); if (offset > highestOffset) highestOffset = offset; offsets.Add(offset); } }
if (highestOffset > -1) highestOffset += 1; int stride = highestOffset;
// Indices XmlNodeList pNodes = polygonsNode.SelectNodes("p"); foreach (XmlNode thisPNode in pNodes) { // Get indices as string array String text = thisPNode.InnerText; text = text.Replace(Environment.NewLine, " "); text = text.Trim(); String[] splittedData = text.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
int numIndices = splittedData.Length / highestOffset;
for (int i = 0; i < offsets.Count; i++) { int[] indices = new int[numIndices]; for (int j = 0; j < numIndices; j++) { int index = offsets[i] + (j * stride); indices[j] = Int32.Parse(splittedData[index]); }
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Na gratuliere. Ich hoffe, Du bist mit Collada zufriedener, als ich es war.
Zitat:
Wenn der Offset aber bei beiden 0 wäre, dann würde ja das bei beiden rauskommen
Wenn der Index bei beiden gleich wäre, würde ich erwarten, dass das Polygon nur vier einzelne Elemente hat. Aber da bin ich mir nicht sicher. Viele Grüße, Traude
Registriert: Di Mai 18, 2004 16:45 Beiträge: 2623 Wohnort: Berlin
Programmiersprache: Go, C/C++
Schon mal darüber nachgedacht vieleicht eine bestehende Bibliothek dafür zu nutzen wie z.B. http://assimp.sourceforge.net/ ? Das könnte einiges an Zeit sparen.
_________________ "Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren" Benjamin Franklin
Na gratuliere. Ich hoffe, Du bist mit Collada zufriedener, als ich es war.
Zitat:
Wenn der Offset aber bei beiden 0 wäre, dann würde ja das bei beiden rauskommen
Wenn der Index bei beiden gleich wäre, würde ich erwarten, dass das Polygon nur vier einzelne Elemente hat. Aber da bin ich mir nicht sicher. Viele Grüße, Traude
Ich mach das aktuell nur, weil ich ein sehr schönen Tempel im Tiefen des Japanischen Internets gefunden habe, aber dieser halt nur in Collada definiert ist
TAK2004 hat geschrieben:
Schon mal darüber nachgedacht vieleicht eine bestehende Bibliothek dafür zu nutzen wie z.B. http://assimp.sourceforge.net/ ? Das könnte einiges an Zeit sparen.
Diese Lib habe ich mir schon angeschaut.
Es gibt viele Sachen die mich daran stören:
- Boost wird benötigt - Ist in C++ geschrieben und muss als Interop DLL in .NET somit eingebunden werden. - Das kann mir zuviel, es liest ja komplett alles von collada, ich brauch aber nur die Geometry.
Deswegen mach ich das selber, weil ich nur einen kleinen Teil davon brauche.
Mitglieder in diesem Forum: 0 Mitglieder und 5 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.