JLI Spieleprogrammierung Foren-Übersicht JLI Spieleprogrammierung

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

[Snippet] 3D Objektklasse

 
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Tutorials
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Fallen
JLI MVP
JLI MVP


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

BeitragVerfasst am: 20.12.2006, 17:09    Titel: [Snippet] 3D Objektklasse Antworten mit Zitat

Da ich immer wieder sehe das einige leute doch grosse probleme mit der Transformation von Objekten haben habe ich mir ein wenig Zeit genommen um eine kleine 3DObjekt Klasse zusammen zu basteln.

Die Klasse bietet nur simple Dinge:
- Positionen
- Skalierungen
- Rotationen (durch Quaternationen)
- Rückgabe des Direktionsvektors, UpVektors sowie Rightvectors
- und die Rückgabe der Transformationsmatrix

Da ich gerne mit D3DX arbeite (DirectX Extensions) wird es also nötig sein sich entweder die D3DX Funktionen ersetzen zu lassen oder einfach nur die D3DX Libraries in das Projekt einzubinden:

d3dx9d.lib für Debug
d3dx9.lib für Release

-------------------

Object3D.h
CPP:
#pragma once

#include <d3dx9.h>

class Object3D
{
public:
   Object3D();
   ~Object3D();

   // object translation
   D3DXVECTOR3 get_Position() const;
   void set_Position(const D3DXVECTOR3& inValue);

   // object rotation
   D3DXQUATERNION get_Rotation() const;
   void get_Rotation(float& outYaw, float& outPitch, float& outRoll);
   void set_Rotation(float inYaw, float inPitch, float inRoll);   
   void set_Rotation(const D3DXQUATERNION& inValue);

   // usefully vectors
   D3DXVECTOR3 get_Direction() const;
   D3DXVECTOR3 get_UpDirection() const;
   D3DXVECTOR3 get_RightDirection() const;

   // object scaling
   D3DXVECTOR3 get_Scale() const;
   void set_Scale(const D3DXVECTOR3& inValue);

   // the matrix combined from translation, rotation and scaling
   D3DXMATRIXA16 get_Matrix();

protected:
   void set_InternalRotation(const D3DXQUATERNION& inValue);

   bool m_bDirty;

   D3DXMATRIXA16 m_Matrix;
   D3DXVECTOR3 m_Position;
   D3DXVECTOR3 m_Scale;
   D3DXVECTOR3 m_Direction;
   D3DXVECTOR3 m_UpDirection;
   D3DXVECTOR3 m_RightDirection;

   float m_Yaw;
   float m_Pitch;
   float m_Roll;

   D3DXQUATERNION m_RotationQuat;
};


Object3D.cpp
CPP:
#include "Object3D.h"

Object3D::Object3D()
   : m_bDirty(true)
   , m_Position(0.0f, 0.0f, 0.0f)
   , m_Scale(1.0f, 1.0f, 1.0f)
   , m_RotationQuat(0.0f, 0.0f, 0.0f, 0.0f)
   , m_Yaw(1.0f)
   , m_Pitch(1.0f)
   , m_Roll(1.0f)
{
   // set rotation here to create an valid direction set
   this->set_Rotation(0.0f, 0.0f, 0.0f);
}


Object3D::~Object3D()
{

}


D3DXVECTOR3 Object3D::get_Position() const
{
   return m_Position;
}


void Object3D::set_Position(const D3DXVECTOR3& inValue)
{
   if (m_Position!=inValue)
   {
      m_bDirty = true;
      m_Position = inValue;
   }
}


D3DXQUATERNION Object3D::get_Rotation() const
{
   return m_RotationQuat;
}


void Object3D::get_Rotation(float& outYaw, float& outPitch, float& outRoll)
{
   outYaw = m_Yaw;
   outPitch = m_Pitch;
   outRoll = m_Roll;
}


void Object3D::set_Rotation(float inYaw, float inPitch, float inRoll)
{
   if (m_Yaw!=inYaw || m_Pitch!=inPitch || m_Roll!=inRoll)
   {
      m_Yaw = inYaw;
      m_Pitch = inPitch;
      m_Roll = inRoll;

      D3DXQUATERNION quat;
      ::D3DXQuaternionRotationYawPitchRoll(&quat,
         m_Yaw,
         m_Pitch,
         m_Roll);

      this->set_InternalRotation(quat);
   }   
}


void Object3D::set_Rotation(const D3DXQUATERNION& inValue)
{
   this->set_InternalRotation(inValue);

   m_Yaw = atan(
(-2*(inValue.y*inValue.w+inValue.x*inValue.z))/
(inValue.x*inValue.x+inValue.y*inValue.y-inValue.z*inValue.z-inValue.w*inValue.w)
);
   m_Pitch = asin(
-2*(inValue.y*inValue.z-inValue.x*inValue.w)
);
   m_Roll = atan(
(-2*(inValue.x*inValue.y+inValue.z*inValue.w))/
(inValue.x*inValue.x-inValue.y*inValue.y+inValue.z*inValue.z-inValue.w*inValue.w)
);
}


D3DXVECTOR3 Object3D::get_Direction() const
{
   return m_Direction;
}


D3DXVECTOR3 Object3D::get_UpDirection() const
{
   return m_UpDirection;
}


D3DXVECTOR3 Object3D::get_RightDirection() const
{
   return m_RightDirection;
}


D3DXVECTOR3 Object3D::get_Scale() const
{
   return m_Scale;
}


void Object3D::set_Scale(const D3DXVECTOR3& inValue)
{
   if (m_Scale!=inValue)
   {
      m_bDirty = true;
      m_Scale = inValue;
   }
}


D3DXMATRIXA16 Object3D::get_Matrix()
{
   if (m_bDirty)
   {
      D3DXMATRIXA16 RotationMatrix;
      D3DXMATRIXA16 ScaleMatrix;
      D3DXMATRIXA16 TranslationMatrix;
      D3DXMATRIXA16 ComboMatrix;

      ::D3DXMatrixRotationQuaternion(&RotationMatrix, &m_RotationQuat);
      ::D3DXMatrixScaling(&ScaleMatrix, m_Scale.x, m_Scale.y, m_Scale.z);
      ::D3DXMatrixTranslation(&TranslationMatrix, m_Position.x, m_Position.y, m_Position.z);

      ::D3DXMatrixMultiply(&ComboMatrix, &RotationMatrix, &TranslationMatrix);
      ::D3DXMatrixMultiply(&m_Matrix, &ScaleMatrix, &ComboMatrix);

      m_bDirty = false;
   }
   return m_Matrix;
}


void Object3D::set_InternalRotation(const D3DXQUATERNION& inValue)
{
   if (m_RotationQuat!=inValue)
   {
      m_bDirty = true;
      m_RotationQuat = inValue;

      // generate direction set
      D3DXMATRIX mat;
      ::D3DXMatrixRotationQuaternion(&mat, &m_RotationQuat);

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

      ::D3DXVec3TransformCoord(&m_Direction, &m_Direction, &mat);
      ::D3DXVec3TransformCoord(&m_UpDirection, &m_UpDirection, &mat);
      ::D3DXVec3TransformCoord(&m_RightDirection, &m_RightDirection, &mat);
   }
}



Sollten jemanden Probleme auffallen, bitte sagt mir bescheid. Die Berechnung der 3 Euler Rotationen könnte meines Wissens nach Fehlerbehaftet sein, diverse Quellen waren nämlich der Meinung dafür immer wieder verschiedene Berechnungen haben zu müssen.

Sollte es anderwertige fragen geben oder kommentare, immer rein damit in diesen Thread.

mfg Mark
_________________
"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
David
Super JLI'ler


Alter: 33
Anmeldedatum: 13.10.2005
Beiträge: 315

Medaillen: Keine

BeitragVerfasst am: 20.12.2006, 19:52    Titel: Re: [Snippet] 3D Objektklasse Antworten mit Zitat

Nurmal so drüber geflogen:
Fallen hat Folgendes geschrieben:

Object3D.h
CPP:
#pragma once

#include <d3dx9.h>

class Object3D
{
public:
   Object3D();
   virtual ~Object3D(); // virtual, sonst könnts evtl krachen

   // object translation
   const D3DXVECTOR3& get_Position() const; // returnwert const ref
   void set_Position(const D3DXVECTOR3& inValue);

   // object rotation
   const D3DXQUATERNION& get_Rotation() const; // returnwert const ref
   void get_Rotation(float& outYaw, float& outPitch, float& outRoll) const; // const correctness
   void set_Rotation(float inYaw, float inPitch, float inRoll);   
   void set_Rotation(const D3DXQUATERNION& inValue);

   // usefully vectors
   const D3DXVECTOR3& get_Direction() const; // ret const ref
   const D3DXVECTOR3& get_UpDirection() const; // ret const ref
   const D3DXVECTOR3& get_RightDirection() const; // ret const ref

   // object scaling
   const D3DXVECTOR3& get_Scale() const; // ret const ref
   void set_Scale(const D3DXVECTOR3& inValue);

   // the matrix combined from translation, rotation and scaling
   const D3DXMATRIXA16& get_Matrix(); // ret const ref

protected:
   void set_InternalRotation(const D3DXQUATERNION& inValue);

private: // kapselung
   bool m_bDirty;

   D3DXMATRIXA16 m_Matrix;
   D3DXVECTOR3 m_Position;
   D3DXVECTOR3 m_Scale;
   D3DXVECTOR3 m_Direction;
   D3DXVECTOR3 m_UpDirection;
   D3DXVECTOR3 m_RightDirection;

   float m_Yaw;
   float m_Pitch;
   float m_Roll;

   D3DXQUATERNION m_RotationQuat;
};


Über Programmierstile kann man sich ja bekanntlich streiten! Wink

grüße
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
DirectXer
Dark JLI'ler



Anmeldedatum: 05.02.2005
Beiträge: 1201
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 20.12.2006, 19:57    Titel: Antworten mit Zitat

@david: Was hat dieser Post mit dem Thema zu tun? Ein Programmierstil ist doch jedem selbst überlassen. Ich finde, dass man das Konzept gut aus Fallens Tut übernehmen und verstehen kann. Außerdem ist man ja nicht an seinen Stil gebunden.

btw: Was findest du denn so schlecht daran?

Gruß DXer

PS: Falls das einige falsch verstehen: Dieser Post ist weder als eine Provokation noch ein "Flame-spiel" gemeint. Smile
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
David
Super JLI'ler


Alter: 33
Anmeldedatum: 13.10.2005
Beiträge: 315

Medaillen: Keine

BeitragVerfasst am: 20.12.2006, 20:03    Titel: Antworten mit Zitat

DirectXer hat Folgendes geschrieben:
@david: Was hat dieser Post mit dem Thema zu tun? Ein Programmierstil ist doch jedem selbst überlassen. Ich finde, dass man das Konzept gut aus Fallens Tut übernehmen und verstehen kann. Außerdem ist man ja nicht an seinen Stil gebunden.

btw: Was findest du denn so schlecht daran?

Gruß DXer

PS: Falls das einige falsch verstehen: Dieser Post ist weder als eine Provokation noch ein "Flame-spiel" gemeint. Smile


Der Post hat insofern was mit dem Thema zu tun als das ich die Deklaration an einigen Stellen verändert habe. Smile Nur als Vorschlag natürlich! Und was mir an Fallens Programmierstil nicht gefällt gehört wirklich nicht hierher! Smile

Außerdem finde ich die Idee sehr gut! Vorallem weil es in letzter Zeit tatsächlich häufiger Fragen im Bezug auf das Threadthema gab.

grüße
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Fallen
JLI MVP
JLI MVP


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

BeitragVerfasst am: 20.12.2006, 22:46    Titel: Antworten mit Zitat

Ich bin eigentlich ganz froh darüber das David mir das gesagt hat, das mit dem virtual DTor zb war wirklich ein übler Fehler von mir, hab zwar mit dem Gedanken gespielt den DTor virtuell zu machen aber aus irgendeinen grund dann doch nicht gemacht.

const correctness, ja damit habe ich immer noch so meine Problemchen, beim Klassendesign denke ich noch dran, bei späteren Veränderungen übersehe ich es dann aber.

Die Rückgabe von const Referenzen, nun auch da gebe ich zu das ich es total vergessen habe, gnarr dabei sollte ich es besser wissen ^^

Zur Kapselung dann noch, tjo ich habs gerne im protected Bereich wenn ich für zukünftige Sachen damit noch einiges vor habe, allerdings ist es schon richtig so wie David es gezeigt hat, hier ist private doch ganz sauber, da ja alle Elemente auch so verarbeitet werden können dank der diversen Methoden.

Demnach bin ich also recht zufrieden mit der Kritik, auch wenn es per PM mir etwas mehr zugesagt hätte Wink

mfg Mark
_________________
"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
DirectXer
Dark JLI'ler



Anmeldedatum: 05.02.2005
Beiträge: 1201
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 20.12.2006, 23:09    Titel: Antworten mit Zitat

arg Embarassed

oh sry, ich hatte gar net gesehen, dass die Kommentare in Davids Zitat von ihm waren, um dich darauf hinzuweisen... Ich dachte er hätte einfach deinen Code zitiert und dann den Satz dazu geschrieben... Naja, manchmal hat man auch einfach ein Brett vorm Kopf Rolling Eyes Smile

Nagut, also noch ma sorry, nehmts mir net übel, hab net so viel schlaf gefunden in der letzten Zeit; Nagut, demnächst werde ich mir einen Post 3x durchlesen, bevor ich irgendwas dazu zu meckern habe Wink

Gruß DXer, geht jetz doch erstmal schlafen
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Tutorials 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