00001 #ifndef TETHER_OPER
00002 #define TETHER_OPER
00003 #include <vector>
00004 #include "ani/Dynamics/Operator.h"
00005 #include "ani/Dynamics/DynamicSystem.h"
00006
00007 namespace gator
00008 {
00010 class TetherOperator : public ani::Operator<ani::Body>
00011 {
00012 public:
00013 typedef boost::shared_ptr<ani::Body> EntityTypePtr;
00014
00015 public:
00016 TetherOperator( EntityTypePtr& e1, EntityTypePtr& e2 ) :
00017 ani::Operator<ani::Body>(),
00018 mE1( e1 ), mE2( e2 )
00019 {
00020 }
00021
00022 virtual ~TetherOperator()
00023 {
00024 }
00025
00027 void setEntities( EntityTypePtr& e1, EntityTypePtr& e2 )
00028 {
00029 mE1 = e1;
00030 mE2 = e2;
00031 }
00032
00034 virtual void exec( ani::DynamicSystem<ani::Body>& ps, float timeDelta )
00035 {
00036
00037
00038 gmtl::Vec3f distance_vec( mE2->position() - mE1->position() );
00039 float distance( gmtl::length( distance_vec ) );
00040
00041 const float desired_distance = 6.0f;
00042 gmtl::Quatf target_rotation = mE2->rotation();
00043 gmtl::Vec3f target_position = target_rotation * gmtl::Vec3f( 0,0,-1 ) * (-desired_distance);
00044 target_position += mE2->position();
00045
00046
00047
00048 const float max_distance = 12.0f;
00049 gmtl::Quatf rot;
00050 gmtl::Vec3f pos;
00051 float slerp_speed = 0;
00052 if (distance < max_distance)
00053 slerp_speed = 5.0f * timeDelta;
00054 else if (distance >= max_distance)
00055 slerp_speed = 9.0f * timeDelta;
00056
00057 if (slerp_speed > 1.0f) slerp_speed = 1.0f;
00058 gmtl::slerp( rot, slerp_speed, mE1->rotation(), target_rotation );
00059 gmtl::lerp( pos, slerp_speed, mE1->position(), target_position );
00060 mE1->setPosition( pos );
00061 mE1->setRotation( rot );
00062 }
00063
00064 private:
00065 EntityTypePtr& mE1;
00066 EntityTypePtr& mE2;
00067 };
00068 }
00069
00070 #endif