Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages

System.cpp

00001 /*************************************************************************** 00002 * This file is part of OpenCAL: Open Computer Animation Library * 00003 * I created OpenCAL as my master's thesis Computer Science (multimedia) * 00004 * at the tUL university in Diepenbeek, Belgium * 00005 * * 00006 * Copyright (C) 2003-2004 by Jeroen Dierckx * 00007 * jeroen.dierckx@student.luc.ac.be * 00008 * * 00009 ***************************************************************************/ 00010 00011 // Includes 00012 #include "System.h" 00013 #include <OpenCAL/Object.h> 00014 #include <OpenCAL/Actor.h> 00015 #include <OpenCAL/Agent.h> 00016 #include <OpenCAL/Renderer.h> 00017 #include <OpenCAL/Picker.h> 00018 #include <OpenCAL/ObjectIterator.h> 00019 using namespace OpenCAL; 00020 00021 #include <OpenCAL/NullParentException.h> 00022 using Exceptions::NullParentException; 00023 00024 using namespace std; 00025 00026 00027 // Macros 00028 #define forAllObjects(it)\ 00029 ObjectList::iterator it;\ 00030 for(it = m_objects.begin(); it != m_objects.end(); ++it) 00031 00032 #define forAllActors(it)\ 00033 ActorList::iterator it;\ 00034 for(it = m_actors.begin(); it != m_actors.end(); ++it) 00035 00036 #define forAllAgents(it)\ 00037 AgentList::iterator it;\ 00038 for(it = m_agents.begin(); it != m_agents.end(); ++it) 00039 00040 #define forAllSystems(it)\ 00041 SystemList::iterator it;\ 00042 for(it = m_systems.begin(); it != m_systems.end(); ++it) 00043 00044 00045 /****************************** 00046 * Constructors and destructor * 00047 ******************************/ 00048 00049 System::System(System *parent) 00050 : m_destructing(false), m_parent(parent), m_initialized(false), 00051 m_draw(true), m_enabled(true), m_accuracyHint(0.0f), 00052 m_selectedObject(0), m_renderer(0), m_picker(0) 00053 { 00054 #ifdef VERBOSE 00055 Debug::print("System constructor", 2); 00056 #endif // VERBOSE 00057 00058 /* 00059 if(!parent) 00060 throw NullParentException(__FILE__, __LINE__); 00061 */ 00062 00063 #ifdef VERBOSE 00064 Debug::print("Parent is given, adding to the the parent's system list...", 2); 00065 #endif // VERBOSE 00066 00067 if(parent) 00068 parent->addSystem(this); 00069 } 00070 00071 System::~System() 00072 { 00073 #ifdef VERBOSE 00074 Debug::print("System destructor", 2); 00075 00076 Debug::stream << "Cleaning up "; 00077 Debug::stream << m_objects.size() << " object(s), "; 00078 Debug::stream << m_actors.size() << " actor(s), "; 00079 Debug::stream << m_agents.size() << " agent(s) and "; 00080 Debug::stream << m_systems.size() << " subsystem(s)." << endl; 00081 Debug::printStream(); 00082 #endif // VERBOSE 00083 00084 m_destructing = true; 00085 00086 forAllSystems(system) 00087 delete *system; // System cannot be 0 00088 00089 forAllObjects(object) 00090 delete *object; 00091 00092 forAllActors(actor) 00093 delete *actor; 00094 00095 forAllAgents(agent) 00096 delete *agent; 00097 00098 if(m_parent) 00099 m_parent->deleteSystem(this); 00100 } 00101 00102 00103 /******************* 00104 * Render functions * 00105 *******************/ 00106 00107 void System::render() 00108 { 00109 if(!m_renderer) 00110 { 00111 cerr << "No renderer available!!" << endl; 00112 return; 00113 } 00114 00115 if(!isInitialized()) 00116 { 00117 #ifdef VERBOSE 00118 Debug::initWarning("system"); 00119 #endif // VERBOSE 00120 initialize(); 00121 } 00122 00123 forAllSystems(system) 00124 { 00125 if((*system)->getDraw()) 00126 { 00127 (*system)->setRenderer(m_renderer); 00128 (*system)->render(); 00129 } 00130 } 00131 00132 forAllActors(actor) 00133 { 00134 if((*actor)->getDraw()) 00135 (*actor)->render(); 00136 } 00137 00138 forAllObjects(object) 00139 { 00140 if((*object)->getDraw()) 00141 (*object)->render(); 00142 } 00143 } 00144 00145 00146 /***************** 00147 * Pick functions * 00148 *****************/ 00149 00150 void System::renderPicking() 00151 { 00152 unsigned int i; 00153 00154 //if(!m_draw) return; 00155 00156 if(!m_picker) 00157 { 00158 cerr << "No picker available!!" << endl; 00159 return; 00160 } 00161 00162 if(!isInitialized()) 00163 initialize(); 00164 00165 for(i = 0; i < m_systems.size(); ++i) 00166 { 00167 if(m_systems[i]->getDraw()) 00168 { 00170 m_systems[i]->setPicker(m_picker); 00171 00172 m_picker->pushName(i); 00173 m_systems[i]->renderPicking(); 00174 m_picker->popName(); 00175 } 00176 } 00177 00178 m_picker->pushName(0); 00179 for(i = 0; i < m_objects.size(); ++i) 00180 { 00181 if(m_objects[i]->getDraw()) 00182 { 00183 m_picker->loadName(i); 00184 m_objects[i]->renderPicking(); 00185 } 00186 } 00187 m_picker->popName(); 00188 } 00189 00190 Object *System::pick(int x, int y) 00191 { 00192 //if(!m_draw) return 0; 00193 00194 if(!m_picker) 00195 { 00196 cerr << "No picker available!!" << endl; 00197 return 0; 00198 } 00199 00200 if(!isInitialized()) 00201 initialize(); 00202 00203 return m_picker->pick(this, x, y); 00204 } 00205 00206 00207 /******************** 00208 * General functions * 00209 ********************/ 00210 00211 void System::initialize() 00212 { 00213 #ifdef VERBOSE 00214 Debug::print("System initialize", 2); 00215 #endif // VERBOSE 00216 00217 if(m_renderer) 00218 m_renderer->initialize(); 00219 00220 forAllSystems(system) 00221 { 00222 (*system)->setRenderer(m_renderer); 00223 (*system)->initialize(); 00224 } 00225 00226 forAllObjects(object) 00227 (*object)->initialize(); 00228 00229 forAllActors(actor) 00230 (*actor)->initialize(); 00231 00232 forAllAgents(agent) 00233 (*agent)->initialize(); 00234 00235 m_initialized = true; 00236 } 00237 00238 void System::step(float deltaSeconds) 00239 { 00240 #ifdef VERBOSE 00241 Debug::stream << "System step (" << deltaSeconds << " seconds)" << endl; 00242 Debug::printStream(Debug::maxLevel); 00243 #endif // VERBOSE 00244 00245 //if(!m_enabled) return; 00246 00247 if(!isInitialized()) 00248 { 00249 #ifdef VERBOSE 00250 Debug::initWarning("system"); 00251 #endif // VERBOSE 00252 initialize(); 00253 } 00254 00255 forAllActors(actor) 00256 { 00257 if((*actor)->isEnabled()) 00258 (*actor)->execute(deltaSeconds); 00259 } 00260 00261 forAllSystems(system) 00262 { 00263 if((*system)->isEnabled()) 00264 (*system)->step(deltaSeconds); 00265 } 00266 00267 forAllAgents(agent) 00268 { 00269 if((*agent)->isEnabled()) 00270 (*agent)->satisfy(); 00271 } 00272 } 00273 00274 /* 00275 #ifdef USE_OPENGL 00276 void System::drawGL() 00277 { 00278 #ifdef VERBOSE 00279 Debug::print("System drawGL", Debug::maxLevel); 00280 #endif // VERBOSE 00281 00282 //if(!m_draw) return; 00283 00284 if(!isInitialized()) 00285 { 00286 #ifdef VERBOSE 00287 Debug::initWarning("system"); 00288 #endif // VERBOSE 00289 initialize(); 00290 } 00291 00292 forAllSystems(system) 00293 { 00294 if((*system)->getDraw()) 00295 (*system)->drawGL(); 00296 } 00297 00298 forAllActors(actor) 00299 { 00300 if((*actor)->getDraw()) 00301 (*actor)->drawGL(); 00302 } 00303 00304 forAllObjects(object) 00305 { 00306 if((*object)->getDraw()) 00307 (*object)->drawGL(); 00308 } 00309 } 00310 00311 void System::drawPickGL() 00312 { 00313 unsigned int i; 00314 00315 //if(!m_draw) return; 00316 00317 if(!isInitialized()) 00318 initialize(); 00319 00320 for(i = 0; i < m_systems.size(); ++i) 00321 { 00322 if(m_systems[i]->getDraw()) 00323 { 00324 glPushName(i); 00325 m_systems[i]->drawPickGL(); 00326 glPopName(); 00327 } 00328 } 00329 00330 glPushName(0); 00331 for(i = 0; i < m_objects.size(); ++i) 00332 { 00333 if(m_objects[i]->getDraw()) 00334 { 00335 glLoadName(i); 00336 m_objects[i]->drawGL(); 00337 } 00338 } 00339 glPopName(); 00340 } 00341 00342 Object *System::pickGL(int x, int y) 00343 { 00344 //if(!m_draw) return 0; 00345 00346 if(!isInitialized()) 00347 initialize(); 00348 00349 GLuint selectBuffer[PICKINGSIZE]; 00350 glSelectBuffer(PICKINGSIZE, selectBuffer); 00351 00352 glRenderMode(GL_SELECT); 00353 00354 glInitNames(); 00355 //glPushName(0); 00356 00357 GLint viewport[4]; 00358 glGetIntegerv(GL_VIEWPORT, viewport); 00359 00360 GLdouble projection[16]; 00361 glGetDoublev(GL_PROJECTION_MATRIX, projection); 00362 00363 glMatrixMode(GL_PROJECTION); 00364 glPushMatrix(); 00365 00366 glLoadIdentity(); 00367 gluPickMatrix((GLdouble) x, (GLdouble) (viewport[3] - y), PICKREGION, PICKREGION, viewport); 00368 glMultMatrixd(projection); 00369 00370 00371 // Change to modelview matrix 00372 glMatrixMode(GL_MODELVIEW); 00373 00374 // Draw the objects 00375 drawPickGL(); 00376 00377 00378 glMatrixMode(GL_PROJECTION); 00379 glPopMatrix(); 00380 glFlush(); 00381 00382 glMatrixMode(GL_MODELVIEW); 00383 GLint hits = glRenderMode(GL_RENDER); 00384 if(hits < 0) 00385 cerr << "The picking buffer has overflowed!" << endl; 00386 00387 00388 // Determine which item is picked 00389 GLuint depth = 0xffffffff; 00390 // These must be constants in MSVC6 00391 vector<int> systemIndices[64]; 00392 int objectIndex[64]; 00393 int selectedIndex = -1; 00394 GLuint *ptr = (GLuint *) selectBuffer; 00395 00396 cout << "[Picking] " << hits << " hits" << endl; 00397 for(GLint i = 0; i < hits; ++i) 00398 { 00399 objectIndex[i] = -1; 00400 00401 GLuint nrNames = *ptr; ++ptr; 00402 GLuint minZ = *ptr; ++ptr; 00403 GLuint maxZ = *ptr; ++ptr; 00404 00405 cout << "[Picking] hit " << i; 00406 cout << " (minZ " << minZ << "; maxZ " << maxZ << ")"; 00407 cout << " has " << nrNames << " names: "; 00408 00409 if(minZ < depth) 00410 { 00411 depth = minZ; 00412 selectedIndex = i; 00413 } 00414 00415 for(GLuint j = 0; j < nrNames; ++j) 00416 { 00417 cout << *ptr << " "; 00418 if(objectIndex[i] != -1) 00419 systemIndices[i].push_back(objectIndex[i]); 00420 objectIndex[i] = *ptr; 00421 ptr++; 00422 } 00423 cout << endl; 00424 } 00425 00426 00427 System *system = this; 00428 Object *object = 0; 00429 if(selectedIndex != -1) 00430 { 00431 for(unsigned int i = 0; i < systemIndices[selectedIndex].size(); ++i) 00432 system = system->getSystem(systemIndices[selectedIndex][i]); 00433 object = system->getObject(objectIndex[selectedIndex]); 00434 } 00435 00436 m_selectedObject = object; 00437 return object; 00438 } 00439 #endif // USE_OPENGL 00440 */ 00441 00442 00443 /********************** 00444 * Protected functions * 00445 **********************/ 00446 00447 void System::deleteObject(Object *object) 00448 { 00454 if(m_destructing) return; 00455 00456 forAllObjects(it) 00457 if(*it == object) 00458 { 00459 m_objects.erase(it); 00460 return; 00461 } 00462 00463 #ifdef VERBOSE 00464 Debug::print("Trying to delete an object that isn't in the list!"); 00465 #endif // VERBOSE 00466 00468 } 00469 00470 00471 void System::deleteActor(Actor *actor) 00472 { 00478 if(m_destructing) return; 00479 00480 forAllActors(it) 00481 if(*it == actor) 00482 { 00483 m_actors.erase(it); 00484 return; 00485 } 00486 00487 #ifdef VERBOSE 00488 Debug::print("Trying to delete an actor that isn't in the list!"); 00489 #endif // VERBOSE 00490 00492 } 00493 00494 void System::deleteAgent(Agent *agent) 00495 { 00501 if(m_destructing) return; 00502 00503 forAllAgents(it) 00504 if(*it == agent) 00505 { 00506 m_agents.erase(it); 00507 return; 00508 } 00509 00510 #ifdef VERBOSE 00511 Debug::print("Trying to delete an agent that isn't in the list!"); 00512 #endif // VERBOSE 00513 00515 } 00516 00517 void System::deleteSystem(System *system) 00518 { 00525 if(m_destructing) return; 00526 00527 forAllSystems(it) 00528 if(*it == system) 00529 { 00530 m_systems.erase(it); 00531 return; 00532 } 00533 00534 #ifdef VERBOSE 00535 Debug::print("Trying to delete a system that isn't in the list!"); 00536 #endif // VERBOSE 00537 00539 }

Generated on Sun Aug 15 19:19:23 2004 for OpenCAL: Open Computer Animation Library by doxygen 1.3.8