#include "Welt3D.h" #include "Zeichnung3D.h" #include "MausEreignis.h" #include "Model3D.h" #include "GraphicsApi.h" #include "DXBuffer.h" using namespace Framework; // Inhalt der Welt3D Klasse aus Welt3D.h // Konstructor Welt3D::Welt3D() { members = new RCArray< Model3D >(); pointLightCount = 0; diffuseLightCount = 0; pointLights = 0; diffuseLights = 0; ref = 1; rend = 0; } // Destruktor Welt3D::~Welt3D() { members->release(); delete[] pointLights; delete[] diffuseLights; } // Blockiert den zugriff auf das Objekt und wartet gegebenfalls auf den Zugriff void Welt3D::lock() { cs.lock(); } // Gibt das Objekt für andere Threads frei void Welt3D::unlock() { cs.unlock(); } // Fügt der Welt ein Objekt hinzu // obj: Das Objekt, was hinzugefügt werden soll void Welt3D::addZeichnung( Model3D *obj ) { cs.lock(); for( auto i = members->getIterator(); i; i++ ) { if( i == obj ) throw std::exception(); } members->add( obj ); rend = 1; cs.unlock(); } // Entfernt ein Objekt aus der Welt // obj: Das Objekt, das entwernt werden soll void Welt3D::removeZeichnung( Model3D *obj ) { cs.lock(); for( int i = 0; i < members->getEintragAnzahl(); i++ ) { if( members->z( i ) == obj ) { members->remove( i ); break; } } cs.unlock(); } // Verarbeitet ein Mausereignis // me: Das Mausereignis, das verarbeitet werden soll void Welt3D::doMausEreignis( MausEreignis3D &me ) { //cs.lock() //int anz = 0; //int index = 0; //for( Zeichnung3D **i = members; index < arraySize; i++, index++ ) //{ // if( *i ) // { // distSq[ anz ] = me.pos.abstandSq( ( *i )->getPos() ); // alphaVS[ anz ] = *i; // anz++; // } //} //index = 0; //for( Zeichnung3D **i = membersAlpha; index < arraySizeAlpha; i++, index++ ) //{ // if( *i ) // { // distSq[ anz ] = me.pos.abstandSq( ( *i )->getPos() ); // alphaVS[ anz ] = *i; // anz++; // } //} //float maxEntf; //int ind; //do //{ // maxEntf = -1; // ind = -1; // for( int i = 0; i < anz; i++ ) // { // if( !used[ i ] && distSq[ i ] > maxEntf ) // { // maxEntf = distSq[ i ]; // ind = i; // } // } // if( ind >= 0 ) // { // alphaVS[ ind ]->doMausEreignis( me ); // if( me.verarbeitet ) // { // cs.unlock(); // return; // } // used[ ind ] = 1; // } //} while( ind >= 0 ); //cs.unlock(); } // Verarbeitet die vergangene Zeit // tickval: Die zeit in sekunden, die seit dem letzten Aufruf der Funktion vergangen ist // return: true, wenn sich das Objekt verändert hat, false sonnst. bool Welt3D::tick( double tickval ) { cs.lock(); for( auto m = members->getIterator(); m; m++ ) rend |= m->tick( tickval ); cs.unlock(); bool tmp = rend; rend = 0; return tmp; } // brerechnet die Farbe eines Sichtstrahls, der von einem bestimmten punkt aus in eine bestimmte richtung schaut // point: Der ursprung des Strahls, // dir: Die Richtung des Strahls // return: Die Farbe des Strahls int Welt3D::traceRay( Vec3< float > &point, Vec3< float > &dir ) { float min = INFINITY; int minId = -1; int index = 0; int pId = 0; for( auto m = members->getIterator(); m; m++, index++ ) { float tmp = m->traceRay( point, dir, min, pId ); if( min > tmp && tmp >= 0 ) { min = tmp; minId = index; } } if( minId >= 0 ) return members->z( minId )->traceRay( point, dir, pId, this ); return 0xFF000000; } // Gibt einen Iterator zurück, mit dem alle Members aufgezählt werden können Iterator< Model3D * > Welt3D::getMembers() { return members->getIterator(); } int Framework::Welt3D::getPointLightCount() const { return pointLightCount; } int Framework::Welt3D::getDiffuseLightCount() const { return diffuseLightCount; } void Framework::Welt3D::copyLight( DXBuffer *zDiffuse, DXBuffer *zPoints ) const { zDiffuse->setData( diffuseLights ); zDiffuse->setLength( diffuseLightCount * (int)sizeof( DiffuseLight ) ); zDiffuse->copieren(); zPoints->setData( pointLights ); zPoints->setLength( pointLightCount * (int)sizeof( PointLight ) ); zPoints->copieren(); } // Erhöht den Reference Counting Zähler. // return: this. Welt3D *Welt3D::getThis() { ref++; return this; } // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht. // return: 0. Welt3D *Welt3D::release() { ref--; if( !ref ) delete this; return 0; }