00001 #ifndef DRIVE_OPERATOR_H
00002 #define DRIVE_OPERATOR_H
00003 #include <vector>
00004 #include "ani/Dynamics/Operator.h"
00005 #include "ani/Dynamics/DynamicSystem.h"
00006 #include <gmtl/Output.h>
00007
00008 namespace gator
00009 {
00017 class DriveNavigationOperator : public ani::Operator<ani::Body>
00018 {
00019 public:
00020 typedef boost::shared_ptr<ani::Body> EntityTypePtr;
00021
00022 public:
00023
00024 DriveNavigationOperator( EntityTypePtr& e ) :
00025 ani::Operator<ani::Body>(), mEnt( e )
00026 {
00027 }
00028
00029
00030 virtual ~DriveNavigationOperator()
00031 {
00032 }
00033
00035 void impulseForce( const gmtl::Vec3f& acc )
00036 {
00037 mImpulseForce += acc;
00038 }
00039
00041 void force( const gmtl::Vec3f& force )
00042 {
00043 mForce += force;
00044 }
00045
00051 void torque( const gmtl::Vec3f& torque )
00052 {
00053 mTorque += torque;
00054 }
00055
00056 void stop()
00057 {
00058 mStopping = true;
00059 }
00060
00061 virtual void exec( ani::DynamicSystem<ani::Body>& ps, float timeDelta )
00062 {
00063 ani::Body& p = *mEnt;
00064
00065
00066
00067 gmtl::Matrix44f mat;
00068
00069
00070 gmtl::set( mat, p.rotation() );
00071 gmtl::Vec3f rotated_force, rotated_torque(mTorque);
00072 rotated_force = mat * mForce;
00073
00074
00075
00076 p.applyForce( rotated_force );
00077
00078 p.setAngularVelocity( rotated_torque );
00079
00080
00081 p.applyForce( mImpulseForce / (timeDelta) );
00082
00083 if (mStopping == true)
00084 {
00085 if (gmtl::length( p.linearVelocity() ) > 0.0f)
00086 {
00087
00088
00089 gmtl::Vec3f force( -p.linearVelocity() * p.mass() / timeDelta );
00090 p.applyForce( force * timeDelta * 3.0f );
00091
00092
00093
00094 }
00095 }
00096 mForce.set( 0,0,0 );
00097 mTorque.set( 0,0,0 );
00098 mImpulseForce.set( 0,0,0 );
00099 mStopping = false;
00100 }
00101 EntityTypePtr mEnt;
00102 gmtl::Vec3f mForce;
00103 gmtl::Vec3f mImpulseForce;
00104 gmtl::Vec3f mTorque;
00105 bool mStopping;
00106 };
00107 }
00108
00109 #endif