00001
00002
00003
00004
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
00036
00037 collisionpairs->sort();
00038
00039
00040 collisionpairs->unique();
00041
00042
00043 int pairnumber = collisionpairs->size();
00044
00045 int objnumber = objects->size();
00046
00047
00048 int *pair = new int[pairnumber] - 1;
00049 for(int i=1; i<=pairnumber; i++)
00050 pair[i] = i;
00051
00052
00053
00054 list<Collisionspair>::iterator it;
00055 for(int i=1; i<=pairnumber; i++) {
00056
00057
00058 it=collisionpairs->begin();
00059 for(int j=1; j<i; j++)
00060 it++;
00061
00062
00063 int obj1 = it->i;
00064 int obj2 = it->j;
00065
00066
00067
00068 it++;
00069 int counter = i+1;
00070 while(it != collisionpairs->end()) {
00071
00072
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
00082 list<Object*> newobjects;
00083 objectList::iterator it2;
00084 Object *obj=NULL, *obj2=NULL, *objmaxmass=NULL;
00085
00086
00087
00088 bool *used = new bool[objnumber]-1;
00089
00090
00091 for(int i=1; i<=objnumber; i++)
00092 used[i]=false;
00093
00094 for(int i=1; i<=pairnumber; i++) {
00095
00096
00097 if(pair[i] == 0)
00098 continue;
00099
00100
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
00110 bool changeRef = false;
00111
00112 for(int j=i; j<=pairnumber; j++) {
00113
00114
00115 if(pair[i] != pair[j])
00116 continue;
00117 if(j>i)
00118
00119 pair[j] = 0;
00120
00121
00122 it=collisionpairs->begin();
00123 for(int z=1; z<j; z++)
00124 it++;
00125
00126 if(! used[it->i]) {
00127
00128 it2=objects->begin();
00129 for(int z=1; z<(it->i); z++)
00130 it2++;
00131
00132 obj = *it2;
00133
00134
00135
00136 if(obj == ourConfiguration.clickedObject)
00137 changeRef = true;
00138
00139
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
00146
00147 if(obj->mass > maxmass) {
00148 maxmass = obj->mass;
00149 objmaxmass = obj;
00150 }
00151 used[it->i] = true;
00152 }
00153
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
00161
00162 if(obj2 == ourConfiguration.clickedObject)
00163 changeRef = true;
00164
00165
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
00172
00173 if(obj2->mass > maxmass) {
00174 maxmass = obj2->mass;
00175 objmaxmass = obj2;
00176 }
00177
00178 used[it->j] = true;
00179 }
00180
00181
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
00195 pair[i]=0;
00196
00197
00198 newradius = pow((double)(newvol/4.0*3.0/PI),(double)(1.0/3.0));
00199
00200
00201 newv /= newmass;
00202
00203
00204 Object * obj = ourObjectManager.createFreeObject(objmaxmass->getType());
00205
00206
00207 newobjects.push_back(obj);
00208
00209
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
00218
00219 if (changeRef)
00220 ourConfiguration.clickedObject = obj;
00221 }
00222
00223
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
00230 deletelist.sort();
00231
00232
00233 deletelist.unique();
00234
00235 string colmsg = "";
00236 unsigned int counter = 1;
00237
00238 for(list<int>::iterator it3=deletelist.end();it3 != deletelist.begin(); ) {
00239 it3--;
00240
00241 it2=objects->begin();
00242 for(int z=1; z<*it3; z++)
00243 it2++;
00244
00245
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
00256 ourObjectManager.deleteObject(it2);
00257 }
00258
00259 colmsg = colmsg + " collided";
00260 Message::msg(Message::COLLISION, colmsg);
00261
00262
00263 collisionpairs->clear();
00264
00265
00266 for(list<Object*>::iterator it4=newobjects.begin();it4 != newobjects.end();
00267 it4++) {
00268 ourObjectManager.addFreeObjectToObjectList(*it4);
00269 }
00270
00271
00272 Window::reloadObjectSelector();
00273 }
00274