Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

11.10.2011, 15:35

Model, Bones und Positionsermittlung der Vertices

Hi,

ich bin gerade dabei ein Spiel zu programmieren und hänge bei der Animation von Modellen über Bones fest.
Als Quelle für das Modell und die Animationen nutze ich das .X Dateiformat.

Nun mein eigentliches Problem:

Ich verstehe irgendwie nicht den Zusammenhang der ganzen Matrizen um über die Animationsmatrizen der Bones die Position der Vertices zu bestimmen.

Beispiel hier:

Gegeben:

Vector3 der den Vertex bestimmt, den ich verschieben will ( -82.598602;-13.225058;0.000000;,)
OffsetMatrix vom Bone der den Vertex beeinflusst
(
0.999948,0.010172,0.000000,0.000000,
-0.010172,0.999948,0.000000,0.000000,
0.000000,0.000000,1.000000,0.000000,
82.591972,1.072177,-10.684452,1.000000;;),

sowie dessen TransformationsMatrizen über die Zeitspanne

( hier zum Zeitpunkt 0:

0.999948,-0.010172,0.000000,0.000000,
0.010172,0.999948,0.000000,0.000000,
0.000000,0.000000,1.000000,0.000000,
-73.549881,2.552204,10.684452,1.000000;;).

Wenn ich als Zeitpunkt 0 annehme, müsste ich doch als endgültige Position des Vertex seine ganz normale Position aus dem File rausbekommen oder?.

Nur hab ich leider keine Ahnung wie. Wie kommt man dann auf die Position des gesuchten Vertex?

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

2

11.10.2011, 15:46

Wenn du schon .x verwenden willst, dann verwend doch die entsprechende Funktionalität aus D3DX!?

3

11.10.2011, 15:48

sry hätte ich erwähnen sollen, ich programmiere in c# mit hilfe von xna.
Um aber die Bones in XNA richtig (oder besser wie von microsoft angedacht) nutzen zu können, müsste ich die durch die ContentPipeline jagen.
Ich lade dateien aber on the fly und deshalb fällt diese Methode weg und ich habe mir einen eigenen X Parser geschrieben.

4

11.10.2011, 15:49

Vielleicht möchte er es auch einfach nur verstehen und nicht denken: "Ach, mit der Funktion gehts, egal wie." (Dann wäre ein Lob angebracht)
Oder aber er möchte eine OpenGL-Applikation programmieren, die X-files laden kann?
Gibt also noch mehrere Möglichkeiten. ;)

5

11.10.2011, 15:52

Vielleicht möchte er es auch einfach nur verstehen und nicht denken: "Ach, mit der Funktion gehts, egal wie." (Dann wäre ein Lob angebracht)
Oder aber er möchte eine OpenGL-Applikation programmieren, die X-files laden kann?
Gibt also noch mehrere Möglichkeiten. ;)
Ja es geht mir ums verstehen :)

6

11.10.2011, 15:56

Dann ein dickes Lob, einfach Funktionen zusammenpappen kann jeder. :thumbup:

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

7

11.10.2011, 16:27

Puh, mit dem einenen .x Parser hast du dir ja viel vorgenommen. Wenn du noch nicht allzuviel Arbeit reingesteckt hast, würd ich dir eher ein anderes Format empfehlen, z.B. ms3d (zum Üben) oder MD5. Denn .x ist nicht nur unglaublich komplex, sondern auch ziemlich veraltet und mittlerweile auch offiziell deprecated.


Zwecks des Verstehens, einfache Boneanimation funktioniert folgendermaßen:

Alles beginnt in der sog. Bindpose. Das ist die Pose, in der das Modell modelliert wurde. In dieser Pose wird auch das Skelett aufgebaut und die Vertices den Bones zugewiesen. Bei den "Bones" handelt es sich eigentlich um die Gelenke (Joints) und nicht um die Knochen dazwischen.
Jeder Bone bzw. Joint hat eben eine Lage/Ausrichtung im Raum, die durch seine Matrix repräsentiert wird. Die Gelenke bilden eine Hierarchie, d.h. das Handgelenk hängt z.B. am Ellenbogen, der wiederum an der Schulter, die wiederum ... Wenn du die Schulter bewegst, sollen sich Ellenbogen und Handgelenk mitbewegen.
Die einzelnen Joints haben eine lokale Matrix (entspricht vermutlich deiner OffsetMatrix) die angibt, wie das Gelenk relativ zu seinem übergeordneten Gelenk platziert ist. Irgendwo gibt es einen Joint, der keinen übergeordneten mehr hat, ein sog. Root-Joint. Die lokalen Matritzen transformieren normalerweise vom untergeordneten zum übergeordneten Koordinatensystem. Damit kannst du nun für jeden Joint eine Matrix berechnen, die vom lokalen Koordinatensystem des Joint ins Koordinatensystem des Model umrechnet. Nennen wir sie die absolute Matrix des Joint. Sagen wir du willst die absolute Matrix des Handgelenks bestimmen. Die bekommst du nun eben, indem du die lokalen Matritzen entlang der ganzen Kette vom Handgelenk zum Root-Joint aufmultiplizierst. Also Handgelenk * Ellenbogen * Schulter * ... * Root-Joint. Diese Matrix transformiert dann direkt vom Joint- in das Model-Koordinatensystem.
Um das Modell nun zu animieren, werden einfach die Gelenke entsprechend animiert. Üblicherweise verwendet man dazu ein keyframebasiertes System. D.h. für jeden Joint wird dessen Lage/Ausrichtung zu bestimmten Zeitpunkten (Keys/Keyframes) festgelegt und dazwischen interpoliert. Zu jeden Zeitpuntk lässt sich dann für jeden Joint dessen absolute Matrix berechnen. Nun muss man nur noch die Vertices des Modells entsprechend mitbewegen. Im ganz einfachen Fall geht man davon aus, dass die Vertices fix an ein Gelenk gekoppelt sind. Um nun die neue Position eines Vertex zu einem bestimmten Zeitpunkt zu berechnen, muss man nur die Position des Vertex relativ zu seinem Gelenk mit der neuen absoluten Matrix des Gelenks transformieren (da der Vertex starr mit dem Gelenk verbunden ist, bleibt diese relative Position unabhängig von der Bewegung des Gelenks immer gleich). Die Position relativ zum Gelenk ergibt sich aus der Bindpose. Wir erinnern uns: Die absolute Matrix transformiert vom lokalen Koordinatensystem des Gelenks ins Model-Koordinatensystem. Die inverse dieser Matrix transformiert dann als vom Model-Koordinatesystem (in dem die Vertices normalerweise ursprünglich vorliegen) zurück in Koordinaten relativ zum Gelenk. D.h. um einen Vertex zu bewegen, transformieren wir seine Koordinaten erst mit der Inversen der Bindpose-Absoluten und dann mit der neuen absoluten Matrix des zugehörigen Gelenks. Natürlich gibts da noch Details, Tricks und viel aufwändigere Verfahren, aber rein prinzipiell funktioniert es so.

Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von »dot« (11.10.2011, 16:35)


8

12.10.2011, 08:11

Danke für die ausführliche Antwort :).

Den Grundgedanken hatte ich richtig aufgefasst. Mein Problem jetzt ist, dass wenn ich testweise einen Block mit einem Bone über die Keyframes animieren möchte, ist wie ich das Verstanden
habe die Finale Transformationsmatrix = OffsetMatrix vom Bone * die Transformationsmatrix im Frame. Wenn ich nun aber die Vertices darüber bewege (also Vector3.Transform) kommt da nichts sinnvolles bei raus. Die Vertices drehen sich wie wild, aber nicht so wie sie sollen.

Was habe ich denn jetzt vergessen?

Ich berechne am Anfang die Matrix und transformiere dann den Originalvector zum Zeitpunkt 0 über diese. Geht das nicht so?

EDIT: Habs hinbekommen! Nach langem debuggen hat sich herausgestellt, das meine rotierten Vektoren nur Zeiger auf die Originalvektoren waren und bei jedem ändern der rotierten Vektoren
hatten sich die Originalvektoren mit geändert.... Mann-O-Mann

Danke für die Hilfe nochmal :)

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »matrixteddy« (12.10.2011, 10:11)


Werbeanzeige

Ähnliche Themen