00001 00003 // 00004 // -= DynamicSystem =- 00005 // 00006 // Definition: "Container class for particle/body and operators" 00007 // 00009 // 00010 // $RCSfile: DynamicSystem.h,v $ 00011 // $Date: 2002/06/07 03:22:12 $ 00012 // $Revision: 1.12 $ 00013 // Copyright (C) 1998, 1999, 2000 Kevin Meinert, kevin@vrsource.org 00014 // 00015 // This library is free software; you can redistribute it and/or 00016 // modify it under the terms of the GNU Library General Public 00017 // License as published by the Free Software Foundation; either 00018 // version 2 of the License, or (at your option) any later version. 00019 // 00020 // This library is distributed in the hope that it will be useful, 00021 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00023 // Library General Public License for more details. 00024 // 00025 // You should have received a copy of the GNU Library General Public 00026 // License along with this library; if not, write to the Free 00027 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00028 // 00030 #ifndef SYSTEM_OF_DYNAMIC_ENTITIES 00031 #define SYSTEM_OF_DYNAMIC_ENTITIES 00032 00033 #include <vector> 00034 #include <list> 00035 #include <iostream> 00036 00037 #include <assert.h> 00038 #include <boost/smart_ptr.hpp> 00039 #include "ani/Dynamics/Operator.h" 00040 #include "ani/Dynamics/Memory.h" // TODO:: replace with shared_ptr 00041 #include "ani/Dynamics/SolverFactory.h" 00042 00043 // ani namespace. 00044 namespace ani 00045 { 00046 template<class __EntityType> 00047 class DynamicSystem : public __EntityType 00048 { 00049 public: 00050 // Need a shared pointer for the entity and operator types 00051 typedef __EntityType EntityType; 00052 typedef boost::shared_ptr<__EntityType> EntityTypePtr; 00053 typedef boost::shared_ptr< ani::Operator<__EntityType> > OperatorPtr; 00054 typedef std::vector<EntityTypePtr> EntityList; 00055 typedef std::list<OperatorPtr> OperatorList; 00056 00057 public: 00058 00060 DynamicSystem<__EntityType>() : mSolver( NULL ), mTotalTime( 0 ), 00061 mTimeDelta( 0 ) 00062 { 00063 } 00064 00068 virtual ~DynamicSystem<__EntityType>() 00069 { 00070 } 00071 00073 EntityList& entities(); 00074 const EntityList& entities() const; 00075 00076 OperatorList& operators(); 00077 const OperatorList& operators() const; 00078 00080 void push_back( OperatorPtr op ); 00081 00083 void push_back( EntityTypePtr ent ); 00084 00086 void push_front( OperatorPtr op ); 00087 00089 void push_front( EntityTypePtr ent ); 00090 00095 //void remove( std::vector< __EntityType* >::iterator& it ); 00096 00097 //: remove an operator from the system O(n) 00098 void remove( OperatorPtr op ); 00099 00100 00101 // clear out all entities, operations, and solver 00102 void clear(); 00103 00104 // clear all entities (result is no entities in the system). 00105 void clearEntities(); 00106 void clearOperators(); 00107 00108 // return the last time delta used (or current time delta) 00109 const float& timeDelta() const; 00110 00111 00112 // take one step in the physical model 00113 virtual void step( float timeDelta ); 00114 00115 // specify what solver to use with this system. 00116 void setSolver( const std::string& solverName = "heun" ) 00117 { 00118 ODEsolver<__EntityType>* temp = NULL; 00119 bool result = SolverFactory<__EntityType>::create( solverName, temp ); 00120 if (result) 00121 mSolver = temp; 00122 } 00123 00124 private: 00125 void zeroForces(); 00126 void execOperations(); 00127 00128 protected: 00129 std::list<OperatorPtr> mOps; 00130 std::vector<EntityTypePtr> mEntities; 00131 ODEsolver<__EntityType>* mSolver; 00132 00133 00134 protected: 00135 float mTotalTime; 00136 float mTimeDelta; 00137 }; 00138 00139 template<class __EntityType> 00140 inline void ani::DynamicSystem<__EntityType>::zeroForces() 00141 { 00142 std::vector< EntityTypePtr >::iterator it; 00143 for (it = mEntities.begin(); it != mEntities.end(); ++it) 00144 { 00145 (*it)->zeroForce(); 00146 } 00147 } 00148 00149 template<class __EntityType> 00150 inline void ani::DynamicSystem<__EntityType>::execOperations() 00151 { 00152 std::list< OperatorPtr >::iterator it; 00153 for (it = mOps.begin(); it != mOps.end(); ++it) 00154 { 00155 ani::Operator<__EntityType>& op = *(*it); 00156 op.exec( *this, mTimeDelta ); 00157 } 00158 } 00159 00160 // get access to the list of entities so you can render them etc... 00161 template<class __EntityType> 00162 inline std::vector< boost::shared_ptr<__EntityType> >& ani::DynamicSystem<__EntityType>::entities() 00163 { 00164 return mEntities; 00165 } 00166 00167 template<class __EntityType> 00168 inline const std::vector< boost::shared_ptr<__EntityType> >& ani::DynamicSystem<__EntityType>::entities() const 00169 { 00170 return mEntities; 00171 } 00172 00173 template<class __EntityType> 00174 inline std::list< boost::shared_ptr< ani::Operator<__EntityType> > >& ani::DynamicSystem<__EntityType>::operators() 00175 { 00176 return mOps; 00177 } 00178 00179 template<class __EntityType> 00180 inline const std::list< boost::shared_ptr< ani::Operator<__EntityType> > >& ani::DynamicSystem<__EntityType>::operators() const 00181 { 00182 return mOps; 00183 } 00184 00185 //: add a function to the system to be executed last 00186 template<class __EntityType> 00187 inline void DynamicSystem<__EntityType>::push_back( boost::shared_ptr< ani::Operator<__EntityType> > op ) 00188 { 00189 assert( op->isInSystem() != true && "ERROR: operator has already been added" ); 00190 op->isInSystem( true ); 00191 mOps.push_back( op ); 00192 } 00193 00194 //: add an entity to the system O(1) 00195 template<class __EntityType> 00196 inline void DynamicSystem<__EntityType>::push_back( boost::shared_ptr<__EntityType> ent ) 00197 { 00198 assert( ent->isInSystem() != true && "ERROR: entity has already been added" ); 00199 ent->isInSystem( true ); 00200 mEntities.push_back( ent ); 00201 } 00202 00203 //: add a function to the system to be executed last 00204 template<class __EntityType> 00205 inline void DynamicSystem<__EntityType>::push_front( boost::shared_ptr< ani::Operator<__EntityType> > op ) 00206 { 00207 assert( op->isInSystem() != true && "ERROR: operator has already been added" ); 00208 op->isInSystem( true ); 00209 mOps.push_front( op ); 00210 } 00211 00212 //: add an entity to the system O(1) 00213 template<class __EntityType> 00214 inline void DynamicSystem<__EntityType>::push_front( boost::shared_ptr<__EntityType> ent ) 00215 { 00216 assert( ent->isInSystem() != true && "ERROR: entity has already been added" ); 00217 ent->isInSystem( true ); 00218 mEntities.push_front( ent ); 00219 } 00220 00221 //: remove an operator from the system O(n) 00222 template<class __EntityType> 00223 inline void ani::DynamicSystem<__EntityType>::remove( boost::shared_ptr< ani::Operator<__EntityType> > op ) 00224 { 00225 assert( op->isInSystem() != false && "ERROR: operator is not part of the system" ); 00226 op->isInSystem( false ); 00227 mOps.remove( op ); 00228 } 00229 00230 template<class __EntityType> 00231 inline void ani::DynamicSystem<__EntityType>::clearEntities() 00232 { 00233 mEntities.clear(); 00234 } 00235 00236 template<class __EntityType> 00237 inline void ani::DynamicSystem<__EntityType>::clearOperators() 00238 { 00239 mOps.clear(); 00240 } 00241 00242 00243 template<class __EntityType> 00244 inline void ani::DynamicSystem<__EntityType>::clear() 00245 { 00246 this->clearEntities(); 00247 this->clearOperators(); 00248 } 00249 00250 //: remove an entity from the system O(1) 00251 // specify its iterator... 00252 // this function is useful only to operators (generally). 00253 /* 00254 template<class __EntityType> 00255 inline void ani::DynamicSystem<__EntityType>::remove( std::vector<EntityTypePtr>::iterator& it ) 00256 { 00257 EntityTypePtr p = (*it); 00258 assert( p->isInSystem() != false && "ERROR: entity is not part of the system" ); 00259 p->isInSystem( false ); 00260 mEntities.erase( it ); 00261 } 00262 */ 00263 00264 // return the last time delta used (or current time delta) 00265 template<class __EntityType> 00266 inline const float& ani::DynamicSystem<__EntityType>::timeDelta() const 00267 { 00268 return mTimeDelta; 00269 } 00270 00271 template<class __EntityType> 00272 inline void ani::DynamicSystem<__EntityType>::step( float timeDelta ) 00273 { 00274 if (mSolver == NULL) 00275 { 00276 this->setSolver( "euler" ); 00277 } 00278 00279 // make sure bogus values don't get processed... 00280 // mostly im afraid of numbers in the 40e+8 range 00281 // but really it shouldn't go lower than 100 00282 if (timeDelta < 100.0f && timeDelta > 0.0f) 00283 { 00284 mTotalTime += timeDelta; 00285 mTimeDelta = timeDelta; 00286 00287 // set the forces in mEntities 00288 this->execOperations(); 00289 00290 // solve for the next state the entities are at 00291 std::vector<DynamicSystem::EntityTypePtr>::iterator it; 00292 for (it = mEntities.begin(); it != mEntities.end(); ++it) 00293 { 00294 EntityType& entity = *(*it); 00295 mSolver->exec( entity, mTimeDelta ); 00296 } 00297 this->zeroForces(); 00298 } 00299 } 00300 00301 }; // end namespace 00302 00303 #endif