Mit dem .x-Format zum Exportieren eines Modells aus Blender kann ich ein Netz, einen Anker und eine Animation laden. Ich habe keine Probleme beim Generieren des Netzes und beim Anzeigen von Modellen im Spiel. Zusätzlich habe ich Animationen und den Anker richtig in entsprechende Datenstrukturen geladen.
Mein Problem besteht darin, die Animation ordnungsgemäß auf die Modelle anzuwenden. Ich habe den Rahmen für die Anwendung der Modelle und den Code für die Auswahl von Animationen und das Durchlaufen von Frames.
Soweit ich weiß, liefert das AnimationKey
s im Inneren die AnimationSet
Transformationen, um die Bindungspose in die Pose im animierten Frame umzuwandeln. Als kleines Beispiel:
Animation {
{Armature_001_Bone}
AnimationKey {
2; //Position
121; //number of frames
0;3; 0.000000, 0.000000, 0.000000;;,
1;3; 0.000000, 0.000000, 0.005524;;,
2;3; 0.000000, 0.000000, 0.022217;;,
...
}
AnimationKey {
0; //Quaternion Rotation
121;
0;4; -0.707107, 0.707107, 0.000000, 0.000000;;,
1;4; -0.697332, 0.697332, 0.015710, 0.015710;;,
2;4; -0.684805, 0.684805, 0.035442, 0.035442;;,
...
}
AnimationKey {
1; //Scale
121;
0;3; 1.000000, 1.000000, 1.000000;;,
1;3; 1.000000, 1.000000, 1.000000;;,
2;3; 1.000000, 1.000000, 1.000000;;,
...
}
}
Um Frame 2 anzuwenden, würde ich die Position, Drehung und Skalierung von Frame 2 übernehmen, daraus eine Transformationsmatrix erstellen (nennen Transform_A
) und diese Matrix auf die Scheitelpunkte anwenden, die von Armature_001_Bone
ihren Gewichten gesteuert werden. Also würde ich TransformA
in meinen Shader stopfen und den Scheitelpunkt transformieren. Etwas wie:
vertexPos = vertexPos * bones[ int(bfs_BoneIndices.x) ] * bfs_BoneWeights.x;
Wo bfs_BoneIndices
und bfs_BoneWeights
sind Werte, die für den aktuellen Scheitelpunkt spezifisch sind.
Beim Laden in die Netzscheitelpunkte transformiere ich sie durch das rootTransform
und das meshTransform
. Dies stellt sicher, dass sie für die Anzeige der Bindungspose richtig ausgerichtet und skaliert sind.
Das Problem ist, dass beim Erstellen dieser Transformationsmatrix (unter Verwendung der Position, Drehung und Skalierung aus der Animation) der Scheitelpunkt nicht richtig transformiert wird. Es geht wahrscheinlich um mehr als nur um die Verwendung der Animationsdaten. Ich habe auch versucht, die Knochentransformationshierarchien anzuwenden, immer noch keine Würfel. Grundsätzlich habe ich einige verdrehte Modelle. Es sollte auch beachtet werden, dass ich in openGL arbeite, daher sollten alle Matrixtransponierungen, die möglicherweise angewendet werden müssen, berücksichtigt werden.
Welche Daten benötige ich und wie kombiniere ich sie, um .x-Animationen auf Modelle anzuwenden?
Ich habe einige Modelle gemacht, wie das aussieht, falls das nützlich ist.
Zuerst wollte ich nur die Übersetzung testen, das ist ein schwankender Kopf, wie es in Blender aussieht:
http://i.stack.imgur.com/NAc4B.gif
Und wie es im Spiel aussieht (egal die Farben):
http://i.stack.imgur.com/nj2du.gif
Für eine einfache Drehung war die Animation der Kopf, der sich um 360 Grad um die vertikale Achse drehte. So sieht das im Spiel aus:
http://i.stack.imgur.com/gVyUW.gif
Beachten Sie, dass es keine Neigung geben sollte, sondern nur eine Drehung wie ein Karussell.
Aktualisieren
Ich habe den Übersetzungsteil der Animation in Arbeit. Aber es fühlt sich irgendwie hackig an und ich sehe nicht, wie ich es auf die Rotation anwenden soll.
Die Übersetzung funktioniert folgendermaßen:
- Nehmen Sie die Position aus dem Animationsrahmen und tauschen Sie die Werte
y
undz
aus - Übersetzen Sie die Transformationsmatrix um die geänderte Position
- Transponieren Sie die Transformationsmatrix
- Wenden Sie die Transformationsmatrix auf die Scheitelpunkte an
So kann es also funktionieren, aber wie soll es allgemein für Position, Skalierung und Rotation funktionieren?
quelle
Antworten:
Vielleicht ist das der Schlüssel. Haben Sie versucht, einige Z-Koordinaten zu negieren, um sie von DirectX-Koordinaten für Linkshänder in OpenGL-Koordinaten für Rechtshänder umzuwandeln?
Sie können alle Zs negieren, bevor Sie Ihre Transformationen anwenden. Wenn Sie fertig sind, können Sie erneut negieren, um festzustellen, ob die Ausgabe besser wird.
BEARBEITEN
Das Vertauschen der Y- und Z-Koordinaten ist eine weitere Möglichkeit, die Händigkeit zu ändern. Sie müssen also Ihre Transformationen anpassen. Weitere Informationen finden Sie in diesem Dokument .
Die Tatsache, dass Sie Ihre Matrix transponieren müssen, bedeutet auch, dass Sie von Zeilenmajor zu Spaltenmajor oder umgekehrt wechseln. Dies sollte weniger kompliziert zu handhaben sein, Sie müssen wahrscheinlich nur den richtigen "Ort" finden, um dies in Ihrer Pipeline zu tun. Ich rate nur, aber es bei Quaternionen zu tun, könnte einfach bedeuten, sie in Matrizen zu ändern, Quaternionen zu transponieren und zurück zu gehen, wenn Ihre Math-Bibliothek diese Option anbietet.
quelle
OK, ich habe etwas mehr Zeit dafür aufgewendet und es für mehrere Knochen zum Laufen gebracht und deutlich weniger hackartig (wenn auch immer noch ein wenig). Das System, das ich ursprünglich hatte, war fast korrekt. Die Hauptprobleme waren jedoch:
Mein Code zum Konvertieren eines Quaternions in eine Matrix war falsch. Ich bin mir eigentlich immer noch nicht sicher, warum dies falsch ist, aber ich weiß, dass der folgende Code als Teil meiner Quaternion-Klasse funktioniert:
Davon abgesehen ist es nur:
finalMatrix = boneMatrix * skinMatrix * invertedBindMatrix;
Notiere dass der
boneMatrix
animierten Matrizen für jeden Knochen anstelle der Bindematrizen verwendet werden sollten. Es sollte auch alle übergeordneten Matrizen wie folgt erhalten:Und es funktioniert. Hinterlasse einen Kommentar, wenn du Klarstellung brauchst.
quelle