00001 #ifndef SPRING_FORCE_OPERATOR
00002 #define SPRING_FORCE_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/BinaryForceOperator.h>
00009
00010 namespace ani
00011 {
00012
00013 template<class __EntityType>
00014 class SpringForceOperator : public BinaryForceOperator<__EntityType>
00015 {
00016 public:
00017 typedef boost::shared_ptr<__EntityType> EntityTypePtr;
00018
00019 public:
00020 SpringForceOperator() : mA(NULL), mB(NULL) {}
00021 virtual ~SpringForceOperator()
00022 {
00023 }
00024
00025
00026 void setEntities( EntityTypePtr a, EntityTypePtr b )
00027 {
00028
00029 mA = a;
00030 mB = b;
00031 }
00032 void setSpringConstant( float ks ) { mSpringConstant = ks; }
00033 void setDampeningConstant( float kd ) { mDampeningConstant = kd; }
00034 void setRestLength( float length ) { mRestLength = length; }
00035 virtual void exec( DynamicSystem<__EntityType>& ps, float timeDelta );
00036 private:
00037 float mSpringConstant;
00038 float mDampeningConstant;
00039 EntityTypePtr mA, mB;
00040 float mRestLength;
00041 };
00042
00043
00044 template< class __EntityType >
00045 void SpringForceOperator<__EntityType>::exec( ani::DynamicSystem<__EntityType>& ps, float timeDelta )
00046 {
00047 if (mA == NULL || mB == NULL)
00048 return;
00049
00050
00051
00052
00053 if (mA->isInSystem() == false || mB->isInSystem() == false)
00054 {
00055 ps.remove( this );
00056 return;
00057 }
00058
00059
00060 gmtl::Vec3f spring_offset = mA->position() - mB->position();
00061 gmtl::Vec3f speed_of_approach = mA->velocity() - mB->velocity();
00062
00063
00064 float spring_force_mag = mSpringConstant * (spring_offset.length() - mRestLength);
00065
00066
00067 float damping_force_mag = mDampeningConstant * ( speed_of_approach.dot( spring_offset ) / spring_offset.length() );
00068
00069
00070 gmtl::Vec3f direction = (spring_offset / spring_offset.length());
00071
00072
00073 gmtl::Vec3f force = -( direction * (spring_force_mag + damping_force_mag ));
00074
00075 mA->applyForce( force );
00076 mB->applyForce( -force );
00077 }
00078 }
00079
00080 #endif