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

22.04.2008, 12:13

objektzentrierte Rotation

Eine Frage an die Mathe-Spezialisten:

In meiner Anwendung muss ich ein Objekt um alle drei Raumachsen rotieren. Kein Problem soweit, dank Scherfgen-Buch "3D-Spieleprogrammierung" ;-)
Allerdings ist es aus bestimmten Gründen hier nicht möglich, die Rotation relativ zur vorherigen Lage des Objekts durchzuführen es muss also jeweils aus der Normallage der Achsen rotiert werden. Habe dazu bereits diverse Quellen zu Euler, Gimbal Lock, Quaternion etc. gelesen, jedoch scheint das für diese Anforderung nicht die Lösung zu sein.
Die im Scherfgen-Buch (3. Aufl., Seite 569) zitierte TriBase-Funktion tbObject::RotateRel() ist schon "fast" geeignet. Ich rotiere also erst aus der Normallage um die X-Achse, was die Lage der anderen Achsen beeinflusst. Also werden die Y- und Z-Achsen entsprechsend transformiert, bevor um die Y-Achse rotiert wird und so weiter. Das Problem gegenüber dem Ansatz, relativ zur vorherigen Lage des Objekts zu rotieren, aus der ja noch sinnvolle Vektoren für Y- und Z-Achse vorhanden sind: Die Rotation um eine der Achsen (in diesem Fall X) geht von der Lage tbVector3(1, 0, 0) für die X-Achse aus, die der tatsächlichen objektbezogenen Lage, die sich erst bei den weiteren Transformationen ergibt, natürlich nicht entspricht.
Gibt es dafür einen sinnvollen und effizienten Lösungsansatz?

Hier noch der an tbObject::RotateRel() angelehnte Code, den ich derzeit verwende und der die X-Rotation so natürlich immer absolut statt objektbezogen handhabt (ich weiss, da gibt es noch Optimierungsmöglichkeiten):

Zitat

// Rotation um die x-Achse des Objekts
tbVector3 vXAxis(1.0f, 0.0f, 0.0f);
// hier liegt das problem: tatsächliche objektbezogene lage der x-achse ist ja noch nicht bekannt
tbMatrix mRotationRel(tbMatrixRotationAxis(vXAxis, m_vR3D_Rotation.x));
tbVector3 vYAxis = tbVector3TransformNormal(tbVector3(0.0f, 1.0f, 0.0f), mRotationRel);
tbVector3 vZAxis = tbVector3Cross(vXAxis, vYAxis);

// Rotation um die y-Achse des Objekts
mRotationRel = tbMatrixRotationAxis(vYAxis, m_vR3D_Rotation.y);
vXAxis = tbVector3TransformNormal(vXAxis, mRotationRel);
vZAxis = tbVector3Cross(vXAxis, vYAxis);

// Rotation um die z-Achse des Objekts
mRotationRel = tbMatrixRotationAxis(vZAxis, m_vR3D_Rotation.z);
vXAxis = tbVector3TransformNormal(vXAxis, mRotationRel);
vYAxis = tbVector3TransformNormal(vYAxis, mRotationRel);

tbMatrix mRotation(tbMatrixAxes(vXAxis, vYAxis, vZAxis));


Thx, bin sehr gespannt
Roberto

2

22.04.2008, 12:27

Hab zwar nicht ganz kapiert, wo dein Problem genau liegt, aber hast du dir die DirectX-Funktionen für Rotationen (D3DXMatrixRotationQuaternion, D3DXMatrixRotationAxis, D3DXMatrixRotationYawPitchRoll usw.) mal angeschaut bzw. ausprobiert?

3

22.04.2008, 13:06

Das Problem liegt darin, dass so wie es nun läuft:

- das Objekt bei Veränderungen des Winkels für Y (in meinem Beispiel m_vR3D_Rotation.y) um seine objektbezogene Y-Achse rotiert -> korrekt
- das Objekt bei Veränderungen des Winkels für Z um seine objektbezogene Z-Achse rotiert -> korrekt
- das Objekt bei Veränderungen des Winkels für X um die absolute oder kamerabezogene X-Achse (1, 0, 0) rotiert -> falsch

Danke für den Hinweis auf D3DX. Es löst das Problem aber nicht. In meinem folgenden Versuch ist der Fehler lediglich auf die Y-Achse verlagert worden:

Zitat

D3DXQUATERNION quat;
D3DXMATRIX mat;

D3DXQuaternionRotationYawPitchRoll(&quat, m_vR3D_Rotation.y, m_vR3D_Rotation.x, m_vR3D_Rotation.z);
D3DXMatrixRotationQuaternion(&mat, &quat);


Anders formuliert ist die Schwierigkeit also, dass sich die notwendige Transformation der ersten Achse erst aus der Transformation der beiden anderen ergibt. Da deren Transformation ja wieder durch die der ersten beeinflusst wird, ist das Problem zyklischer Natur. Ich bin sicher, dass es da eine Lösung gibt. Aber mehr habe ich leider noch nicht zu bieten... weitere Vorschläge sind also willkommen, Danke!

MfG
Roberto

4

22.04.2008, 13:22

Um was für ein Objekt handelt es sich denn überhaupt?
Vielleicht hilft das mir/uns etwas mehr auf die Sprünge ... ;)

5

22.04.2008, 14:12

Es handelt sich zunächst um ein schlichtes Dreieck.
Man kann das Problem natürlich auf einen Punkt reduziert betrachten, aber am Dreieck kann man das besser visuell veranschaulichen.

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

6

22.04.2008, 17:16

Nochmal ein paar Verständnisfrage:

-Relativ zu was, willst du dein Objekt rotieren? Relativ zum absoluten Koordinatensystem oder relativ zum Objektkoordinatensystem?

-Ich gehe mal vom 2. Fall aus und frage mich:

Zitat

llerdings ist es aus bestimmten Gründen hier nicht möglich, die Rotation relativ zur vorherigen Lage des Objekts durchzuführen es muss also jeweils aus der Normallage der Achsen rotiert werden.

Was sind die Gründe dafür?
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

tnecniv

Treue Seele

Beiträge: 164

Wohnort: BERLIN

  • Private Nachricht senden

7

22.04.2008, 17:19

Was heißt denn für dich "objektbezogene Lage"?
und wie willst du einen Punkt rotieren lassen? dafür bräuchtest du ja noch einen bezugspunkt... bisschen verworren, deine fragestellung... :?
Sagt der igel zu dem dachs:
willst du größer sein, dann wachs!
- alte Fritz weisheit

8

22.04.2008, 18:40

@Nox: Relativ zum Objektkoordinatensystem (siehe Betreff).
Der Grund ist:
Es werden in einem Editor bestimmte Bewegungspfade von Objekten über einen Zeitverlauf vordefiniert. Man muss jederzeit den Zustand (die Lage der Objekte) für jeden beliebigen Zeitpunkt herstellen können, ohne vorher eine u.U. sehr lange Vorgeschichte durchzurechnen. Außerdem sind in dem System durch Rundungsfehler akkumulierte Abweichungen nicht tolerierbar.
Der Zustand der Szene ist also über bestimmte, z.T. nicht kontinuierliche Funktionen für einen bestimmten Zeitpunkt definiert, die von einer Host-Anwendung per Netzwerk an den Renderer übertragen werden. Die Aufgabe heisst nun: Stelle ein bestimmtes Objekt dar (z.B. Dreieck), und zwar bezogen auf einen Punkt seines Koordinatensystems um die Werte x, y und z gedreht. Und da liegt das Problem.

@tnecniv: Selbstverständlich kann ich die Koordinaten eines Punktes nur entsprechend transformieren, wenn es einen Bezugspunkt gibt, nämlich das Rotationszentrum. Und das ist in diesem Fall im Objektkoordinatensystem definiert ist. Ob ich nun drei Punkte oder einen transformiere, macht ja keinen prinzipiellen Unterschied. Mein Betreff war wohl doch nicht so eindeutig wie ich dachte...;-)

Gruß
Roberto

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

9

22.04.2008, 21:44

Tja. Also du willst:
-ein Objekt in sein eigenes Koordinatensystem rotieren lassen (welche bereits durch vorherige Schritte bel. transformiert ist)?
-ohne dabei die vorhergegangenen Schritte durchzurechnen (da sich Rundungsfehler akkumulieren)?

Weil wenn du den vorherigen Zustand kennst (Transformationsmatrixe oder Achsen) und verwenden würdest, wäre eine einfache Matrixenmultiplikation die simpelste Lösung. Natürlich müsste RelRot dafür korrekt funktionieren. Ich kann morgen mal in meinen Dateien kramen, weil ich ein ähnliches Problem mal hatte. Ggf. hilft auch die Forensuchfunktion weiter.
ALLERDINGS NUR wenn die beiden oberen Fragen mit einem NEIN beantwortet werden können.
Wobei diese Aussagen nur auf Basis meines bescheidenen Wissen fundiert sind (also kein Gewehr ;) )
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

10

23.04.2008, 00:38

Hallo Nox,

die erste Frage kann ich mit "nein" beantworten: Die Rotationswinkel für x, y, und z, die mein Renderer erhält, sind immer absolut, beziehen sich also auf das objekt in "Normallage", untransformiert.
Dadurch erübrigt sich die zweite Frage ja eigentlich, es gibt in dem System keine vorangegangenen Schritte, sondern zu jedem Zeitpunkt nur eine absolute Angabe der Rotation des Objekts in Form von drei Rotationswinkeln (und neben der Rotation natürlich auch eine Position in Form eines 3D-Vektors, ist hier aber irrelevant).
Es handelt sich nicht um ein Computerspiel, deshalb ist dieser Ansatz für Spieleentwickler vielleicht schwer nachvollziehbar. In einem Spiel hieße eine vergleichbare Aufgabe vermutlich: Stelle die initiale Lage eines vorher modellierten Objekts zum Start des Spiels ein. Je nachdem, in welcher Reihenfolge die vorgegebene X-, Y- und Z-Rotation durchgeführt werden, kommt wegen der Repräsentation der Rotation durch Euler-Winkel immer eine andere Lage des Objekts heraus.
Habe inzwischen einen Haufen guter Beiträge hier und in anderen Foren gelesen, und habe dabei gelernt: Vermeiden lässt sich die gegenseitige Beeinflussung der Achsen und damit das Problem der Reihenfolge sowie das Auftreten von Gimbal Lock nur, wenn von vornherein die Definition der Rotation durch Quaternions statt durch drei Rotationswinkel erfolgt. Das kann man dem Anwender aber leider nicht zumuten, da es - vorsichtig ausgedrückt - sehr wenig intuitiv ist. Professionelle Animationssysteme wie Maya, 3Ds Max etc. bieten daher beide Möglichkeiten (Winkel oder Quaternion) zur Animation an. Eine nachträgliche Erstellung eines Quaternions auf Basis der drei Euler-Winkel bringt entgegen der häufig geäußerten Ansicht keinerlei Abhilfe, da auch dafür zunächst die Winkel in einer definierten Reihenfolge verarbeitet werden, man das Problem also schon bei der Umrechnung von Euler-Winkeln in das Quaternion manifestiert. Ich werde also mit dem Nachteil, die Rotation des Objekts nicht unabhängig für jede (objektbezogene) Achse einfach einstellen zu können, leben müssen, denn es liegt in der Natur der Definition einer Objekt-Rotation durch drei Winkel.

Interessante Quellen hierzu sind übrigens u.a.:
http://www.gamasutra.com/features/19980703/quaternions_01.htm
http://www.gamedev.net/reference/articles/article1095.asp
http://www.anticz.com/eularqua.htm
http://www.fho-emden.de/~hoffmann/gimbal09082002.pdf

Danke für Deine Bemühungen und die der anderen!
Roberto

Werbeanzeige