Ich versuche, Code zu schreiben, um Animationen zu übertragen, die für ein Skelett entwickelt wurden, um auf einem anderen Skelett korrekt auszusehen. Die Quellanimationen bestehen nur aus Rotationen mit Ausnahme von Übersetzungen im Stammverzeichnis (dies sind die Mocap-Animationen aus der CMU-Bewegungserfassungsdatenbank ). Viele 3D-Anwendungen (z. B. Maya) haben diese Funktion integriert, aber ich versuche, eine (sehr einfache) Version für mein Spiel zu schreiben.
Ich habe einige Arbeiten zur Knochenzuordnung durchgeführt, und da die Skelette hierarchisch ähnlich sind (Zweibeiner), kann ich für alles außer für die Wirbelsäule eine 1: 1-Knochenzuordnung durchführen (kann später daran arbeiten). Das Problem ist jedoch, dass die Grund-Skelett- / Bindungs-Posen unterschiedlich sind und die Knochen unterschiedliche Maßstäbe (kürzer / länger) haben. Wenn ich also nur die Drehung direkt darüber kopiere, sieht es sehr seltsam aus.
Ich habe eine Reihe von Dingen versucht, die der folgenden Lösung von Lorancou ähnlich sind, ohne Erfolg (dh Multiplikation jedes Einzelbilds in der Animation mit einem knochenspezifischen Multiplikator). Wenn jemand Ressourcen für solche Dinge hat (Papiere, Quellcode usw.), wäre das wirklich hilfreich.
quelle
Antworten:
Das Problem war die numerische Stabilität. Ungefähr 30 Stunden Arbeit in 2 Monaten, nur um herauszufinden, dass ich es von Anfang an richtig gemacht habe. Wenn ich die Rotationsmatrizen vor dem Einfügen in den Retarget-Code orthonormiert habe, hat die einfache Lösung des Multiplizierens von Quelle * Inverse (Ziel) perfekt funktioniert. Natürlich ist Retargeting viel mehr als das (insbesondere unter Berücksichtigung der unterschiedlichen Formen des Skeletts, dh der Schulterbreite usw.). Hier ist der Code, den ich für den einfachen, naiven Ansatz verwende, wenn jemand neugierig ist:
quelle
Ich glaube, dass Ihre einfachste Option darin besteht, die ursprüngliche Bindungshaltung mit Ihrem neuen Skelett abzugleichen, wenn Sie die Möglichkeit haben (wenn Ihr neues Skelett noch nicht gehäutet ist).
Wenn Sie das nicht können, können Sie Folgendes versuchen. Dies ist nur eine Intuition, ich übersehen wahrscheinlich viele Dinge, aber es könnte Ihnen helfen, das Licht zu finden. Für jeden Knochen:
In Ihrer "alten" Bindungshaltung haben Sie eine Quaternion, die die relative Rotation dieses Knochens im Vergleich zu seinem Elternknochen beschreibt . Hier ist ein Hinweis, wie Sie es finden. Nennen wir es
q_old
.Ebd. Nennen wir es für Ihre "neue" Bind-Pose
q_new
.Sie können die relative Drehung von der "neuen" Bindungspose zur "alten" Bin-Pose finden, wie hier beschrieben . Das ist
q_new_to_old = inverse(q_new) * q_old
.Dann haben Sie in einem Animationsschlüssel Ihr einziges Quaternion, das diesen Knochen von der "alten" Bindungspose in eine animierte Pose umwandelt. Nennen wir das hier
q_anim
.Anstatt
q_anim
direkt zu verwenden, versuchen Sie es mitq_new_to_old * q_anim
. Dies sollte die Orientierungsunterschiede zwischen den Bindungsposen "aufheben", bevor die Animation angewendet wird.Es könnte den Trick machen.
BEARBEITEN
Ihr Code oben scheint der Logik zu folgen, die ich hier beschreibe, aber etwas ist umgekehrt. Anstatt dies zu tun:
Sie könnten das versuchen:
Ich denke, dass Sie sich von Ihrem Ziel zu Ihrer Quelle transformieren müssen, bevor Sie die Quellanimation anwenden, um die gleiche endgültige Ausrichtung zu erhalten.
quelle