JLI Spieleprogrammierung Foren-Übersicht JLI Spieleprogrammierung

 
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen 
 medals.php?sid=a3c300eb9bada6c3966fc7fd42a0d3f6Medaillen   RegistrierenRegistrieren   ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

D3D: Objekte rotieren

 
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> DirectX, OpenGL
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Chewie
Super JLI'ler



Anmeldedatum: 17.07.2003
Beiträge: 382

Medaillen: Keine

BeitragVerfasst am: 23.11.2003, 17:18    Titel: D3D: Objekte rotieren Antworten mit Zitat

Wie erreicht man es am besten, dass sich Objekte um ihre lokalen achsen drehen? In einem anderen thread wurde vorgeschlagen, die Objekte immer zurückzusetzen, um den Nullpunkt drehen und neu zu positionieren. Das scheint mir aber nicht wirklich optimal.
Viel besser gefällt mir da, sich die lokalen Rotationsachsen von jedem Objekt zu speichern, und diese für die Rotationen herzunehmen. Ich weiß nur nicht recht, wie ich das anstellen soll. Hat da jemand von euch eine Idee?

edit: also wie man ein Objekt um eine beliebige achse dreht, hab ich jetzt gecheckt: D3DXMatrixRotationAxis()...nur wie kann ich die Rotationsachsen(in 3 vektoren gespeichert) nach einer Rotation/Translation anpassen?
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
AFE-GmdG
JLI MVP
JLI MVP


Alter: 45
Anmeldedatum: 19.07.2002
Beiträge: 1374
Wohnort: Irgendwo im Universum...
Medaillen: Keine

BeitragVerfasst am: 23.11.2003, 18:26    Titel: Antworten mit Zitat

Du mußt die einzelnen Koordinatensysteme auseinanderhalten:
Es gibt das Objektkoordinatensystem, das Szenenkoordinatensystem sowie einige weitere. Rotiert werden Objekte, indem man die Objekte von einem Koordinatensystem in ein anderes Überführt. Das muß man in jedem Fall für jeden Frame machen. Dazu erstellt man eine Transformationsmatrix, die neben Verschiebung oder Skalierung auch die Rotation enthält. Somit rotiert, verschiebt und skaliert man Objekte in jedem Frame sowieso..
_________________
CPP:
float o=0.075,h=1.5,T,r,O,l,I;int _,L=80,s=3200;main(){for(;s%L||
(h-=o,T= -2),s;4 -(r=O*O)<(l=I*I)|++ _==L&&write(1,(--s%L?_<(L)?--_
%6:6:7)+\"World! \\n\",1)&&(O=I=l=_=r=0,T+=o /2))O=I*2*O+h,I=l+T-r;}
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Fallen
JLI MVP
JLI MVP


Alter: 40
Anmeldedatum: 08.03.2003
Beiträge: 2860
Wohnort: Münster
Medaillen: 1 (mehr...)

BeitragVerfasst am: 23.11.2003, 19:02    Titel: Antworten mit Zitat

Genau und diese Transfomationsmatrix für das Projekt sollte man immer nur dann neu berechnen wenn sich am Objekt etwas geändert hat (rot,scal,trans). Um rechenzeit zu sparen.

Wenn du dein Obj um die lok Achsen drehen möchtets dann erstelle zuerst eine Einheitsmatrix und wende die Matrixrotation darauf an.
_________________
"I have a Core2Quad at 3.2GHz, 4GB of RAM at 1066 and an Nvidia 8800 GTS 512 on Vista64 and this game runs like ass whereas everything else I own runs like melted butter over a smokin' hot 18 year old catholic schoolgirl's arse."
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Chewie
Super JLI'ler



Anmeldedatum: 17.07.2003
Beiträge: 382

Medaillen: Keine

BeitragVerfasst am: 27.11.2003, 19:26    Titel: Antworten mit Zitat

hatte kaum Zeit zum Posten, sorry, danke mal für eure Antworten...
@AFE:
das ist mit schon klar, es geht darum, wie ich mir am Besten die Transformtionsmatrix erstellen kann.

@FallenAngel:
Mit der Einheitsmatrix funkt das eben nicht. Oder eben nur solange das Objekt auf 0,0,0 steht. Selbst wenn ich das Objekt jedesmal zurücksetzten würde, könnte ich immer nur in einer bestimmten Reihenfolge rotieren, weil wenn ich z.B. zuerst 'pitche und dann 'rolle', ist das nicht dasselbe wie zuerst roll, dann pitch.
Kann es sein, dass dieses Problem 'gimbal lock' genannt wird? Bin jetzt schon öfter über diesen Begriff gestolpert.

Ich versuche genauer zu definieren, was ich ca. machen möchte.
NICHT um den Ursprung rotieren. Ich dachte ich lege mir für jedes Objekt 3 Vektoren an, die meine Rotationsachsen repräsentieren. vUp, vLook, vRight. Um diese Achsen rotiere ich dann und passe bei der Rotation auf einer Achse die anderen 2 Achsen automatisch an.
So soll das ca. aussehen:
Code:

// init
vUp     = (0.0, 1.0, 0.0);
vLook  = (0.0, 0.0, 1.0);
vRight = (1.0, 0.0, 0.0);

// im spiel
D3DXMatrixRotationAxis(matX, vRight, 10);
// Anpassen von vUp, vLook
D3DXMatrixRotationAxis(matY, vUp, 10);
// Anpassen von ....
D3DXMatrixRotationAxis(matZ, vLook, 10);
// Anpassen von ....

// alle Rotationsmatrizen zu einer multiplizieren
// Tranformationsmatrix berechnen
// Rotation und Translation mult.

m_lpDevice->SetTransform(D3DTS_WORLD, &newObjMatrix);


Es scheitert momentan daran, dass ich nicht weiß wie ich die Vektoren anpassen soll. Oder sollte ich es überhaupt anders machen?
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Mr.X
Junior JLI'ler



Anmeldedatum: 15.04.2003
Beiträge: 88

Medaillen: Keine

BeitragVerfasst am: 28.11.2003, 10:09    Titel: Antworten mit Zitat

Irgendwie scheint mir Du hast das Prinzip bei der ganzen Sache noch nicht ganz verstanden!
Du schreibst ständig: "...das Objekt ... zurücksetzten ..."

Denk nochmal genau über AFE's Post nach!
Du kannst immer nur um eine Achse vom Null-Punkt ausgehend rotieren!!! Demzufolge nutzen Dir absolute Koordinaten in Deiner Welt überhaupt nichts!
Du solltest Dir etwas anderes bei Deinen Positionsdatenspeicherungen einfallen lassen. Denn mir scheint so als speicherst Du immer die komplette Matrix vom letzten Frame und nutzt diese dann, um darauf die neuen Rotationen/Translationen anzuwenden. Und das geht schief!

Du solltest in jedem Frame das Objekt innerhalb seines Objektkoordinatensystems (siehe AFE's Post) Rotieren (per Einheitsmatrix als Grundeinstellung, eben das hat FallenAngel bereits geschrieben) und auf diese Matrix wendest Du dann Deine neue Translation an (welche sich aus den alten Positionskoordinaten und der neu hinzugekommenen Verschiebung zusammensetzt).

Demzufolge speicherst Du zu Deinem Objekt nicht die alte Rotations/Translationmatrix !!!, sondern lediglich die Rotationen und die Position in Deiner Welt! Und in jedem Frame rotierst Du dann das Objekt entsprechend und verschiebst es dann an die gewünschte Position. Und das hat NICHTS!!! mit "Zurücksetzen des Objektes" zu tun.

Selbst wenn das Objekt immer an der gleichen Stelle innerhalb Deiner Welt sein soll, und lediglich rotieren soll, dann musst Du trotzdem in jedem Frame das Objekt immer wieder an diese Position schieben, da Du wie schon gesagt die Rotation um die eigene Achse nur im Objektkoordinatensystem zustande bringst.


P.S. Deinen oben geposteter Code funktioniert mit Rotation eben nur um den Null-Punkt, da wenn Du um einer beliebige Achse im Raum drehen möchtest (eben nicht vom Null-Punkt aus) Du mindestens die Gleichung einer Geraden im Raum brauchst, um welche Du dann rotieren kannst. Und die enthält neben einer Variablen eben ZWEI Vektoren. Und Deine oben aufgeführte Funktion D3DXMatrixRotationAxis(..., Vektor,...); hat als Parameter nur einen Vektor!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Fallen
JLI MVP
JLI MVP


Alter: 40
Anmeldedatum: 08.03.2003
Beiträge: 2860
Wohnort: Münster
Medaillen: 1 (mehr...)

BeitragVerfasst am: 28.11.2003, 11:29    Titel: Antworten mit Zitat

Du kannst ein Objekt nicht gleichzeitig um 2 verschiedene Achsen drehen. Du musst immer eins nach dem anderen machen. Das einzige was DU machen könntest wäre eine Option einzubauen die bestimmt in welcher Reihenfolge rotiert werden soll.

Und:

Yaw=Y-Achse (bei mir nach oben/unten)
Roll=Z-Achse (bei mir nach hinten/vorn)
Pitch=X-Achse (bei mir nach links/rechts)
_________________
"I have a Core2Quad at 3.2GHz, 4GB of RAM at 1066 and an Nvidia 8800 GTS 512 on Vista64 and this game runs like ass whereas everything else I own runs like melted butter over a smokin' hot 18 year old catholic schoolgirl's arse."
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Chewie
Super JLI'ler



Anmeldedatum: 17.07.2003
Beiträge: 382

Medaillen: Keine

BeitragVerfasst am: 29.11.2003, 22:22    Titel: Antworten mit Zitat

Ok, jetzt sieht es so aus, als ob es funktionieren würde. Was habe ich falsch gemacht? Translationsmatrix mit Rotation multipliziert, und nicht umgekehrt. Dadurch hat sich das Objekt im Szenenkoordinatensystem um den Ursprung gedreht. So funkt das jetzt:
Code:

D3DXMatrixTranslation(&matPos, m_vCubePos.x, m_vCubePos.y, m_vCubePos.z);
D3DXMatrixRotationYawPitchRoll(&matRot, m_vCubeRot.y, m_vCubeRot.x, m_vCubeRot.z);
D3DXMatrixMultiply(&m_mCubeMat, &matRot, &matPos);

Ich habs nicht gecheckt, und daher der Ansatz mit den Vektoren, welchen ich immer noch nicht ganz verworfen habe. Es funktioniert nämlich an sich, nur weiß ich immer noch nicht wie ich einen Richtungsvektor durch eine Rotation verändern kann...

Der Code weiter oben war echt nur zur groben Veranschaulichung was ich eigentlich machen will...wenn ich die Vektortransformationen rausfinde, poste ich dann das funktionierende Teil.

Achja, und was hat es nun mit dem Ausdruck 'gimbal lock' auf sich? Sagt das irgendwem was?
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Mr.X
Junior JLI'ler



Anmeldedatum: 15.04.2003
Beiträge: 88

Medaillen: Keine

BeitragVerfasst am: 30.11.2003, 08:42    Titel: Antworten mit Zitat

Chewie hat Folgendes geschrieben:
...Translationsmatrix mit Rotation multipliziert, und nicht umgekehrt. ...
Code:

...D3DXMatrixMultiply(&m_mCubeMat, &matRot, &matPos);
...

Nichts für ungut, aber Du hast es doch umgekehrt gemacht! Du multiplizierst matRot * matPos! Also doch zuerst die Rotation und dann die Translation! (siehe DXDoku: ...(Out = M1 * M2))



Chewie hat Folgendes geschrieben:
...Achja, und was hat es nun mit dem Ausdruck 'gimbal lock' auf sich? Sagt das irgendwem was?...

Das passiert, wenn Du Dein Objekt zum Beispiel um 90° Grad um eine Achse drehst und danach noch eine weitere Rotation um eine weitere Achse durchführen willst. Denn bei der ersten Rotation verliert die Ergebnismatrix einen Freiheitsgrad, da cos(90°) NULL wird. Die weitere Rotation wird dann nicht Dein gewünschtes Ergebnis liefern.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Fallen
JLI MVP
JLI MVP


Alter: 40
Anmeldedatum: 08.03.2003
Beiträge: 2860
Wohnort: Münster
Medaillen: 1 (mehr...)

BeitragVerfasst am: 30.11.2003, 12:47    Titel: Antworten mit Zitat

Was meinst du mit deinen Richtungsvektoren ? Meinst du damit das du nach dem erstellen deiner Matrix den Richtungsvektor neu errechnen möchtest ? Ich glaube dazu muss man sich eine eigene Funktion schreiben.

Mit dem Richtungsvektor meinst du doch in welche Richtung dein Objekt "schaut" ?
_________________
"I have a Core2Quad at 3.2GHz, 4GB of RAM at 1066 and an Nvidia 8800 GTS 512 on Vista64 and this game runs like ass whereas everything else I own runs like melted butter over a smokin' hot 18 year old catholic schoolgirl's arse."
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Chewie
Super JLI'ler



Anmeldedatum: 17.07.2003
Beiträge: 382

Medaillen: Keine

BeitragVerfasst am: 30.11.2003, 22:45    Titel: Antworten mit Zitat

Mr.X hat Folgendes geschrieben:
Chewie hat Folgendes geschrieben:
...Translationsmatrix mit Rotation multipliziert, und nicht umgekehrt. ...
Code:

...D3DXMatrixMultiply(&m_mCubeMat, &matRot, &matPos);
...

Nichts für ungut, aber Du hast es doch umgekehrt gemacht!


Wie jetzt? Rotation * Translation, oder nicht? passt doch eh...

@FallenAngel:
Jup, das will ich machen! Ich hab jetzt die Funktion D3DXVec3TransformCoord() gefunden, bei der ich mir eigentlich dachte, dass es funktioniert, aber es haut nicht hin.

Ich versuch noch mal kurz das Problem zu erklären, dass ich mit der 'normalen' Methode habe: Angenommen man proggt einen Weltraumshooter...jetzt hat man ein Schiff, in dem sich der Spieler befindet. Der Spieler 'taucht' jetzt hinunter, rotiert um x, fliegt so eine Zeit, und will dann nach rechts schwenken, was aber nicht funktioniert, weil die y-Achse mittlerweile längs durch das Schiff durchgeht.
Dazu hab ich dann in einem Buch den Ansatz gelesen, sich für jedes Objekt ein lokales Koordinatensystem anzulegen, in Form von 3 Vektoren um welche dann rotiert wird und welche immer angepasst werden. Wenn das Objekt also irgenwie schief im Raum hängt, müssen diese 3 Vektoren das lokale Ko.-system dafür bilden.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Chewie
Super JLI'ler



Anmeldedatum: 17.07.2003
Beiträge: 382

Medaillen: Keine

BeitragVerfasst am: 01.12.2003, 00:11    Titel: Antworten mit Zitat

Hooray Exclamation Ich habs gecheckt!
Mit der Funktion kann man ein Objekt immer um sein lokales Koordinatenssystem drehen. Was ich eigentlich nicht wollte, was aber irgendwie daraus resultiert, ist, dass eine relative Rotation durchgeführt wird, also um den angegebenen Winkel weitergedreht wird...
Cool ist, das wenn man sich die Vektoren ausgerechnet hat, man sie einfach in eine Einheitsmatrix packen kann und die fertige Rotationsmatrix hat.
Code:

D3DXVECTOR3 vCubeX (1.0f, 0.0f, 0.0f);
D3DXVECTOR3 vCubeY (0.0f, 1.0f, 0.0f);
D3DXVECTOR3 vCubeZ (0.0f, 0.0f, 1.0f);


D3DXMATRIX RotateRel(D3DXVECTOR3 vCubeRot)
{
  D3DXMATRIX matRotX, matRotY, matRotZ;

  D3DXMatrixRotationAxis(&matRotX, &vCubeX, vCubeRot.x); 
  D3DXVec3TransformNormal(&vCubeY, &vCubeY, &matRotX);
  D3DXVec3TransformNormal(&vCubeZ, &vCubeZ, &matRotX);

  D3DXMatrixRotationAxis(&matRotY, &vCubeY, vCubeRot.y); 
  D3DXVec3TransformNormal(&vCubeX, &vCubeX, &matRotY);
  D3DXVec3TransformNormal(&vCubeZ, &vCubeZ, &matRotY);

  D3DXMatrixRotationAxis(&matRotZ, &vCubeZ, vCubeRot.z); 
  D3DXVec3TransformNormal(&vCubeY, &vCubeY, &matRotZ);
  D3DXVec3TransformNormal(&vCubeX, &vCubeX, &matRotZ);

  D3DXMATRIX matRot( m_vCubeX.x, m_vCubeX.y, m_vCubeX.z, 0.0f,
                           m_vCubeY.x, m_vCubeY.y, m_vCubeY.z, 0.0f,
                           m_vCubeZ.x, m_vCubeZ.y, m_vCubeZ.z, 0.0f,
                              0.0f,       0.0f,       0.0f,       1.0f );

  return matRot;
}


...jetzt muß ich nur noch rausfinden, wie ich eine absolute Rotation zustande bringe.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Fallen
JLI MVP
JLI MVP


Alter: 40
Anmeldedatum: 08.03.2003
Beiträge: 2860
Wohnort: Münster
Medaillen: 1 (mehr...)

BeitragVerfasst am: 01.12.2003, 12:34    Titel: Antworten mit Zitat

Ich hab ne Funktion dafür zu Hause werde sie dir bei Gelegenheit mal zeigen. Die Funktion macht genau das was du möchtest. Du brauchst nur die Rotationen pitch,yaw oder roll in radiant zu haben.
_________________
"I have a Core2Quad at 3.2GHz, 4GB of RAM at 1066 and an Nvidia 8800 GTS 512 on Vista64 and this game runs like ass whereas everything else I own runs like melted butter over a smokin' hot 18 year old catholic schoolgirl's arse."
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> DirectX, OpenGL Alle Zeiten sind GMT
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.


Powered by phpBB © 2001, 2005 phpBB Group
Deutsche Übersetzung von phpBB.de

Impressum