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

c:/home/kevn/src/animaniac/ani/Dynamics/DynamicSystem.h

Go to the documentation of this file.
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

Generated on Wed Jun 12 01:54:01 2002 for Animaniac by doxygen1.2.15