Ich habe Probleme beim Animieren eines geladenen COLLADA-Modells. Ich habe meinen eigenen Parser geschrieben und möchte nun auch meine eigene Zeichenroutine schreiben. Das Problem ist, dass sobald ich die Animation an meinem Modell aktiviere, die Hände, Beine und der Kopf vom Ursprung des Modells weggestreckt sind. (Der Loader basiert auf dem Tutorial: COLLADA Tutorial )
Das erste, was ich in meiner Zeichenfunktion des Modells mache, ist die Einrichtung der Verbindungsmatrizen (nicht ihre Weltmatrizen!) mit den gegebenen Zielen aus den gelesenen Blöcken, Wenn ich zum Beispiel einen Kanal lese wie:
%Vor%Ich werde die Matrixkomponente (3) (2) von der Gelenkmatrix des Gelenks mit der sid="Transformation" in diesem ersten Schritt modifizieren:
%Vor%Nachdem die JointMatrices von allen Kanälen modifiziert wurden, berechne ich die worldMatrices des Gelenks neu, indem ich die folgende Funktion auf dem Wurzel-Joint aufruft:
%Vor%Jetzt sollte alles bereit sein, um meine Modellbreite zu zeichnen, den folgenden letzten Teil meiner Zeichenfunktion:
%Vor%Jetzt ist das Problem, dass die Ausgabe wie folgt aussieht:
Ich bin mir sicher, dass die Datenlade-Routine richtig implementiert wurde, weil die allgemeine Animation des gehenden Mannes sichtbar ist, aber das Mesh deformiert ist:
Wie gesagt, wenn ich die Zeile auskommentiere:
%Vor%Die Animation ist deaktiviert und das Modell wird in der Standardpose angezeigt:
Wenn ich nun zu den ersten drei Spalten der jointMatrices eine Normalisierung hinzufüge, wie zuvor, rechne ich die Weltmatrix der Verbindung neu:
%Vor%Das Problem besteht immer noch, aber dieses Mal in einer anderen Ausgabe. Der Mann sieht jetzt wie ein Alien aus: D, aber das reduziert die Skalierung:
Ich weiß jetzt nicht genau, ob ich die Normalisierung richtig gemacht habe. Ist diese Normalisierung wirklich nötig? Es ist nicht im Tutorial beschrieben und ich konnte auch nichts Ähnliches finden.
Immerhin habe ich mir die Implementierung der Interpolation im Code von der Tutorial-Seite angeschaut. UND: Sie benutzen überhaupt keine Quaternionen, um die Lochmatrix zu lokalisieren. Was sie tun, ist folgendes (was bei mir nicht funktioniert):
%Vor%Dann verwende ich Quaternionen in einem anderen Ansatz (auch nicht für mich):
%Vor%Es wird auch nicht für mich funktionieren. Nichts scheint zu funktionieren. Ich habe wirklich keine Ahnung, was hier vor sich geht.
Jetzt nach zwei Tagen funktioniert es dank der Antwort von datenwolf
Ich möchte alle darüber informieren, wie es funktioniert hat. Jetzt scheint alles klar und es war immer nur ein kleiner Schritt. Jetzt beginnen wir mit dem Animationsteil. Ich iteriere über alle Kanäle und speichere die Anfangs- und Endwerte sowie einen Interpolations-Delta-Wert im Bereich 0.0 1.0 zum Gelenk, der Kanal animiert:
%Vor%Wie Sie sehen können, gibt es hier überhaupt keine Interpolation. Wir speichern einfach die Anfangs- und Endwerte und ein Delta für alle animierten Gelenke (und wir setzen auch ein Flag für jede modifizierte Verbindung)
Nun, nachdem alle Animationen gemacht sind, rufen wir die Funktion interpolateMatrices () auf allen Wurzelknoten auf:
%Vor%Das ist nicht neu, aber der interessante Teil ist jetzt die Implementierung der Interpolation. Nothing qith quaternions überhaupt:
%Vor%}
Wie Sie sehen können, geben wir einfach alle Werte der Matrix an und danach normalisieren wir die oberen drei Spalten der Matrix. Danach berechnen wir sofort die worldSpaceMatrix für dieses Joint, sowie die komplette Skinning-Matrix, um Leistung zu sparen. Jetzt sind wir fast fertig mit allem. Zuletzt müssen Sie die Scheitelpunkte animieren und dann das Gitter zeichnen:
%Vor%Alles in allem war es fast das gleiche wie der Code, mit dem ich angefangen habe. Aber jetzt sind die Dinge viel klarer für mich und ich kann beginnen, auch & lt; Übersetzung & gt ;, & lt; rotation & gt; und & lt; Maßstab & gt; Animationen auch. Fühlen Sie sich frei, meine Implementierung auf gear3d.de zu überprüfen (laden Sie den SVN-Stamm herunter)
Ich hoffe, dass dies einigen Leuten hilft, ihre eigene Lösung zu diesem wundervollen Thema zu implementieren:)
Wenn ich mir diese Bilder anschaue, habe ich den Eindruck, dass Ihre gemeinsamen Matrizen nicht normalisiert sind, d. h. der obere linke 3 × 3-Teil skaliert Ihre Masche nach oben. Versuchen Sie, was passiert, wenn Sie die oberen linken 3-Spalten-Vektoren normalisieren.
Wenn dies das Problem reduziert, muss untersucht werden, welcher Teil des Animationssystems das verursacht.
In meinem Fall zielen alle Referenzen auf Matrixkomponenten ab. Deshalb interpoliere ich nur eine Matrixkomponente.
Sie interpolieren niemals Matrizen. Immer .
Dies wird normalerweise so gehandhabt, dass beim Laden der Animationsdaten jede Matrix in eine Quaternion und Position zerlegt wird (und skaliert, wenn Sie die Skalierung animieren). Quaternions werden verwendet, weil sie klein sind, einfach zu interpolieren und nach der Interpolation leicht zu normalisieren sind. Im Gegensatz zu Matrizen, die groß sind, schwer zu interpolieren und danach schwer zu orthonormieren.
Beachten Sie, dass der obige Vorgang normalerweise als Vorverarbeitungsschritt in einem Werkzeug ausgeführt wird. Das Werkzeug lädt die Collada-Animation, wandelt sie in Quaternionen und Positionen um und schreibt diese dann zum späteren Lesen in ein Dateiformat.
Sie interpolieren dann die Quaternionen (verwenden Sie ein LERP für die Intra-Animationsinterpolation) nach Bedarf mit einer schnellen Normalisierung danach. Die Positionen müssen nur aktualisiert werden, wenn sich die Positionen tatsächlich relativ zum ursprünglichen Offset ändern. Sie komponieren diese zurück in eine Matrix und fahren wie gewohnt fort.
Einfach und einfach.