Du bist nicht angemeldet.

Werbeanzeige

Cranberry

Treue Seele

  • »Cranberry« ist der Autor dieses Themas

Beiträge: 312

Wohnort: Innsbruck, Tirol

  • Private Nachricht senden

1

29.12.2013, 23:35

[DirectX] Objekte um eigene Achse rotieren

Folgendes Szenario: Ich habe zwei Würfel in meiner Szene. Diese will ich um ihre eigene Achse rotieren. Ich multipliziere also die worldMatrix mit einer YawPitchRoll-Rotationsmatrix.

C-/C++-Quelltext

1
m_WorldMatrix = m_WorldMatrix * XMMatrixRotationRollPitchYaw(m_RotationX, m_RotationY, m_RotationZ);

Die Würfel rotieren sich jedoch nicht um ihre eigene Achse sonder um den Mittelpunkt.
Um das ganze zu veranschaulichen hab ich euch mal das BeispielOnline gestellt.
Wie kann ich den Würfel also um seine eigene Achse rotieren? Muss ich den Würfel zuerst auf den Mittelpunkt setzen, rotieren und wieder zurücksetzen? (Das wär doch unsinnig :D)

FSA

Community-Fossil

  • Private Nachricht senden

2

29.12.2013, 23:39

Muss ich den Würfel zuerst auf den Mittelpunkt setzen, rotieren und wieder zurücksetzen?

So ist es!

Nachtrag: Objekt mit der Matrix multiplizieren
§ \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ -Tx & -Ty & -Tz & 1 \end{pmatrix} §
Dann rotieren und wieder mit dieser Matrix multiplizieren
§ \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ Tx & Ty & Tz & 1 \end{pmatrix} §

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veralteten strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

Cranberry

Treue Seele

  • »Cranberry« ist der Autor dieses Themas

Beiträge: 312

Wohnort: Innsbruck, Tirol

  • Private Nachricht senden

3

29.12.2013, 23:46

8|
Jetzt wo ich drüber nachdenke klingt es logisch, aber bei vielen Objekten schlägt sich sowas doch auf die Performance. Naja anscheinend geht das nicht anders.
Dankesehr!

FSA

Community-Fossil

  • Private Nachricht senden

4

29.12.2013, 23:49

Doch das ganze geht anders.
Mach aus
m_WorldMatrix = m_WorldMatrix * XMMatrixRotationRollPitchYaw(m_RotationX, m_RotationY, m_RotationZ);
einfach
m_WorldMatrix = XMMatrixRotationRollPitchYaw(m_RotationX, m_RotationY, m_RotationZ) * m_WorldMatrix;

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veralteten strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »FSA« (30.12.2013, 00:02)


Cranberry

Treue Seele

  • »Cranberry« ist der Autor dieses Themas

Beiträge: 312

Wohnort: Innsbruck, Tirol

  • Private Nachricht senden

5

29.12.2013, 23:53

Danke funktioniert mit der Methode :)

David Scherfgen

Administrator

Beiträge: 10 305

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

6

30.12.2013, 00:22

Es ist überhaupt nicht gut, die Weltmatrix ständig zu verändern.
Mit der Zeit kommen da immer mehr Rundungsfehler hinein, bis dein Objekt irgendwann völlig deformiert ist.
Du kannst dein Programm ja mal ein paar Minuten laufen lassen, da dürfte sich das schon bemerkbar machen. Irgendwann hast du wahrscheinlich keinen Würfel mehr, sondern ein komisches Gebilde.

Speichere lieber die Rotation getrennt von der Position (Rotation als Quaternion, Position als 3D-Vektor) und berechne die Weltmatrix dann aus den beiden, wenn du sie brauchst, d.h. normalerweise 1x pro Frame.

Verändere nie die Matrix "schrittweise"!

Und über die Performance solltest du dir dabei keine Gedanken machen. Du machst dir gar keine Vorstellungen davon, wie viele Fließkommaoperationen eine moderne CPU pro Sekunde leisten kann. Viel wichtiger ist es, den CPU-Cache gut zu nutzen. Aber das ist ein fortgeschrittenes Thema.

Cranberry

Treue Seele

  • »Cranberry« ist der Autor dieses Themas

Beiträge: 312

Wohnort: Innsbruck, Tirol

  • Private Nachricht senden

7

30.12.2013, 11:20

Verändere nie die Matrix "schrittweise"!

Danke für den Tipp!
Ich habs jetzt so gelöst: Nach jeder Änderung in Position, Rotation oder Skalierung rufe ich die Funktion Mesh.Update() aus. Diese berechnet die WorldMatrix indem sie sie mit der Translations-, Rotations- und Skalierungsmatrix multipliziert.
Das funktioniert soweit auch super.
Ist das der richtige Weg oder kann ich das noch optimieren?

Nimelrian

Alter Hase

Beiträge: 1 260

Beruf: Softwareentwickler (aktuell Web/Node); Freiberuflicher Google Proxy

  • Private Nachricht senden

8

30.12.2013, 14:00

Verändere nie die Matrix "schrittweise"!

Diese berechnet die WorldMatrix indem sie sie mit der Translations-, Rotations- und Skalierungsmatrix multipliziert.
Ist das der richtige Weg oder kann ich das noch optimieren?


Du hast Davids Tipp überhaupt nicht angewandt :huh:
Du erstellst deine WM immer noch aus der WM und anderen Matrizen, du sollst die WM aber immer nur für's Rendern erstellen.
Ich bin kein UserSideGoogleProxy. Und nein, dieses Forum ist kein UserSideGoogleProxyAbstractFactorySingleton.

Sc4v

Alter Hase

Beiträge: 377

Beruf: Student

  • Private Nachricht senden

9

30.12.2013, 14:06

Diese berechnet die WorldMatrix indem sie sie mit der Translations-, Rotations- und Skalierungsmatrix multipliziert.

Mal ne Frage dazu (sry vielleicht ein klein wenig OT)

Gegeben sei ein Punkt §P§, wenn ich jetzt immer die Worldmatrix wie beschrieben berechne erreiche ich immer eine solche Transformation:

§P' = Translation * Rotation * Scale * P§

Ist das nicht eigentlich "dumm"? Dadurch kann ich sowas wie

C-/C++-Quelltext

1
2
3
node.rotate();
node.translate();
node.rotate();


gar nicht mehr ausdrücken, bzw.

§P' = Rotation1 * Translation * Rotation2 * P§

da dies doch dann werden würde zu

§P' = Rotation1 * Rotation2 * Translation * P§

oder stehe ich gar grade auf dem Schlauch?

Grüße

Cranberry

Treue Seele

  • »Cranberry« ist der Autor dieses Themas

Beiträge: 312

Wohnort: Innsbruck, Tirol

  • Private Nachricht senden

10

30.12.2013, 14:54

@Nimelrian: Das mach ich doch: Zuerst wird das Objekt verändert durch die Funktionen SetRotation(), SetPosition() und SetScale() wenn alle Transformationen abgeschlossen sind, also am Ende der Update Funktion, direkt vor der Render Funktion, wird die WorldMatrix neu berechnet.
@Sc4v: Da hast du recht. Aber sonst müsste ich die WorldMatrix eben schrittweise multiplizieren, und wie David schon sagte führt das zu Deformationen des Würfels. Habe ich den Tipp etwa falsch verstanden? :hmm:

Werbeanzeige