Nochmal: Skeletal Animation
-
Ich kenne die Threads zu diesem Thema von ein paar Tagen, aber außer, dass diese bewirkt haben, dass ich nun auch ein kleines Animationsprogramm schreiben will, können sie kaum Fragen beantworten.
weights braucht man nur, wenn man einem Vertex mehr als 1 Bone zuordnen will, oder?
einem Vertex mehr als ein Bone zuzuordnen, macht eigentlich keinen Sinn, es sei denn man will eine schön "smoothe" Knickstelle statt einem spitzen Ellenbogen oder sowas, oder?
wenn bisher korrekt, und unter der weiteren Annahme, dass 2) ziemlich kompliziert wird: Ist das unbedingt notwendig oder erziehlt man auch so schöne Ergebnisse?
Jetzt geht's etwas mehr in die Software-engineer/Design-Richtung:
Ich stell mir das dann in einer Engine später so vor:
Es gibt eine Mesh-Klasse, die ein paar Arrays hat; in diesen sind die Vertices und Normals und Texcoords und so, und in einem weiteren Indices. (Es ist sichergestellt, dass alles Arrays außer dem Indices-Array gleich groß sind, so dass ein Index reicht, anders gehts eh nicht mit OpenGL Vertex Arrays / Buffer Objects)
Jedes Mesh besitzt dann noch einen Zeiger auf ein Bone-Objekt (root_bone).
Ein Bone besitzt wiederrum einen std::vector oder so von Zeigern auf andere Bones (childs). Jedes Bone hat außerdem ein Array indem Indices für die Vertex Data Arrays des Meshes stehen UND
eine Zuordnung von Zeiten mit dreh-informationen (matrizen, quaternions, winkel, kA, die Frage kommt noch)
Vielleicht also eine std::map.
Jetzt muss Mesh nurnoch die Vertexdaten aktualisieren können.
Dazu dachte ich: ich geb' Mesh eine rekursive Funktion
Diese wird einmal pro Frame dann so aufgerufen:
updateMesh(time, IrgendwasMathematisches(), root_bone);updateMesh(float time, const IrgendwasMathematisches& parent_berechnete_drehinformation, const Bone& bone) { IrgendwasMathematisches interpolierteDrehung = bone.interpoliereZwischenEntsprechendenDrehinfosAusDerSTD_Map(time); //beim rootbone gibt es immer 2 Einträge in der 0. Sekunde und am Ende (30. Sekunde?) //beide Einträge stellen 0 bzw. Identity dar IrgendwasMathematisches endgültigesDing = parent_berechnete_drehinformation * interpolierteDrehung; //parent_berechnete_drehinformation wird beim root auch als identity bzw. 0 übergeben, s.o. for (int i = 0; i < vertex_count; ++i) { verticex[i] *= endgültigesDing; normals[i] *= endgültigesDing; } for (int i = 0; i < bone.children.size(); ++i) { updateMesh(time, endgültigesDing, bone.children[i]); } }
Soweit, so gut.
Jetzt brauchen die Leute, die mir hier helfen sollten, auch noch Mathekenntnisse, über die ich in diesem Bereich kaum verfüge:
Wie ich oben schon schrieb, weiß ich nicht, wie ich die Informationen speichern und wie ich damit arbeiten soll.
Die anscheinend altbekannte Mehtode wären Matrizen.
So wie ich das mitkriege, arbeiten die DirectXler besonders gerne damit.
Ich habe Matrizen lustiger weise noch nie gebraucht (außer in Shadern). Meine Kameraklasse verwendet nur gewöhnliche Winkel in Form von 3 floats, und benutzt glRotate um nacheinander um die 3 Achsen zu drehen -> Funktioniert trotz Gimbal Lock, der Spieler bekommt eine stinknormale Egoshootersteuerung. Auch für Shadow Mapping brauche ich dank 0&00000001's (oder so, bin kein C-ler, sry) Hilfe keine Matrizen mehr für meine Punktlichter.
Die Frage 4) ist also, ob nicht sogar einfache Winkel ausreichen. Dass diese dann, wenn Gimbal Lock auftritt, nicht mehr die "echten" Winkel sind, ist klar.
Aber das stört ja keinen, solange trotzdem alles funktioniert.
oder anders -> 4) Stört Gimbal Lock hier überhaupt?
Jetzt schweife ich in 2 entgegengesetzte Richtungen ab und stelle 2 weitere Fragen:
5)
Wenn Gimbal Lock auftritt, wenn ich glRotate verwende, wieso sollte es dann nicht auftreten, wenn ich die Matrizensachen selbst berechne?
6)
Falls 4) mit JA und 5) mit "es tritt doch noch auf" beantwortet wurde:
Ich habe nun noch von Quaternions gehört. Damit sollen sich wunderbar mehrere Rotationen kombinieren lassen. Die Doom3-Engine scheint Quaternions für Skeletal Animation zu verwenden.
Problem: Habe keine Lust mir eine Library dafür zu schreiben. Für Matrizen hab ich schon eine.Oh, und noch was, sehr wichtig:
Wenn ich nur mit Winkeln arbeite (was ich ja anstrebe wegen der Einfachheit),
muss ich ja (da ich sowieso kein glRotate benutzen kann, sondern die Positionen erst selbst vor dem Zeichnen ausrechnen will, wegen Kollision etc.) das ganze nicht genau so machen wie glRotate.
Ich würde einfach mit sin und cos arbeiten, und nacheinander die 3 Drehungen berechnen. Also erst um die X-Achse, dann um die Y-Achse, dann um die Z-Achse. Außerdem würden die Drehwinkel in einem vektor3 gespeichert sein, und anstatt der Matrizenmultiplikation würde ich Vektoren addieren.
Jetzt kann ich mir noch vorstellen, dass was anderes dabei rauskommt, wenn ich die Reihenfolge vertausche. Ist aber glaub ich nicht so schlimm. Gimbal Lock heißt doch, dass um die lokalen Achsen gedreht wird, und diese bei jeder Rotation mitgedreht werden. Und DAS kann ich mir bei dieser Methode nicht vorstellen.
Mag sein, dass es an meinem begrenzten Vorstellungsvermögen liegt.
Oder ist das vielleicht doch ok so, und eigentlich nichts anderes als Matrizen zu benutzen?Um wieder auf das Design zurückzukommen:
Gestern Nacht viel mir irgendwas ein, das man eigentlich auch von unten nach oben durch den Baum gehen könnte und so, und da war das ganze plötzlich schnell und eleganter und besonders dafür geeignet dass auch mit Weights und so gearbeitet werden kann. Die rekursive Funktion hat das sich glaub ich als erstes für die Parents selbst aufgerufen und das Ergebnis für diese returned, so fiel der zusätzliche Parameter "const IrgendwasMathematisches& parent_berechnete_drehinformation" wegKann mich leider nicht mehr genau dran erinnern...
Was ich eigentlich sagen will: Bevor ich nicht weiß, wie ich das mathematisch machen will und ob ein vertex mehrere Bones haben können sollte, kann ich mir nur schwer über das Design gedanken machen.
Das sind dann also die wichtigsten Fragen. Besonders eifrige Helfer können aber gerne auch gleich noch mit auf das Design eingehenSo, ich glaub das war der längste Beitrag den ich je geschrieben habe. Würde mich da gleich auch noch mal interessieren, ob das zu viel ist und man lieber ein, zwei kurze Fragen hätte formulieren sollen, unter der Gefahr, nicht richtig verstanden zu werden, oder ob das ok so war.
Vielen Dank für alle mich weiterbringende Mühen, postet fleißig!
P.S: Google sollte nur bedingt helfen. Schließlich ist es möglich, dass z.B. nur noch niemand versucht hat, Winkel statt Matrizen zu nehmen, obwohl es möglich wäre, und ich ein falsches Bild erhalte.
-
- Ja.
2/3) Frage den Grafiker.
4)5)6( Ja, kann auftreteten, dafür kann man sich sich Winkel besser als die Quaternionen vorstellen.
Bye, TGGC (NP Intelligenz)
-
Nun ja, Grafiker habe ich leider nicht zur Hand.
Hab ich das richtig verstanden, Gimbal Lock ist nicht weiter schlimm, und einfache Winkel sollten ok sein?
D.h., hast du "kann" im Sinne von "dürfen" gebraucht?
Das wäre dann schonmal sehr interessant.
Ich befürchte nämlich, dass Quaternions für mich (10.-Klässler) ein wenig "zu hoch" sind...