Hauptseite | Liste aller Namensbereiche | Klassenhierarchie | Alphabetische Liste | Datenstrukturen | Auflistung der Dateien | Datenstruktur-Elemente | Datei-Elemente

CollisionsManager.cpp

gehe zur Dokumentation dieser Datei
00001 /*
00002 Autor: $Author: kunkel $ State: $State: Exp $
00003 Datum: $Date: 2005/05/30 12:35:25 $
00004 Version: $Revision: 1.1 $
00005 */
00006 
00012 #include "config.h"
00013 #include "CollisionsManager.h"
00014 #include "ObjectManager.h"
00015 #include "Configuration.h"
00016 #include "Message.h"
00017 #include "Window.h"
00018 
00024 CollisionsManager::CollisionsManager(list<Collisionspair> *colpairs, list<Object*> *obj) {
00025     collisionpairs = colpairs;
00026     objects = obj;
00027 }
00028 
00034 void CollisionsManager::collide() {
00035     // sortiere Kollisionsliste, es werden dabei die Relationen aus der Klasse
00036     // Collisionspair verwendet
00037     collisionpairs->sort();
00038 
00039     // doppelte Paare loeschen
00040     collisionpairs->unique();
00041 
00042     // Anzahl der Kollisionspaare bestimmen
00043     int pairnumber = collisionpairs->size();
00044     // Objektanzahl bestimmen
00045     int objnumber = objects->size();
00046 
00047     // allokiere Speicher fuer pair (Verwendung: siehe unten) und initialisiere
00048     int *pair = new int[pairnumber] - 1;
00049     for(int i=1; i<=pairnumber; i++)
00050         pair[i] = i;
00051 
00052     // die folgenden for-Schleife weisst allen Paaren pair[i] den gleichen Wert
00053     // zu, wenn sie miteinander kollidieren
00054     list<Collisionspair>::iterator it;
00055     for(int i=1; i<=pairnumber; i++) {
00056 
00057         // setze Iterator auf i-tes Paar
00058         it=collisionpairs->begin();
00059         for(int j=1; j<i; j++)
00060             it++;
00061 
00062         // speichere Objektnummern des i-ten Paares
00063         int obj1 = it->i;
00064         int obj2 = it->j;
00065 
00066         // da die Kollisionspaare geordnet sind, reicht es aus nur die
00067         // groesseren Paare zu betrachten
00068         it++;
00069         int counter = i+1;
00070         while(it != collisionpairs->end()) {
00071             // wenn ein Objekt der beiden Paare gleich, dann bekommt das
00072             // groessere Paar den gleichen Wert wie das kleinere Paar
00073             if(obj1 == it->i || obj1 == it->j || obj2 == it->i || obj2 == it->j) {
00074                 pair[counter] = pair[i];
00075             }
00076             it++;
00077             counter++;
00078         }
00079     }
00080 
00081     // Liste fuer neue Objekte
00082     list<Object*> newobjects;
00083     objectList::iterator it2;
00084     Object *obj=NULL, *obj2=NULL, *objmaxmass=NULL;
00085 
00086     // used wird verwendet, um sich zu merken, welches Objekt schon zu
00087     // Kollisionen herangezogen wurde (siehe unten)
00088     bool *used = new bool[objnumber]-1;
00089 
00090     // initialisiere used
00091     for(int i=1; i<=objnumber; i++)
00092         used[i]=false;
00093 
00094     for(int i=1; i<=pairnumber; i++) {
00095 
00096         // tue nicht wenn pair[i] schon verwendet wurde
00097         if(pair[i] == 0)
00098             continue;
00099 
00100         // Variablen fuer neue Daten
00101         Vector newpos(0.0,0.0,0.0);
00102         Vector zeros(0.0,0.0,0.0);
00103         Vector newv(0.0,0.0,0.0);
00104         double newradius=0.0;
00105         double newmass=0.0;
00106         double newvol=0.0;
00107         double maxmass=0.0;
00108 
00109         // initialisiere changeRef
00110         bool changeRef = false;
00111 
00112         for(int j=i; j<=pairnumber; j++) {
00113             // haben zwei Paare in pair[i] nicht den gleichen Wert, so muessen
00114             // sie nicht kollidiert werden
00115             if(pair[i] != pair[j])
00116                 continue;
00117             if(j>i)
00118                 // setze pair[j] auf 0, so dass es nicht mehr verwendet wird
00119                 pair[j] = 0;
00120 
00121             // setze Iterator 1 auf j-tes Paar
00122             it=collisionpairs->begin();
00123             for(int z=1; z<j; z++)
00124                 it++;
00125 
00126             if(! used[it->i]) {
00127                 // setze Iterator 2 auf das Objekt i im j-ten Paar
00128                 it2=objects->begin();
00129                 for(int z=1; z<(it->i); z++)
00130                     it2++;
00131 
00132                 obj = *it2;
00133 
00134                 // falls obj das aktuell ausgewaehlte Objekt ist, setze
00135                 // changeRef auf true (siehe unten)
00136                 if(obj == ourConfiguration.clickedObject)
00137                     changeRef = true;
00138 
00139                 // berechne Daten des neuen Objekts
00140                 newv += obj->v * obj->mass;
00141                 newradius += obj->radius;
00142                 newmass += obj->mass;
00143                 newvol += cubic(obj->radius)*4.0/3.0*PI;
00144 
00145                 // anhand von objmaxmass wird spaeter der Typ des neuen Objekts
00146                 // bestimmt
00147                 if(obj->mass > maxmass) {
00148                     maxmass = obj->mass;
00149                     objmaxmass = obj;
00150                 }
00151                 used[it->i] = true;
00152             }
00153             // // setze Iterator 2 auf das j-te Objekt
00154             if(! used[it->j]) {
00155                 it2=objects->begin();
00156                 for(int z=1; z<(it->j); z++)
00157                     it2++;
00158                 obj2 = *it2;
00159 
00160                 // falls obj2 das aktuell ausgewaehlte Objekt ist, setze
00161                 // changeRef auf true (siehe unten)
00162                 if(obj2 == ourConfiguration.clickedObject)
00163                     changeRef = true;
00164 
00165                 // berechne Daten des neuen Objekts
00166                 newv += obj2->v * obj2->mass;
00167                 newradius += obj2->radius;
00168                 newmass += obj2->mass;
00169                 newvol += cubic(obj2->radius)*4.0/3.0*PI;
00170 
00171                 // anhand von objmaxmass wird spaeter der Typ des neuen Objekts
00172                 // bestimmt
00173                 if(obj2->mass > maxmass) {
00174                     maxmass = obj2->mass;
00175                     objmaxmass = obj2;
00176                 }
00177 
00178                 used[it->j] = true;
00179             }
00180             // berechne die neue Position: es wird hier ein gewichteter
00181             // Mittelwert des euklidischen Abstandes verwendet
00182             if(newpos == zeros) {
00183                 newpos = (obj->pos - obj2->pos)* (obj->mass) /
00184                          (obj->mass+obj2->mass) + obj2->pos;
00185             } else {
00186                 double massObj12=(obj->mass+obj2->mass);
00187                 newpos = (((obj->pos - obj2->pos)* (obj->mass) / massObj12  +
00188                            obj2->pos)
00189                           - newpos)*(massObj12)/(massObj12+newmass)  + newpos;
00190             }
00191 
00192         }
00193 
00194         // markiere Paar als benutzt
00195         pair[i]=0;
00196 
00197         // berechne neuen radius, abhaenig vom Volumen
00198         newradius = pow((double)(newvol/4.0*3.0/PI),(double)(1.0/3.0));
00199 
00200         // neue Geschwindigkeit noch durch Masse teilen (Impulserhaltung)
00201         newv /= newmass;
00202 
00203         // erzeuge neues Objekt, wobei der Typ duch die
00204         Object * obj = ourObjectManager.createFreeObject(objmaxmass->getType());
00205 
00206         // fuege neues Objekt in die Liste der neuen Objekte ein
00207         newobjects.push_back(obj);
00208 
00209         // aktualisiere die Daten des neuen Objekts
00210         obj->pos = newpos;
00211         obj->v = newv;
00212         obj->radius = newradius;
00213         obj->mass = newmass;
00214         obj->setTexture(objmaxmass->getTexture());
00215         obj->setName(objmaxmass->getName());
00216 
00217         // falls eins der kollisierten Objekte das ausgewaehlte war, so muss
00218         // nun das neue Objekt, das clickedObject sein
00219         if (changeRef)
00220             ourConfiguration.clickedObject = obj;
00221     }
00222 
00223     // erstelle Liste mit Nummern der Objekte, die geloescht werden muessen
00224     list<int> deletelist;
00225     for(it=collisionpairs->begin();it != collisionpairs->end(); it++) {
00226         deletelist.push_back(it->i);
00227         deletelist.push_back(it->j);
00228     }
00229     // sortiere die deletelist
00230     deletelist.sort();
00231 
00232     // loesche mehrfach vorkommende
00233     deletelist.unique();
00234 
00235     string colmsg = "";
00236     unsigned int counter = 1;
00237     // loesche Objekte, die in der deletelist stehen
00238     for(list<int>::iterator it3=deletelist.end();it3 != deletelist.begin(); ) {
00239         it3--;
00240         // setze Iterator 2
00241         it2=objects->begin();
00242         for(int z=1; z<*it3; z++)
00243             it2++;
00244 
00245         // erzeuge Kollisionsnachricht
00246         if(counter > 1) {
00247             if(counter < deletelist.size())
00248                 colmsg = colmsg + ", ";
00249             else
00250                 colmsg = colmsg + " and ";
00251         }
00252         colmsg = colmsg + (*it2)->getName();
00253         counter++;
00254 
00255         // loesche die Objekte entgueltig
00256         ourObjectManager.deleteObject(it2);
00257     }
00258     // stelle Kollisionsnachricht fertig und gebe sie an Message weiter
00259     colmsg = colmsg + " collided";
00260     Message::msg(Message::COLLISION, colmsg);
00261 
00262     // loesche Liste der Kollisionspaare
00263     collisionpairs->clear();
00264 
00265     // fuege die neuen Objekte in die Objektliste ein
00266     for(list<Object*>::iterator it4=newobjects.begin();it4 != newobjects.end();
00267             it4++) {
00268         ourObjectManager.addFreeObjectToObjectList(*it4);
00269     }
00270 
00271     // aktualisiere Objektselektion
00272     Window::reloadObjectSelector();
00273 }
00274 

Erzeugt am Mon May 30 14:31:15 2005 für Sunsystembuildingandsimulation von doxygen 1.3.6