Assimp aiNode Names

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
Benutzeravatar
Jonathan
Establishment
Beiträge: 2353
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Assimp aiNode Names

Beitrag von Jonathan »

'nAbend

Ich verzweifle gerade ein wenig an den Datenstrukturen von Assimp.

Nach einem Versionsupgrade hängt mein Loader in einer Endlosschleife. Ich kann nicht genau sagen, welcher Versionssprung dafür verantwortlich ist, ich kompiliere hier auf einem neuen PC und hab grad nicht den Nerv dutzende Versionen auszuchecken, zu kompilieren, meine Engine zu kompilieren, alles zu testen und dann wieder von vorne anzufangen. Egal, langfristig will ich ja eh mit der neusten Version kompatibel sein, also wird die jetzt einfach benutzt und meine Engine dazu kompatibel gemacht.

Konkret geht es darum, dass ich die Bone bzw. Node Struktur in meine Bones umsetze. Früher hab ich einfach den Namen von einem aiNode als Identifier genommen, aber jetzt habe ich hier ein Modell, dessen erster Node "Scene" heißt, dessen Child dann "carabiner01" (Name des Modells) aber dessen Child dann auch wieder "Scene". Zack, Endlosschleife. Auf den ersten Blick sahen die zwei "Scene"-Node Pointer unterschiedlich aus (es ist ja die Frage ob ein Zyklus in der Node-Hiearchie ist, oder einfach der Name gleich ist), aber das ist letztendlich auch egal, denn die Dokumentation sagt, dass der Name einfach kein Unique-Identifier ist und leer sein kann oder das auch zwei Bones den selben Namen haben können. Also muss ich meinen Code so oder so fixen.
Das Problem ist jetzt: aiNodes haben überhaupt keinen Unique-Identifier. Es gibt keinen Index oder ähnliches (es sind ja auch einfach nur Objekte, die nicht notwendigerweise hintereinander im Speicher stehen), d.h. wenn ich die Knochen in meiner Struktur nachbilden will bleibt mir nichts anderes übrig, als Pointer zu vergleichen. Was vermutlich ok ist, aber ich meine mich zu erinnern, dass es in C++ prinzipiell Fälle gibt, wo das schief gehen kann (bei Vererbungshierarchien und unterschiedlichen Pointertypen oder so), also ist es schonmal nicht unbedingt nett, das tun zu müssen.

Also fange ich an meinen Loader umzuschreiben, bis ich bei aiBone auf das nächste Problem stoße: Hier wird ein Node auf einmal anhand seines Namens referenziert, es gibt keinen Pointer mehr. Gut, laut Dokumentation ist der Node Name eindeutig, wenn ein Bone auf ihn zeigt, also sollte das prinzipiell funktionieren, aber hey mal ehrlich, das ist doch kacke. Um Nodes zu referenzieren brauche ich jetzt sowohl eine Abbildung von Pointer auf Node als auch von Name auf Node. Ist das einfach historisch irgendwie komisch gewachsen oder gibt es einen vernünftigen Grund dafür? Wieso haben aiNodes keinen Unique-Identifier? Das muss ja nicht der Name sein, der Name könnte ja auch eine Art optionaler Kommentar sein. Aber so ist das alles gerade irgendwie sehr unbefriedigend.

Die zweite, vielleicht interessantere Frage: Hat irgendjemand hier den Überblick über die Assimp Entwicklung und klingelt da bei meinem Problem gerade irgendetwas? Wie gesagt, ich hab nicht alles komplett systematisch durchgetestet, aber ich bin mir ziemlich sicher, dass ich jetzt andere Datenstrukturen von Assimp bekomme als früher, denn der entsprechende Code wurde lange nicht angefasst und hat zuvor immer "gut" funktioniert. Vermutlich war das Verhalten immer irgendwie falsch, weil ich davon ausging, Node-Namen seien Unique-Identifier, aber das ging trotzdem bisher immer gut.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Benutzeravatar
Krishty
Establishment
Beiträge: 8229
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Assimp aiNode Names

Beitrag von Krishty »

Jonathan hat geschrieben: 05.10.2022, 21:39Das Problem ist jetzt: aiNodes haben überhaupt keinen Unique-Identifier. Es gibt keinen Index oder ähnliches (es sind ja auch einfach nur Objekte, die nicht notwendigerweise hintereinander im Speicher stehen), d.h. wenn ich die Knochen in meiner Struktur nachbilden will bleibt mir nichts anderes übrig, als Pointer zu vergleichen. Was vermutlich ok ist, aber ich meine mich zu erinnern, dass es in C++ prinzipiell Fälle gibt, wo das schief gehen kann (bei Vererbungshierarchien und unterschiedlichen Pointertypen oder so), also ist es schonmal nicht unbedingt nett, das tun zu müssen.
Die Vergleiche sind erlaubt und okay, so lange du die Zeiger vorher nicht zu void * castest, sondern bei ihren Typen bleibst.

Minimales Problem ist, dass die Adressen Laufzeitabhängig sind und sich von Durchlauf zu Durchlauf ändern können (und aus Sicherheitsgründen auch ändern sollen). Falls du sie z. B. in einem std::set sammelst oder anderweitig nach Adressen sortierst, ist dein Import nicht mehr reproduzierbar (liefert mit jedem Durchlauf ein anderes Ergebnis).
Jonathan hat geschrieben: 05.10.2022, 21:39Die zweite, vielleicht interessantere Frage: Hat irgendjemand hier den Überblick über die Assimp Entwicklung und klingelt da bei meinem Problem gerade irgendetwas? Wie gesagt, ich hab nicht alles komplett systematisch durchgetestet, aber ich bin mir ziemlich sicher, dass ich jetzt andere Datenstrukturen von Assimp bekomme als früher, denn der entsprechende Code wurde lange nicht angefasst und hat zuvor immer "gut" funktioniert. Vermutlich war das Verhalten immer irgendwie falsch, weil ich davon ausging, Node-Namen seien Unique-Identifier, aber das ging trotzdem bisher immer gut.
Bin leider seit einem Jahr raus und die UID-Problematik klingelt bei mir nichts. Schreib kimmi ggf eine PM, aber besser wäre das Öffnen eines Issues auf Github (da schauen dann auch andere Experten drauf).

(Ich habe immer mit Zeigerwerten gearbeitet. Aber ich habe mich nie um Bone-Hierarchien gekümmert, darum ist das jetzt keine Empfehlung.)
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Jonathan
Establishment
Beiträge: 2353
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: Assimp aiNode Names

Beitrag von Jonathan »

Ok.

Ich hab jetzt eine kleine Hilfsklasse geschrieben, über die man Bones entweder per Zeiger oder per Name abfragen kann. Das Laden funktioniert jetzt gemäß Spezifikation und es wird nicht mehr angenommen, dass Nodes eindeutige Namen haben.
Tatsächlich hat das jetzt all meine Probleme beseitigt. Es gibt keine Endlosschleifen mehr und die geladenen Animationen funktionieren auch korrekt (vorher hatte ich einen dummen Fix implementiert, der zwar die Schleife terminieren lässt weil er mit Zykeln im Graphen zurecht kommt (die durch das falsche mergen von Nodes gleichen Namens entstehen), aber damit halt auch die Animationen kaputt macht). Jetzt bin ich bis auf Weiteres happy.

Trotzdem bleibt der Kommentar, das man sich doch vlt. mal überlegen könnte, die Assimp-Datenstrukturen anzupassen. Wäre ja voraussichtlich ein Breaking-Change und damit was für Version 6, aber ich finde das aktuelle System wirklich nicht hübsch. Ich würde ja z.B. einen Integer-Key präferieren, einerseits ist der effizienter als ein String-Vergleich, andererseits könnte man auch alle aiNodes der Szene in ein Array packen und dann in Konstanter Zeit darauf zugreifen.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Benutzeravatar
Schrompf
Moderator
Beiträge: 4838
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Assimp aiNode Names

Beitrag von Schrompf »

Die Namen der Nodes kommen aus den Files, die Du importierst. Und daher müsstest Du nicht nur Assimp-Versionen durchprobieren, sondern auch Deine Exporter checken, ob die jetzt krude Szenenhierarchien schreiben.

Deine Map von Nodes muss doch nicht über Importe hinweg gepflegt werden, oder? Dann nimm einfach den Node-Pointer anstatt des Namens als Key und fertig. Sind doch alles nur Zahlen. Den Doku-Teil mit den Node-Namen hab ich geschrieben, ich kann Dir versichern, dass Du Dich auf die Namen wirklich nicht verlassen solltest.

Alle Angaben ohne Gewähr, bin schon ne Weile aus der Loop.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Jonathan
Establishment
Beiträge: 2353
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: Assimp aiNode Names

Beitrag von Jonathan »

Ich hab das nochmal überprüft:

Alt:
Viewer_04eFOMWQGw.png
Viewer_04eFOMWQGw.png (7.24 KiB) 489 mal betrachtet
Neu:
Viewer_w346mpIVwb.png
Viewer_w346mpIVwb.png (6.44 KiB) 489 mal betrachtet
Scheinbar wurde früher der Top-Level-Node umbenannt und das wurde irgendwann geändert. Auf eine gewisse Art sind die Namen damit vermutlich "richtiger". Aber ihr könnt euch vorstellen, dass das meinem alten Code, der Nodes nur anhand von Namen erkennt, nicht gefallen hat...
Deine Map von Nodes muss doch nicht über Importe hinweg gepflegt werden, oder? Dann nimm einfach den Node-Pointer anstatt des Namens als Key und fertig. Sind doch alles nur Zahlen. Den Doku-Teil mit den Node-Namen hab ich geschrieben, ich kann Dir versichern, dass Du Dich auf die Namen wirklich nicht verlassen solltest.
Jap, aber das Problem ist halt, dass sowohl aiBone als auch aiNodeAnim ihre entsprechenden Nodes einzig über Namen adressieren. Man kommt um einen Namen-Lookup also unmöglich herum. Und damals hat mich das halt in die Versuchung geführt, einfach alles über Namen zu machen...

Aber ok, ein wirklicher Bug-Report ist es doch nicht geworden (was in gewisser Weise ja besser ist), es funktioniert ja alles wie spezifiziert, und mag ich halt die Spezifikation absolut nicht. Oh well...
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Antworten