JLI Spieleprogrammierung Foren-Übersicht JLI Spieleprogrammierung

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

Problem: Freie Bewegung im 3D Raum

 
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Entwicklung
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Chriss
Senior JLI'ler



Anmeldedatum: 18.08.2004
Beiträge: 267

Medaillen: Keine

BeitragVerfasst am: 04.09.2006, 12:59    Titel: Problem: Freie Bewegung im 3D Raum Antworten mit Zitat

Hi zusammen,

Mein Problem dürfte für die meisten wohl ein Kinderspiel sein aber ich komme einfach nicht darauf wie ich es lösen kann.

Ich versuche eine Kameraklasse zu schreiben die es ermöglichen soll sich föllig frei im 3 Diminsionalen Raum zu bewegen. Als Vorlage habe ich die Kamerabewegung aus dem Buch "JLI Spieleprogrammierung mit c++ und DirectX9" genommen.

Ich habe versucht sie so zu erweitern das auch das Rollen in der X und Z Achse machbar sein soll.

Erstmal habe ich folgende globalen Variablen in der Klasse
CPP:
D3DXVECTOR3 Positon;
D3DXVECTOR3 Rotation;

welche die Position und die entsprechenden Rotationswinkel enthalten sollen.

Folgende Funktion soll eine Vorwärtsbewegung ausführen
CPP:
void MoveForward(float Distance)
{
   D3DXVECTOR3 ChangeForwardBackward;

   ChangeForwardBackward.x = sinf(Rotation.y) * Distance;
   ChangeForwardBackward.z = cosf(Rotation.y) * Distance;
   
   // Berechnung der y Richtung
   ChangeForwardBackward.y = sinf(Rotation.x) * Distance;

   //  Update 'Position'
   Position.x += ChangeForwardBackward.x;
   Position.y += ChangeForwardBackward.y;
   Position.z += ChangeForwardBackward.z;
}

Das Rollen in Z Richtung wird dabi gar nicht berücksichtig da ich nicht weiß wie ich es mit einbauen soll. Das Rollen in Y Richtung funktioniert in der Grenze +- Pi/2 einigermaßen aber ich bewege mich hier nicht in einer Einheitskugel sondern in einem Zylinder, was sind Sinn der Sache ist.

Das zweite Problem ergibt sich daraus. Ich habe versucht auf die selbe Art den LookAt Vektor (eigentlich ja Punkt) und den Vektor Top zu berechnen.
CPP:
D3DXMATRIX ViewMatrix;

   //.. Berehnung von LookAt wie die Position oben

   // Berechnung der 'Top' Position

   // Berechnung der Blickhöhe y-z Ebende
   Top.y = cosf(m_ActualCamera->Rotation.x);
   Top.z = sinf(m_ActualCamera->Rotation.x);
   // Berechnung der blickhöhe
   Top.x = sinf(m_ActualCamera->Rotation.z);

   // Erstellt die Kameramatrix
   D3DXMatrixLookAtLH(&ViewMatrix, &D3DXVECTOR3(Position.x,Position.y,Position.z),&LookAt,&Top);

Auch die führt beim Rollen in der X Achse auserhalb der Grenze +- Pi/2 zu merkwürdigen Ergebnissen.

Als nächstes habe ich versucht die Matrix mit den DX Funktionen aufzubauen
CPP:
D3DXMATRIX ViewMatrix;
D3DXMATRIX TmpMatrix;

   // Objekt rotieren
    D3DXMATRIX RotationMatrix;
   D3DXMatrixRotationX(&RotationMatrix,Rotation.x);
   D3DXMatrixRotationY(&TmpMatrix,Rotation.y);
   // Zwischenergebnis speichern
   D3DXMatrixMultiply(&RotationMatrix,&RotationMatrix,&TmpMatrix);
   D3DXMatrixRotationZ(&TmpMatrix,Rotation.z);
   // Zwischenergebnis speichern
   D3DXMatrixMultiply(&RotationMatrix,&RotationMatrix,&TmpMatrix);

   // Objekt verschiebens verschieben
    D3DXMATRIX TransMatrix;
   D3DXMatrixTranslation(&TransMatrix,Position.x,Position.y,Position.z);

    // Matrizen multiplizieren und das Resultat in ViewMatrix speichern
    D3DXMatrixMultiply(&ViewMatrix,&RotationMatrix,&TransMatrix);

Hier funktioniert alles solange ich mich im Ursprung (0,0,0) befinde. Außerhalb bekomme ich auch sehr merkwürdige Ergebnisse. Beispielsweise habe ich mich weit von einem Objekt wegbewegt, welches sich im Ursprung befindet und bei einer linksdrehung sehe ich wie das Objekt um den Einheitskreis rotiert.

In Sachen 3D hab ich noch sehr wenig Erfahrung und ich habe bisher kein Tutorial gefunden das sich mit der Kamera wirklich beschäftigt.

Ich hoffe das mir einer von Euch meinen Fehler zeigen kann oder ein passendes Tutorial kennt.

Grüße Chriss
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: 04.09.2006, 14:05    Titel: Antworten mit Zitat

Schau dir mal Quarternations an, ist sicher eine etwas komplexere Sache doch es bietet dir genau das was du suchst.

CPP:
void Camera::SetRotation(const D3DXQUATERNION& Rot)
{
   if (m_Rotation == Rot)
      return;

   m_Rotation = Rot;

   // generate direction
   D3DXMATRIX lMatrix;
   ::D3DXMatrixRotationQuaternion(&lMatrix, &m_Rotation);

   m_Direction = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
   m_UpDirection = D3DXVECTOR3(0.0f, 1.0f, 0.0f);

   D3DXVECTOR4 lTempVector;
   ::D3DXVec3Transform(&lTempVector, &m_Direction, &lMatrix);
   m_Direction.x = lTempVector.x;
   m_Direction.y = lTempVector.y;
   m_Direction.z = lTempVector.z;

   ::D3DXVec3Transform(&lTempVector, &m_UpDirection, &lMatrix);
   m_UpDirection.x = lTempVector.x;
   m_UpDirection.y = lTempVector.y;
   m_UpDirection.z = lTempVector.z;
}


CPP:
void Camera::MoveForward(float Distance)
{
   //  Update 'Position'
   Position += m_Direction * Distance
}


Rotieren kannst du deine Cam dann einfach so:

CPP:
myCam->SetRotation(D3DXQUATERNION(0.0f, 0.0f, 0.0f, 1.0f));


Das wäre dann die Ausrichtung in die positive ZAchse.

Die Werte die 0.0f sind was genau die bedeuten solltest du selber herausfinden können.
_________________
"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
Chriss
Senior JLI'ler



Anmeldedatum: 18.08.2004
Beiträge: 267

Medaillen: Keine

BeitragVerfasst am: 06.09.2006, 08:32    Titel: Antworten mit Zitat

Hi Fallen

erstmal danke für die Antwort.

Ich habe jetzt schon einiges über Quaternions gelesen und obwohl ich den Mathematischen Teil noch nicht so ganz verstehe sind sie sehr interessant.

Dabei bin ich auch die Funktion 'D3DXQuaternionRotationYawPitchRoll' gestossen.

ich habe die Funktion von dir genommen und das Quaternion 'Rot' mit dieser Funktion erzeugt.

CPP:
void Camera::SetRotation(const float &x,const float &y,const float &z)
{
   D3DXQUATERNION Rot(0.0f,0.0f,0.0f,1.0f);

   D3DXQuaternionRotationYawPitchRoll(&Rot,y,x,z);

   if (m_Rotation == Rot)
      return;

   m_Rotation = Rot;

   // generate direction
   D3DXMATRIX lMatrix;
   ::D3DXMatrixRotationQuaternion(&lMatrix, &m_Rotation);

   m_Direction = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
   m_UpDirection = D3DXVECTOR3(0.0f, 1.0f, 0.0f);

   D3DXVECTOR4 lTempVector;
   ::D3DXVec3Transform(&lTempVector, &m_Direction, &lMatrix);
   m_Direction.x = lTempVector.x;
   m_Direction.y = lTempVector.y;
   m_Direction.z = lTempVector.z;

   ::D3DXVec3Transform(&lTempVector, &m_UpDirection, &lMatrix);
   m_UpDirection.x = lTempVector.x;
   m_UpDirection.y = lTempVector.y;
   m_UpDirection.z = lTempVector.z;
}


Die Kamera aktualisiere ich mit folgender Funktion
CPP:
D3DXVECTOR3 LookAt( m_Position.x + m_Direction.x,
                  m_Position.y + m_Direction.y,
                  m_Position.z + m_Direction.z);

   D3DXVECTOR3 Top(m_Position.x + m_UpDirection.x,
               m_Position.y + m_UpDirection.y,
               m_Position.z + m_UpDirection.z);

   // Erstellt die Grundkamera
   D3DXMatrixLookAtLH(&m_ViewMatrix,
                  &m_Position,
                  &LookAt,
                  &Top);

   m_lpD3DDevice->SetTransform(D3DTS_VIEW,&m_ViewMatrix);

m_ViewMatrix ist eine globale Variable

Wenn ich jetzt um die y Achse Drehen will verändere ich eine float variable um +-0.01f´und rufe die beiden Funktionen in dieser Reihenfolge auf. Als ergebnis sehe ich mein fixes Objek, welches sich im Mittelpunkt (0,0,0) befindet, sich wie auf einem umgedrehten U bewegen obwohl sich die kamera drehen sollte.

Bewege ich mich jedoch nur vor und zurück (ohne Rotation), dann stimmt soweit alles.

Da die Quaternions Normalisierd sein müssen habe ich die Funktion 'D3DXQuaternionNormalize' eingebaut, was aber leider keine Änderung ergab.

Habe ich da etwas elementares falsch verstanden?

Grüße
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Chriss
Senior JLI'ler



Anmeldedatum: 18.08.2004
Beiträge: 267

Medaillen: Keine

BeitragVerfasst am: 06.09.2006, 08:51    Titel: Antworten mit Zitat

Also bei CodeGuru hab ich eine andere Möglichkeit gefunden die Viewmatrix zu erstellen

CPP:
// 1) Build a new view matrix

   // 1.1) First calcuate Translation
   D3DXMATRIX matTranslation;

   D3DXMatrixTranslation(  &matTranslation ,
                            -m_Position.x ,
                            -m_Position.y ,
                            -m_Position.z );

   // 1.2) Now calculate rotation, by taking the conjucate of the
   // quaternion
   D3DXMATRIX matRotation;
   D3DXMatrixRotationQuaternion( &matRotation,
                                 &D3DXQUATERNION( -m_Rotation.x ,
                                                  -m_Rotation.y ,
                                                  -m_Rotation.z ,
                                                   m_Rotation.w ));

   // 2) Apply rotation & translation matrix at view matrix
   D3DXMatrixMultiply(&m_ViewMatrix , &matTranslation , &matRotation );


so ist zumindest die bewegung in der X-Z Ebene gut möglich.

Rollen führt jedoch zu anderen komischen Ergebnissen Sad
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: 06.09.2006, 09:13    Titel: Antworten mit Zitat

Sry hab deinen vorherigen Post gar nicht bemerkt.
CPP:
D3DXVECTOR3 Top(m_Position.x + m_UpDirection.x,
               m_Position.y + m_UpDirection.y,
               m_Position.z + m_UpDirection.z);


Ist völlig unnötig, nutze einfach m_UpDirection, du brauchst die Position nicht zu addieren.


CPP:
::D3DXMatrixPerspectiveFovLH(&ProjectionMatrix, D3DXToRadian(Fov), Aspect, NearClip, FarClip);
::D3DXMatrixLookAtLH(&ViewMatrix, &Position, &(Direction + Position), &UpDirection);


Aspect ist meist 1.0f
_________________
"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
Christian Rousselle
Site Admin


Alter: 48
Anmeldedatum: 19.07.2002
Beiträge: 1630

Medaillen: Keine

BeitragVerfasst am: 06.09.2006, 09:33    Titel: Antworten mit Zitat

Fallen hat Folgendes geschrieben:


Aspect ist meist 1.0f


Aspect ist das Verhältnis von Breite zu Höhe des Backbuffers, also eher selten 1.0f, sondern eher 4:3 (1,33...) oder 16:9 (1,77...) . Am besten die tatsächlichen Werte verwenden.

C.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Chriss
Senior JLI'ler



Anmeldedatum: 18.08.2004
Beiträge: 267

Medaillen: Keine

BeitragVerfasst am: 06.09.2006, 09:51    Titel: Antworten mit Zitat

Christian Rousselle hat Folgendes geschrieben:
Fallen hat Folgendes geschrieben:


Aspect ist meist 1.0f


Aspect ist das Verhältnis von Breite zu Höhe des Backbuffers, also eher selten 1.0f, sondern eher 4:3 (1,33...) oder 16:9 (1,77...) . Am besten die tatsächlichen Werte verwenden.

C.


Ich vermute Fallen rendert mehr auf Texturen als auf den Backbuffer, denn die sind ja meistens quadratisch.

Wie auch immer, danke für die schnellen Antworten.

Bis auf die Drehung der X Achse geht jetzt alles. Dort jedoch habe ich einen komischen Fehler. Ich beobachte eine Dreheng ähnlich die der Z-Achse, jedoch mit dem Unterschied, dass sich mein Objekt nicht im Zentrum Dreht sondern als würde es sich auf dem Einheitskreis bewegen. Die restlichen Drehungen stimmen alle und die Vor-/Zurückbewegung stimmt auch.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Entwicklung 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