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

PhysicsSystem.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 "PhysicsSystem.h" 00013 #include <OpenCAL/PhysicalObject.h> 00014 #include <OpenCAL/Force.h> 00015 #include <OpenCAL/Constraint.h> 00016 #include <OpenCAL/EulerSolver.h> 00017 #include <OpenCAL/MidpointSolver.h> 00018 #include <OpenCAL/RungeKutta4Solver.h> 00019 using namespace OpenCAL; 00020 00021 using namespace std; 00022 00023 00024 // Macros 00025 /* 00026 #define forAllObjects(it)\ 00027 ObjectList::iterator it;\ 00028 for(it = m_objects.begin(); it != m_objects.end(); ++it) 00029 00030 #define forAllForces(it)\ 00031 ForceList::iterator it;\ 00032 for(it = m_forces.begin(); it != m_forces.end(); ++it) 00033 00034 #define forAllConstraints(it)\ 00035 ConstraintList::iterator it;\ 00036 for(it = m_constraints.begin(); it != m_constraints.end(); ++it) 00037 */ 00038 00039 00040 /****************************** 00041 * Constructors and destructor * 00042 ******************************/ 00043 00044 PhysicsSystem::PhysicsSystem(System *parent) 00045 : System(parent), m_solver(0), m_maxStepSize(0.3f) 00046 { 00047 } 00048 00049 PhysicsSystem::~PhysicsSystem() 00050 { 00051 if(m_solver) 00052 delete m_solver; 00053 } 00054 00055 00056 /************************ 00057 * Get and set functions * 00058 ************************/ 00059 00060 00061 /****************** 00062 * Force functions * 00063 ******************/ 00064 00065 void PhysicsSystem::addForce(const Vector3 &force) 00066 { 00067 unsigned int i; 00068 00069 for(i = 0; i < m_systems.size(); ++i) 00070 ((PhysicsSystem *) m_systems[i])->addForce(force); 00071 00072 PhysicalObject *object; 00073 for(i = 0; i < m_objects.size(); ++i) 00074 { 00075 object = (PhysicalObject *) m_objects[i]; 00076 if(!object->isFixed()) 00077 object->addForce(force); 00078 } 00079 } 00080 00081 void PhysicsSystem::resetForces() 00082 { 00083 unsigned int i; 00084 00085 for(i = 0; i < m_systems.size(); ++i) 00086 ((PhysicsSystem *) m_systems[i])->resetForces(); 00087 00088 PhysicalObject *object; 00089 for(i = 0; i < m_objects.size(); ++i) 00090 { 00091 object = (PhysicalObject *) m_objects[i]; 00092 if(!object->isFixed()) 00093 object->resetForce(); 00094 } 00095 } 00096 00097 00098 /*********************** 00099 * ODE Source functions * 00100 ***********************/ 00101 00102 void PhysicsSystem::fillState() 00103 { 00104 /* 00105 unsigned int size = m_objects.size() * 6; 00106 m_state.clear(size); 00107 */ 00108 00110 m_state.clear(); 00111 00112 //cout << "Filling from " << m_objects.size() << " objects" << endl; 00113 for(unsigned int i = 0; i < m_objects.size(); ++i) 00114 { 00115 PhysicalObject *object = (PhysicalObject *) m_objects[i]; 00116 object->addToState(&m_state); 00118 //m_state.concat(((PhysicalObject *) m_objects[i])->getPosition()); 00119 //m_state.concat(((PhysicalObject *) m_objects[i])->getVelocity()); 00120 } 00121 } 00122 00123 void PhysicsSystem::fillDerivative() 00124 { 00126 //unsigned int size = m_objects.size() * 6; 00127 //m_derivative.clear(size); 00128 00129 m_derivative.clear(); 00130 00131 00132 for(unsigned int i = 0; i < m_objects.size(); ++i) 00133 { 00134 PhysicalObject *object = (PhysicalObject *) m_objects[i]; 00135 object->addToDerivative(&m_derivative); 00136 00137 //bool fixed = object->isFixed(); 00139 //m_derivative.concat(fixed ? Vector3::zero : object->getVelocity()); 00140 //m_derivative.concat(fixed ? Vector3::zero : object->getAccelleration()); 00141 } 00142 } 00143 00144 void PhysicsSystem::fromState() 00145 { 00146 // Go to the beginning of the state vector 00147 m_state.reset(); 00148 00149 for(unsigned int i = 0; i < m_objects.size(); ++i) 00150 { 00151 PhysicalObject *object = (PhysicalObject *) m_objects[i]; 00152 object->fromState(&m_state); 00153 /* 00154 if(!object->isFixed()) 00155 { 00156 Vector3 *pos = object->getPositionP(); 00157 Vector3 *vel = object->getVelocityP(); 00158 00159 pos->setX(m_state[i * 6]); 00160 pos->setY(m_state[i * 6 + 1]); 00161 pos->setZ(m_state[i * 6 + 2]); 00162 00163 vel->setX(m_state[i * 6 + 3]); 00164 vel->setY(m_state[i * 6 + 4]); 00165 vel->setZ(m_state[i * 6 + 5]); 00166 } 00167 // @warning Should this be done here? 00168 object->setForce(Vector3::zero); 00169 */ 00170 } 00171 } 00172 00173 00174 /****************** 00175 * Other functions * 00176 ******************/ 00177 00178 void PhysicsSystem::step(float deltaSeconds) 00179 { 00180 //if(!m_enabled) return; 00181 00182 /* 00183 1. Reset forces \ 00184 2. Apply forces - Done by the System 00185 3. Apply constraints / 00186 4. Integrate system 00187 */ 00188 00189 unsigned int steps = (unsigned int) (deltaSeconds / m_maxStepSize) + 1; 00190 deltaSeconds /= steps; 00191 00192 for(unsigned int i = 0; i < steps; ++i) 00193 { 00194 System::step(deltaSeconds); 00195 if(m_objects.size() > 0) 00196 m_solver->solve(deltaSeconds, this); 00197 } 00198 } 00199 00200 00201 /************************ 00202 * Phase space functions * 00203 ************************/ 00204 00205 /* 00206 PhaseSpace PhysicsSystem::getState() const 00207 { 00208 unsigned int size = m_objects.size() * 6; 00209 00210 // Reserve the space in the phase space (faster) 00211 PhaseSpace result(size); 00212 00213 for(unsigned int i = 0; i < m_objects.size(); ++i) 00214 { 00216 result += ((PhysicalObject *) m_objects[i])->getPosition(); 00217 result += ((PhysicalObject *) m_objects[i])->getVelocity(); 00218 } 00219 00220 return result; 00221 } 00222 00223 PhaseSpace PhysicsSystem::getDerivative() const 00224 { 00225 unsigned int size = m_objects.size() * 6; 00226 00227 // Reserve the space in the phase space (faster) 00228 PhaseSpace result(size); 00229 00230 for(unsigned int i = 0; i < m_objects.size(); ++i) 00231 { 00232 result += ((PhysicalObject *) m_objects[i])->getVelocity(); 00233 result += ((PhysicalObject *) m_objects[i])->getAccelleration(); 00234 } 00235 00236 return result; 00237 } 00238 00239 void PhysicsSystem::setState(const PhaseSpace &state) 00240 { 00241 for(unsigned int i = 0; i < m_objects.size(); ++i) 00242 { 00243 PhysicalObject *object = (PhysicalObject *) m_objects[i]; 00244 Vector3 *pos = object->getPositionP(); 00245 Vector3 *vel = object->getVelocityP(); 00246 00247 pos->setX(state[i * 6]); 00248 pos->setY(state[i * 6 + 1]); 00249 pos->setZ(state[i * 6 + 2]); 00250 00251 vel->setX(state[i * 6 + 3]); 00252 vel->setY(state[i * 6 + 4]); 00253 vel->setZ(state[i * 6 + 5]); 00254 00255 // @warning Should this be done here? 00256 object->setForce(Vector3::zero); 00257 } 00258 } 00259 */ 00260 00261 00262 void PhysicsSystem::initialize() 00263 { 00264 System::initialize(); 00265 00267 m_solver = new EulerSolver; 00268 //m_solver = new MidpointSolver; 00269 //m_solver = new RungeKutta4Solver; 00270 00271 /* 00272 forAllObjects(object) 00273 (*object)->initialize(); 00274 00275 forAllForces(force) 00276 (*force)->initialize(); 00277 00278 forAllConstraints(constraint) 00279 (*constraint)->initialize(); 00280 */ 00281 } 00282 00283 /********************** 00284 * Protected functions * 00285 **********************/ 00286 00287 /* 00288 void PhysicsSystem::addObject(Object *object) 00289 { 00290 if(!dynamic_cast<PhysicalObject *>(object)) 00291 { 00292 cerr << "Only PhysicalObject objects are allowed in this system. "; 00293 cerr << "Please delete this object manually, "; 00294 cerr << "because it will not be managed by the system." << endl; 00295 return; 00296 } 00297 00298 System::addObject(object); 00299 } 00300 00301 void PhysicsSystem::addActor(Actor *actor) 00302 { 00303 if(!dynamic_cast<Force *>(actor)) 00304 { 00305 cerr << "Only Force actors are allowed in this system. "; 00306 cerr << "Please delete this actor manually, "; 00307 cerr << "because it will not be managed by the system." << endl; 00308 return; 00309 } 00310 00311 System::addActor(actor); 00312 } 00313 00314 void PhysicsSystem::addAgent(Agent *agent) 00315 { 00316 if(!dynamic_cast<Constraint *>(agent)) 00317 { 00318 cerr << "Only Constraint agents are allowed in this system. "; 00319 cerr << "Please delete this agent manually, "; 00320 cerr << "because it will not be managed by the system." << endl; 00321 return; 00322 } 00323 00324 System::addAgent(agent); 00325 } 00326 */ 00327 00328 00329 #ifdef BLABLA 00330 void PhysicsSystem::deleteObject(PhysicalObject *object) 00331 { 00337 if(isDestructing()) return; 00338 00339 forAllObjects(it) 00340 if(*it == object) 00341 { 00342 m_objects.erase(it); 00343 return; 00344 } 00345 00346 #ifdef VERBOSE 00347 Debug::print("Trying to delete an object that isn't in the list!"); 00348 #endif // VERBOSE 00349 00351 } 00352 00353 void PhysicsSystem::deleteForce(Force *force) 00354 { 00360 if(isDestructing()) return; 00361 00362 forAllForces(it) 00363 if(*it == force) 00364 { 00365 m_forces.erase(it); 00366 return; 00367 } 00368 00369 #ifdef VERBOSE 00370 Debug::print("Trying to delete a force that isn't in the list!"); 00371 #endif // VERBOSE 00372 00374 } 00375 00376 void PhysicsSystem::deleteConstraint(Constraint *constraint) 00377 { 00383 if(isDestructing()) return; 00384 00385 forAllConstraints(it) 00386 if(*it == constraint) 00387 { 00388 m_constraints.erase(it); 00389 return; 00390 } 00391 00392 #ifdef VERBOSE 00393 Debug::print("Trying to delete a constraint that isn't in the list!"); 00394 #endif // VERBOSE 00395 00397 } 00398 #endif // BLABLA

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