Zum Inhalt springen

Irrlicht - from Noob to Pro: CWuerfel Code

Aus Wikibooks
//Einbinden der Header-Datei von Irrlicht
#include <Irrlicht.h>
//Einbinden der Headerdatei der Würfel-Klasse
#include "CWuerfel.h"

//Einbinden der Namespaces
using namespace irr;
using namespace core;
using namespace video;

//!Der Konstruktor für die Würfel - Klasse
CWuerfel::CWuerfel(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id)
		: scene::ISceneNode(parent, mgr, id)
{
	mat.Wireframe = false; //Kein Wireframe
	mat.Lighting = false;  //Keine Lichtberechnung	
	this->fWinkel = 0.0f;  //Winkel auf 0 Grad stellen

	this->SetSize(0.6f, 0.6f, 0.6f); //Die Größe angeben
	this->Create_Indicies();         //Indicies-Array erstellen
}

//!Setzt die Größe des Würfels auf die angegebenen Werte
void CWuerfel::SetSize(f32 fWidth, f32 fHeight, f32 fDepth)
{
	cwWidth = fWidth;	//Speichern der Werte ...
	cwHeight = fHeight;	//in den Variablen ...
	cwDepth = fDepth;       //der Klasse
	Create_Vertices();	//Erstellen der Vertexdaten
	Create_BoundingBox();   //Erstellen der Bounding-Box
}

//!Gibt uns einen Debug-String des Würfels zurück
stringw CWuerfel::GetDebugString()
{
		//Den Debug-String erstellen
		stringw str("fMaxRechts : "); str += this->fMaxRechts;
		str += L"\nfMaxLinks : "; str += this->fMaxLinks;
		str += L"\nfMaxOben : "; str += this->fMaxOben;
		str += L"\nfMaxUnten : "; str += this->fMaxUnten;
		str += L"\nfMaxVorne : "; str += this->fMaxVorne;
		str += L"\nfMaxHinten : "; str += this->fMaxHinten;
		str += L"\ncwWidth : "; str += this->cwWidth;
		str += L"\ncwHeight : "; str += this->cwHeight;
		str += L"\ncwDepth : "; str += this->cwDepth;
		str += L"\nfWinkel : "; str += this->fWinkel;
		str += L"\nuAktuelleZeit : "; str += this->uAktuelleZeit;
		return str; //Rückgabe aus der Funktion
}

//!Erstellt das globale Indicies-Array
void CWuerfel::Create_Indicies()
{
//Zuerst als lokales Array definieren ....
u16 ind[36] = {0, 1, 2, //A->B->C=Dreieck1 (Vorderseite)
	       2, 1, 3, //C->B->D=Dreieck2 (Vorderseite)
	       3, 6, 2, //D->G->C=Dreieck3 (Rechte Seite)
	       3, 7, 6, //D->H->G=Dreieck4 (Rechte Seite)		   
	       6, 7, 5, //G->H->F=Dreieck5 (Rückseite)
	       5, 4, 6, //F->E->G=Dreieck6 (Rückseite)
	       5, 1, 4, //F->B->E=Dreieck7 (Linke Seite)
	       4, 1, 0, //E->B->A=Dreieck8 (Linke Seite)
	       1, 5, 7, //B->F->H=Dreieck9 (Oberseite)
	       7, 3, 1, //H->D->B=Dreieck10 (Oberseite)
	       4, 0, 6, //E->A->G=Dreieck11 (Unterseite)
	       6, 0, 2};//G->A->C=Dreieck12 (Unterseite)
//... und dann ins globale Array kopieren
for (u8 i=0; i<36; i++)
		 uiIndicies[i] = ind[i];
}

//!Merkt sich den letzten Moment der Drehung des Würfels
void CWuerfel::SetTimePos(irr::u32 uiTime)
{
	this->uZuletztGestoppt = uiTime;
}

//!Übergibt die aktuelle Zeit an die Würfel-Klasse
void CWuerfel::TellCurrentTime(irr::u32 uiTime)
{
	this->uAktuelleZeit = uiTime;
}

//!Übergibt die Zeitspanne, nach der eine Drehung stattfinden soll
void CWuerfel::SetDeltaTime(irr::u32 uiDeltaTime)
{
	this->uDeltaTime = uiDeltaTime;
}

//!Dreht den Würfel nach Ablauf der Delta-Time
void CWuerfel::TurnIfDesired()
{
//Gewünschte Zeit vergangen ?
if (this->uAktuelleZeit >= (this->uZuletztGestoppt + this->uDeltaTime))
		{
			//Aktuellen Zeitmoment der Drehung speichern
			this->SetTimePos(this->uAktuelleZeit);
			//Den Winkel erhöhen
			this->fWinkel += 0.5f;
			//Nicht über 360 Grad drehen
			if (this->fWinkel > 360) this->fWinkel = 1;
		}
//Rotation ausführen
this->setRotation(core::vector3df(0,this->fWinkel,this->fWinkel));
}

//!Erstellt die Eckdaten des Würfels
void CWuerfel::Create_Vertices()
{	
	/**** Linke und rechte Grenze ****/
	/*********************************/
	//Rechter Rand
	fMaxRechts = cwWidth / 2.0f;	//z.B. 3 : 2 = 1.5
	//Linker Rand
	fMaxLinks = (fMaxRechts - cwWidth); //z.B. 3 : 2 = 1.5 - 3 = -1.5
	/**** Vordere und hintere Grenze ****/
	/************************************/
	//Hinterer Rand
	fMaxHinten = cwDepth / 2;
	//Vorderer Rand
	fMaxVorne = (fMaxHinten - cwDepth);
	/**** Obere und untere Grenze ****/
	/*********************************/
	//Oberer Rand
	fMaxOben = cwHeight / 2;
	//Unterer Rand
	fMaxUnten = fMaxOben - cwHeight;

	//Vorne
	cwVertices[0] = S3DVertex(fMaxLinks, fMaxUnten, fMaxVorne,0,0,0,SColor(255,255,0,0),0,0); //Punkt A
	cwVertices[1] = S3DVertex(fMaxLinks, fMaxOben,  fMaxVorne,0,0,0,SColor(255,0,255,0),0,0); //Punkt B
	cwVertices[2] = S3DVertex(fMaxRechts,fMaxUnten, fMaxVorne,0,0,0,SColor(255,0,0,255),0,0); //Punkt C
	cwVertices[3] = S3DVertex(fMaxRechts,fMaxOben,  fMaxVorne,0,0,0,SColor(255,0,0,255),0,0); //Punkt D
	//Hinten
	cwVertices[4] = S3DVertex(fMaxLinks, fMaxUnten, fMaxHinten,0,0,0,SColor(255,255,255,0),0,0); //Punkt E
	cwVertices[5] = S3DVertex(fMaxLinks, fMaxOben,  fMaxHinten,0,0,0,SColor(255,0,255,255),0,0); //Punkt F
	cwVertices[6] = S3DVertex(fMaxRechts,fMaxUnten, fMaxHinten,0,0,0,SColor(255,255,0,255),0,0); //Punkt G
	cwVertices[7] = S3DVertex(fMaxRechts,fMaxOben,  fMaxHinten,0,0,0,SColor(255,0,0,255),0,0);   //Punkt H	
}

//!Erstellt unsere Axis Aligned Bounding Box
void CWuerfel::Create_BoundingBox()
{
	ABox.reset(cwVertices[0].Pos); //Reset in Initialisierung auf den ersten Vertex
	for (s32 i=1; i<8; ++i) //Hinzufügen der restlichen Vertices
			ABox.addInternalPoint(cwVertices[i].Pos);
}

//!Registriert den Würfel im Szene-Manager von Irrlicht zum Rendern
void CWuerfel::OnRegisterSceneNode()
{
	if (IsVisible) //Falls sichtbar ...
		SceneManager->registerNodeForRendering(this); //zum Zeichnen registrieren
	//Aufruf des Registriervorgangs	
	ISceneNode::OnRegisterSceneNode();
}

//!Gibt unsere Bounding-Box an Irrlicht zurück
const core::aabbox3d<f32>& CWuerfel::getBoundingBox() const
{
	return ABox;
}

//!Gibt die Anzahl der von uns verwendeten Materialien zurück
u32 CWuerfel::getMaterialCount() const
{
	return 1;
}

//Gibt ein bestimmtes Material zurück
video::SMaterial& CWuerfel::getMaterial(u32 i)
{
	return mat;
}

//!Zeichnet unseren Würfel
void CWuerfel::render()
{
	//Den Treiber einholen
	video::IVideoDriver* driver = SceneManager->getVideoDriver();

	//Das Material festlegen
	driver->setMaterial(mat);	
	
	//Wir verändern hier die Weltkoordinaten ...
	driver->setTransform(ETS_WORLD, AbsoluteTransformation);    
	
	//Zeichnen des Würfels
	driver->drawIndexedTriangleList(
			&cwVertices[0],		//Zeiger auf das erste Element im Vertices-Array
			8,			//Anzahl der Elemente im Vertices-Array
			&uiIndicies[0],		//Zeiger auf das erste Element in Indicies-Array
			12);			//Anzahl der zu zeichnenden Dreiecke
}