object.cpp
Go to the documentation of this file.00001 #include "lugre_prefix.h"
00002 #include "lugre_fifo.h"
00003 #include "lugre_gfx3D.h"
00004 #include "lugre_ogrewrapper.h"
00005 #include "lugre_ode.h"
00006 #include "resyncreceiver.h"
00007 #include "objectcontroller.h"
00008 #include "physicform.h"
00009 #include "object.h"
00010 #include "location.h"
00011
00012 using namespace Lugre;
00013
00014 cObject::cObject() :
00015 mpParentLocation(0),
00016 mpPhysicForm(0),
00017 mpController(0),
00018 miID(0),
00019 miResyncCounterHigh(0),
00020 miResyncCounterLow(0),
00021 miLastChangeTime(0),
00022 mbResynced(true),
00023 mfMaxSpeed(0),
00024 mfBoundingRad(0),
00025 mfDistToLocationCenter(0),
00026 mpGfx3D(0),
00027 mvPos( Ogre::Vector3::ZERO),
00028 mvVel( Ogre::Vector3::ZERO),
00029 mvAccel( Ogre::Vector3::ZERO),
00030 mqRot( Ogre::Quaternion::IDENTITY),
00031 mqTurn( Ogre::Quaternion::IDENTITY) {}
00032
00033 cObject::~cObject() {
00034 SetParentLocation(0);
00035 SetController(0);
00036 #ifdef ENABLE_ODE
00037 if (mpPhysicForm) { delete mpPhysicForm; mpPhysicForm = 0; }
00038 #endif
00039 SetID(0);
00040 }
00041
00042 void cObject::SetController (cObjectController* pObjectController) {
00043 if (mpController) mpController->Release();
00044 mpController = pObjectController;
00045 if (mpController) mpController->Lock();
00046 }
00047
00048
00049
00050 Ogre::Vector3 Vector_project_on_vector (Ogre::Vector3 v1, Ogre::Vector3 v2){
00051 return v2 * (v1.dotProduct(v2) / v2.dotProduct(v2));
00052
00053 }
00054
00055
00056 Ogre::Vector3 Vector_project_on_plane (Ogre::Vector3 v, Ogre::Vector3 n){
00057 return v - Vector_project_on_vector(v,n);
00058 }
00059
00060
00063 void cObject::Step (const int iCurTime,const float fPhysStepTime,const bool bIncResyncCounterLow) {
00064
00065 if (mpController) {
00066 mpController->Step(this);
00067 miLastChangeTime = iCurTime;
00068 }
00069
00070 if (mfMaxSpeed > 0) {
00071 float fCurSpeed = mvVel.length();
00072 if (fCurSpeed > mfMaxSpeed) mvVel *= mfMaxSpeed / fCurSpeed;
00073 }
00074
00075
00076
00077
00078 if (mpPhysicForm == 0) {
00079 mvVel += mvAccel * fPhysStepTime;
00080 mvPos += mvVel * fPhysStepTime;
00081
00082
00083 static Ogre::Radian angle;
00084 static Vector3 axis;
00085 mqTurn.ToAngleAxis(angle,axis);
00086 mqRot = mqRot * Quaternion(angle*fPhysStepTime,axis);
00087 mqRot.normalise();
00088 } else {
00089 #ifdef ENABLE_ODE
00090 float fspeed = 100.0f;
00091 mpPhysicForm->AddForce(mvAccel.x * fspeed, mvAccel.y * fspeed, mvAccel.z * fspeed);
00092
00093 if(0 && mvAccel.length() > 0.0f){
00094 mpPhysicForm->AddForceAtRelPos(10000,10000,10000, 1,1,0);
00095 }
00096
00097
00098 mpPhysicForm->GetPosition(mvPos.x, mvPos.y, mvPos.z);
00099 mpPhysicForm->GetLinearVelocity(mvVel.x, mvVel.y, mvVel.z);
00100 mpPhysicForm->GetRotation(mqRot.x, mqRot.y, mqRot.z, mqRot.w);
00101 mqRot.normalise();
00102 #endif
00103 }
00104
00105 mfDistToLocationCenter = mvPos.length();
00106 if (mpParentLocation) {
00107 float fNewBound = mfDistToLocationCenter + mfBoundingRad;
00108 if (mpParentLocation->mfBoundingRad < fNewBound)
00109 mpParentLocation->mfBoundingRad = fNewBound;
00110 }
00111
00112 if (mpGfx3D) {
00113 mpGfx3D->SetPosition(mvPos);
00114 mpGfx3D->SetOrientation(mqRot);
00115 mpGfx3D->mfCustomBoundingRadius = mfBoundingRad;
00116 }
00117
00118 if (bIncResyncCounterLow) {
00119 ++miResyncCounterLow;
00120 assert(miResyncCounterLow > 0 && "todo : handle overflow in miResyncCounterLow");
00121 }
00122 }
00123
00126 void cObject::SetParentLocation (cLocation* pParentLocation) {
00127 if (mpParentLocation == pParentLocation) return;
00128 if (mpParentLocation) mpParentLocation->mlObjects.erase(_mLocationInsertPos);
00129 mpParentLocation = pParentLocation;
00130 if (mpParentLocation) _mLocationInsertPos = mpParentLocation->mlObjects.insert(mpParentLocation->mlObjects.begin(),this);
00131 }
00132
00134 void cObject::SetID (const int iID) {
00135 if (miID != 0 && gpResyncReceiver) gpResyncReceiver->RemoveObject(miID);
00136 miID = iID;
00137 if (miID != 0 && gpResyncReceiver) gpResyncReceiver->AddObject(miID,this);
00138 }
00139
00141 void cObject::SaveResyncData (cFIFO& pFIFO) {
00142 pFIFO.PushUint32(miID);
00143 pFIFO.PushUint16((uint16)miResyncCounterHigh);
00144 pFIFO.PushUint32(miResyncCounterLow);
00145 pFIFO.Push(mvPos);
00146 pFIFO.Push(mvVel);
00147 pFIFO.Push(mvAccel);
00148 pFIFO.Push(mqRot);
00149 pFIFO.Push(mqTurn);
00150 }
00151
00153 void cObject::LoadResyncData (cFIFO& pFIFO) {
00154 pFIFO.Skip(4);
00155 if (pFIFO.PopUint16() != (uint16)miResyncCounterHigh) { pFIFO.Skip(kResyncMessageLen-(4+2)); return; }
00156 uint32 newlow = pFIFO.PopUint32();
00157 if (newlow < miResyncCounterLow) { pFIFO.Skip(kResyncMessageLen-(4+2+4)); return; }
00158 miResyncCounterLow = newlow;
00159 pFIFO.Pop(mvPos);
00160 pFIFO.Pop(mvVel);
00161 pFIFO.Pop(mvAccel);
00162 pFIFO.Pop(mqRot);
00163 pFIFO.Pop(mqTurn);
00164 }
00165
00166 void cObject::SkipResyncData (cFIFO& pFIFO) {
00167 pFIFO.Skip(kResyncMessageLen);
00168 }