objectcontroller.cpp

Go to the documentation of this file.
00001 #include "lugre_prefix.h"
00002 #include "object.h"
00003 #include "objectcontroller.h"
00004 #include <stdio.h>
00005 #include <assert.h>
00006 
00007 using namespace Lugre;
00008 
00009 // targets
00010 cObjectContollerTarget::~cObjectContollerTarget () { PROFILE }
00011 
00012 Vector3 cObjectContollerTargetObject::GetPosition() { PROFILE
00013     return *mpApproachObject ? (*mpApproachObject)->mvPos : Vector3(0,0,0);
00014 }
00015 Vector3 cObjectContollerTargetObject::GetVelocity() { PROFILE
00016     return *mpApproachObject ? (*mpApproachObject)->mvVel : Vector3(0,0,0);
00017 }
00018 
00019 bool    cObjectContollerTargetObject::IsAlive () { PROFILE
00020     return (*mpApproachObject) != 0;
00021 }
00022 
00023 cObjectContollerTargetObject::cObjectContollerTargetObject (cObject* pObject) : mpApproachObject(pObject) { PROFILE }
00024 cObjectContollerTargetObject::~cObjectContollerTargetObject (){ PROFILE }
00025 
00026 
00027 Vector3 cObjectContollerTargetPosition::GetPosition () { PROFILE return mvPosition; }
00028 bool cObjectContollerTargetPosition::IsAlive () { PROFILE return true; }
00029 Vector3 cObjectContollerTargetPosition::GetVelocity () { PROFILE return Vector3(0,0,0); }
00030 
00031 cObjectContollerTargetPosition::cObjectContollerTargetPosition (Vector3 vPosition) : mvPosition(vPosition) { PROFILE }
00032 cObjectContollerTargetPosition::~cObjectContollerTargetPosition () { PROFILE }
00033 
00034 
00035 cObjectController::cObjectController () : mpApproachTarget(0), miControlledObjectCount(0), mfMaxAccel(1), mfApproachMinDist(0), mbStupid(false) {}
00036 
00037 cObjectController::~cObjectController () {
00038     assert(miControlledObjectCount == 0 && "WARNING ! destroyed cObjectController still in use");
00039     if (miControlledObjectCount != 0) printf("WARNING ! destroyed cObjectController still in use\n");
00040     if(mpApproachTarget) { delete mpApproachTarget; mpApproachTarget = 0; }
00041 }
00042 
00043 void    cObjectController::Lock     () { miControlledObjectCount++; }
00044 void    cObjectController::Release  () { miControlledObjectCount--; assert(miControlledObjectCount >= 0); } 
00045 
00046 void    cObjectController::SetTarget    (cObjectContollerTarget *pTarget) { PROFILE
00047     if(mpApproachTarget) delete mpApproachTarget;
00048     mpApproachTarget = pTarget;
00049 }
00050 
00051 void    cObjectController::Step (cObject* pControlled) {
00052     using namespace Ogre;
00053     
00054     if (mpApproachTarget && mpApproachTarget->IsAlive()) {
00055         // approach autopilot
00056         
00057         Vector3 relpos = (pControlled->mvPos - mpApproachTarget->GetPosition());
00058         Vector3 relvel = (pControlled->mvVel - mpApproachTarget->GetVelocity());
00059         Vector3 dir = -relpos.normalisedCopy();
00060         Real relspeed = relvel.dotProduct(dir);
00061         Real reldist = relpos.length();
00062         
00063         // Real maxacc = (mvAccelParam-mvAccelParam2).length()*0.5;
00064         
00065         bool accel = true;
00066         if (reldist < mfApproachMinDist) accel = false;
00067         
00068         if (relspeed > 0.0) {
00069             Real breaktime = relspeed / mfMaxAccel;
00070             Real breakdist = relspeed * breaktime + mfMaxAccel * breaktime * breaktime;
00071             if (breakdist > reldist-mfApproachMinDist) accel = false; // hit the breaks
00072             //printf("apr=%d rd=%0.3f rs=%0.3f breaktime=%f breakdist=%f accell=%d\n",miID,reldist,relspeed,breaktime,breakdist,accel?1:0); 
00073         } else {
00074             //printf("apr=%d rd=%0.3f rs=%0.3f \n",miID,reldist,relspeed);  
00075         }
00076         
00077         // lotv prevents orbiting around the target if the current speed is orthogonal to the direction to the target
00078         Vector3 lotp = relspeed * dir;
00079         Vector3 lotv = (lotp - relvel).normalisedCopy();
00080         Real veldot = relvel.dotProduct(dir);
00081         if (veldot < 0.0) veldot = -veldot;
00082         
00083         if (accel || mbStupid) {
00084             //mvAccel = mfMaxAccel * dir;
00085             pControlled->mvAccel = mfMaxAccel * (( 1.0*dir + lotv).normalisedCopy());  // full speed ahead
00086         } else {
00087             //mvAccel = (-mfMaxAccel) * dir;
00088             pControlled->mvAccel = mfMaxAccel * ((-1.0*dir + lotv).normalisedCopy());  // hit the brakes !
00089         }
00090     }
00091     
00092     /*
00093     SLOWDOWN : 
00094         //accelerate inverse to current velocity
00095         mbNeedResync = true;
00096         Ogre::Vector3 v = -mvVel;
00097         v.normalise();
00098         v *= std::min(mfAccelParam1,mvVel.length());
00099         mvAccel = v;
00100         //set accel and speed to zero if is almost zero
00101         if(mvVel.isZeroLength()){
00102                 mvVel = Ogre::Vector3::ZERO;
00103                 mvAccel = Ogre::Vector3::ZERO;
00104         }
00105     */
00106 }
00107 
00108 
00109 #if 0
00110 // old code from object.cpp
00111 
00112 #ifndef M_PI
00113     #define M_PI 3.14159265358979323846
00114 #endif
00115 
00117 void    cObject::Step       (Ogre::Real time,bool think) { PROFILE
00118     //#define NO_CLIENT_PRECALC 
00119     // server only : autopilot stuff
00120     if (miTrackingMode == kTrackMode_Object || miTrackingMode == kTrackMode_ObjectAdvAim) {
00121         cObject* obj = *mTrackObject;
00122         mvTrackParam = obj ? (obj->mvPos - mvPos) : Vector3::UNIT_Z;
00123 
00124         // TODO : use GetAbsolutePos or GetVectorTo or something when coordinate-hierarchy system is finished
00125         // TODO : this is unfair (turn is set directly, instead of turnaccel), rewrite me
00126 
00127         static Vector3      v;
00128         static Vector3      fwd(0,0,1.0);
00129         static Vector3      axis;
00130         static Radian       angle;
00131         static Quaternion   rot;
00132         
00133         v = mqRot.Inverse() * mvTrackParam; // TODO : getDerivedOrientation instead of mqRot directly
00134         v.normalise();
00135         mqTurn = fwd.getRotationTo(v);
00136         mqTurn.ToAngleAxis(angle,axis);
00137         angle = fmax(-mfMaxTurnAccel,fmin(mfMaxTurnAccel,angle.valueRadians() / fmax(0.0001,time) ));
00138         mqTurn = Quaternion(angle,axis);
00139 
00140         /*
00141         DIDN'T work :
00142         fwd = mqRot * Vector3::UNIT_Z;
00143         fwd.normalise();
00144         rot = fwd.getRotationTo(mvTrackParam);
00145         rot.ToAngleAxis(angle,axis);
00146         //angle = fmax(-mfMaxTurnAccel,fmin(mfMaxTurnAccel,angle.valueRadians() / fmax(0.0001,time) ));
00147         mqTurn = Quaternion(angle,axis);
00148         //mqRot = rot;
00149         //mqTurn = Quaternion::IDENTITY;
00150         */
00151     }
00152 }
00153 
00154 
00155 
00156 #endif

Generated on Wed May 23 06:00:15 2012 for cpp by  doxygen 1.5.6