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/operators/SpringForceOperator.h

Go to the documentation of this file.
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    // spring force
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       //TODO: refactor this, move it to its superclass.
00026       void setEntities( EntityTypePtr a, EntityTypePtr b ) 
00027       {
00028          // take responsibility for a and b
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    //: apply this force function to the particle
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       // does not make sense for this operator to exist if it has nothing 
00051       // to act upon...
00052       // note: this could leave the user holding an operator that maybe they thought would stay in the system... oh well, they will have to check the op's isInSystem...
00053       if (mA->isInSystem() == false || mB->isInSystem() == false)
00054       {
00055          ps.remove( this );
00056          return;
00057       }
00058 
00059       // ignoring the particle system...
00060       gmtl::Vec3f spring_offset = mA->position() - mB->position();
00061       gmtl::Vec3f speed_of_approach = mA->velocity() - mB->velocity();
00062 
00063       // calculate the spring force magnitude.
00064       float spring_force_mag = mSpringConstant * (spring_offset.length() - mRestLength);
00065 
00066       // calculate the damping force magnitude.
00067       float damping_force_mag = mDampeningConstant * ( speed_of_approach.dot( spring_offset ) / spring_offset.length() );
00068 
00069       // what direction the force is in
00070       gmtl::Vec3f direction = (spring_offset / spring_offset.length());
00071 
00072       // calculate the force from the spring and damping forces.
00073       gmtl::Vec3f force = -( direction * (spring_force_mag + damping_force_mag ));
00074 
00075       mA->applyForce( force );
00076       mB->applyForce( -force );
00077    }
00078 } // end of namespace
00079 
00080 #endif

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