00001 #ifndef VISCOUS_DRAG_OPERATOR 00002 #define VISCOUS_DRAG_OPERATOR 00003 00004 #include <boost/smart_ptr.hpp> 00005 #include <gmtl/Vec.h> 00006 #include "ani/Dynamics/Operator.h" 00007 #include "ani/Dynamics/DynamicSystem.h" 00008 #include <ani/Dynamics/operators/GlobalForceOperator.h> 00009 00010 namespace ani 00011 { 00016 template<class __EntityType> 00017 class ViscousDragOperator : public GlobalForceOperator<__EntityType> 00018 { 00019 public: 00020 ViscousDragOperator(){} 00021 ViscousDragOperator( float coef ) : _dragCoef( coef ) {} 00022 virtual ~ViscousDragOperator(){} 00023 void setDrag( const float& coeficient ) 00024 { 00025 _dragCoef = coeficient; 00026 } 00027 00028 //: apply this force function to the particle 00029 virtual void exec( DynamicSystem<__EntityType>& ps, float timeDelta ); 00030 00031 private: 00032 float _dragCoef; 00033 }; 00034 00035 //: apply this force function to the particle 00036 template< class __EntityType > 00037 void ViscousDragOperator<__EntityType>::exec( ani::DynamicSystem<__EntityType>& ps, float timeDelta ) 00038 { 00039 std::vector<EntityTypePtr>::iterator it; 00040 for ( it = ps.entities().begin(); it != ps.entities().end(); ++it) 00041 { 00042 EntityTypePtr p = *it; 00043 if (this->isIgnored( p ) == false) 00044 { 00045 // Calculate the force nesesary to knock of kV velocity 00046 00047 // get the velocity we need to reduce entities speed 00048 // eqn: V(new) = V - kV, where k is a coeficient between 0..1 00049 gmtl::Vec3f antiVelocity = p->linearVelocity() * (-_dragCoef); 00050 00051 // how much do we have to decelerate it to achieve 'newDesiredVelocity' 00052 // decelerateAmount = antiVelocity / timeChange; 00053 // NOTE: timeChange is 1.0, so deceleration is just antiVelocity 00054 gmtl::Vec3f force = antiVelocity * p->mass(); 00055 p->applyForce( force ); 00056 } 00057 } 00058 } 00059 00060 } // end of namespace 00061 00062 #endif