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

maumo

unregistriert

1

16.11.2010, 14:27

Bonematrizen

Hi,

ich arbeite zur Zeit an einem Projekt, dass einen Exporter für Blender beinhält, mit dem ich Blender-Modelle in ein XML-Format schreibe, um diese dann via XNA in einer eigenen Engine darzustellen und zu animieren.

Nun habe ich ein Problem mit den Bones.

Mein allgemeines Verständnis zum vorgehen sieht so aus:

Vertices sind in absoluter Position gespeichert. Zu allen habe ich Position, Normale, BoneIndices (4 Stück) und BoneWeights (auch 4 Stück).
Zu den Bones habe ich jeweils den Parent-Bone und die absolute Matrix gespeichert.

Nun lade ich ein Modell und transformiere dessen Vertices mit den Matrizen ihrer 4 Bones. Diese multipliziere ich vorher mit dem entsprechenden Weigthtwert und addiere sie zu einer. Dann speichere ich die invertierte Matrix.

Im Vertex-Shader werden nun die invertierten Matrizen zu den Bones geladen und dann die Vertices gerendert.
Soweit so gut. Bis hierhin habe ich noch keine sichtlichen Probleme.

Nun möchte ich natürlich auch irgendwelche Animationen abspielen. Zu diesen speichere ich für die entsprechenden Frames für die einzelnen Bones die lokale Matrix und multipliziere diese jeweils mit der des Parent-Bones (diese ist auch mit den des Parents multipliziert usw.). Zum Schluss wird diese Matrix noch mit der invertierten des Bones multipliziert und zum rendern geladen.
Hier scheine ich einen Denkfehler zu haben. Es werden merkwürdige Fraktale angezeigt.

Könnt ihr mir da helfen? Ist das das gängige Vorgehen?

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

2

16.11.2010, 15:31

Normalerweise transformiert man die Vertices zunächst mit der Inversen der absoluten Bindpose-Bonematrix. So bekommst du die Positionen der Vertices relativ zu ihren Bones. Die packst du in deinen Vertexbuffer. Um das Modell dann animiert zu rendern berechnest du für jeden Frame die absoluten Bonematritzen und übergibst die an den VertexShader. Der VertexShader muss jetzt nurnorch die Vertexposition mit der entsprechenden Bonematrix transformieren und fertig.

maumo

unregistriert

3

16.11.2010, 21:50

Transformiere ich die Vertices denn mit der Summe der Inversen? Oder summiere ich die absoluten Matrizen, invertiere dannach und transformiere dann?

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

4

16.11.2010, 21:55

Du tust nicht summieren sondern multiplizieren. Die absolute Bone Matrix ist das Produkt von der lokalen Matrix mit der absoluten Matrix des Parent, also im Prinzip das Produkt von allen Bonematritzen vom aktuellen bis ganz rauf zum Root Bone. In welcher Reihenfolge du multiplizierst hängt von deinen Konventionen ab (Spalten- vs. Zeilenvektoren). Ob zuerst oder nacher invertieren ist eigentlich egal, wenn du die inversen Matritzen konkatenieren willst dann pass auf dass dabei die Multiplikationsreihenfolge natürlich umkehrt ist.

maumo

unregistriert

5

17.11.2010, 09:06

Ich habe zu jedem Vertex ja aber mehrere BoneIndices, sodass ich ja beim laden die Vertices mit mehreren absoluten Bone Matrizen transformieren muss. Summiere ich diese denn?

C#-Quelltext

1
2
3
4
5
6
7
Matrix m = InverseBindMatrices[vertices[i].BlendIndices0] * vertices[i].BlendWeight.X
+ InverseBindMatrices[vertices[i].BlendIndices1] * vertices[i].BlendWeight.Y
+ InverseBindMatrices[vertices[i].BlendIndices2] * vertices[i].BlendWeight.Z
+ InverseBindMatrices[vertices[i].BlendIndices3] * vertices[i].BlendWeight.W;

vertices[i].Position = Vector3.Transform(vertices[i].Position, m);
vertices[i].Normal = Vector3.Transform(vertices[i].Normal, m);


Wobei ich vorher zu jedem Bone das hier mache:

C#-Quelltext

1
2
3
BindMatrices[j] = bone.Transform;
absoluteTransform = bone.Transform * parentBoneTransform;
InverseBindMatrices[j] = Matrix.Invert(absoluteTransform);

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

6

17.11.2010, 10:29

Es ist egal ob du vorher die Matritzen gewichtet aufsummierst und dann den Vertex damit multiplizierst oder zuerst den Vertex mit jeder Matrix multiplizierst und dann die Ergebnisse davon gewichtet aufsummierst.

maumo

unregistriert

7

17.11.2010, 10:32

Hm Schade, dann muss ich wohl nach eienr anderen Fehlerstelle suchen.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

8

17.11.2010, 10:41

Wenn du ein Problem hast würd ich die Sache mit den Gewichten überhaupt mal streichen und erstmal schauen dass ich das ganze mit nur einem Bone pro Vertex zum Laufen bekomme.

maumo

unregistriert

9

17.11.2010, 12:13

Zitat

Wenn du ein Problem hast würd ich die Sache mit den Gewichten überhaupt mal streichen und erstmal schauen dass ich das ganze mit nur einem Bone pro Vertex zum Laufen bekomme.
Danke für den Tipp. Hatte vergessen das nach ein paar Änderungen nochmal mit einzelnen Bones zu testen. Das Problem besteht aber weiterhin.

Ich habe mein Problem mal abgefilmt.
So sollte es aussehen:

[youtube]http://www.youtube.com/watch?v=lpIOeEvb0_4[/youtube]

Und so sieht es aus:
[youtube]http://www.youtube.com/watch?v=cpVc-Ce697U[/youtube]

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

10

17.11.2010, 12:22

Das schaut mir nach einer falschen Multiplikationsreihenfolge deiner Matritzen aus...

Werbeanzeige