Home || Architecture || Video Search || Visual Search || Scripts || Applications || Important Messages || OGL || Src

PhysicsEngine.h

Go to the documentation of this file.
00001 #ifndef Impala_Application_Videolympics_PhysicsEngine_h
00002 #define Impala_Application_Videolympics_PhysicsEngine_h
00003 
00004 #include "OglGui/View.h"
00005 
00006 namespace Impala {
00007 namespace Application {
00008 namespace Videolympics {
00009 
00010 using namespace OglGui;
00011 class PhysicsPart
00012 {
00013 public:
00014     PhysicsPart(OGLVIEW3D *view, int identifier)
00015     {
00016         mView = view;
00017         mNr = identifier;
00018         view3DSys.GetDimensions(mView, &tX, &tY, &tZ, NULL, NULL, NULL);
00019         mDestroying = false;
00020         tfX = tfY = tfZ = fX = fY = fZ = 0.0f;
00021     }
00022     void
00023     DoPhysics()
00024     {
00025         if (!IsAtTarget()) {
00026             CalcForces();
00027             float aX, aY, aZ;
00028             view3DSys.GetDimensions(mView, &aX, &aY, &aZ, NULL, NULL, NULL);
00029 
00030             aX += fX;
00031             aY += fY;
00032             aZ += fZ;
00033             view3DSys.SetDimensions(mView, aX, aY, aZ, FRETAIN, FRETAIN, FRETAIN);
00034         }
00035     }
00036 
00037     void
00038     CalcForces()
00039     {
00040         float sFactor = 0.005f;
00041 
00042         float aX, aY, aZ;
00043         view3DSys.GetDimensions(mView, &aX, &aY, &aZ, NULL, NULL, NULL);
00044 
00045         tfX = (tX - aX);
00046         tfY = (tY - aY);
00047         tfZ = (tZ - aZ);
00048 
00049         //fX = fX * (1.0f - sFactor) + tfX * sFactor * 0.8;
00050         //fY = fY * (1.0f - sFactor) + tfY * sFactor * 0.8;
00051         //fZ = fZ * (1.0f - sFactor) + tfZ * sFactor * 0.8;
00052         fX = (tX - aX) * 0.05;
00053         fY = (tY - aY) * 0.05;
00054         fZ = (tZ - aZ) * 0.05;
00055 
00056         fX = Limit(fX, 0.2f);
00057         fY = Limit(fY, 0.2f);
00058         fZ = Limit(fZ, 0.2f);
00059     }
00060 
00061     float
00062     Limit(float f, float max)
00063     {
00064         if (f > max)
00065             return max;
00066         if (f < -max)
00067             return -max;
00068         return f;
00069     }
00070 
00071     void
00072     AddToStack(int stackno)
00073     {
00074         int mStackNo = stackno;
00075     }
00076 
00077     void
00078     MoveTo(float x, float y, float z)
00079     {
00080         tX = x; tY = y; tZ = z;
00081     }
00082 
00083     void
00084     MoveRelative(float x, float y, float z)
00085     {
00086         tX += x; tY += y; tZ += z;
00087     }
00088 
00089     // call this when this physics part AND the view on which it operates
00090     // should be destroyed, logic in VidolviWindow will take care of the
00091     // actual destruction based on this.
00092     void
00093     DoDestroyPart()
00094     {
00095         mDestroying = true;
00096     }
00097 
00098     bool
00099     IsDestroying()
00100     {
00101         return mDestroying;
00102     }
00103 
00104     bool
00105     ShouldDestroy()
00106     {
00107         if (mDestroying)
00108             return true;
00109 
00110 /*        float aX, aY, aZ;
00111         view3DSys.GetDimensions(mView, &aX, &aY, &aZ, NULL, NULL, NULL);
00112         if (IsAtTarget())
00113         {
00114             ILOG_DEBUG("VIEW " << mNr << "TARGET REACHED. DESTROYING...");
00115             return true;
00116         } */
00117         return false;
00118     }
00119 
00120 
00121     inline bool
00122     IsAlmost(float a, float r)
00123     {
00124         if (a==r) return true;
00125         if ( (a>r && a - r < 0.01) || (r>a && r - a < 0.01))
00126             return true;
00127         return false;
00128     }
00129 
00130     bool
00131     IsAtTarget()
00132     {
00133         float aX, aY, aZ;
00134         view3DSys.GetDimensions(mView, &aX, &aY, &aZ, NULL, NULL, NULL);
00135         if (IsAlmost(aX,tX) && IsAlmost(aY,tY) && IsAlmost(aZ, tZ))
00136         {
00137             return true;
00138         }
00139         return false;
00140     }
00141 
00142 private:
00143     bool mRequestDestroy;
00144     bool mDestroying;
00145     float tX, tY, tZ;
00146     float fX, fY, fZ;
00147     float tfX, tfY, tfZ;
00148     OGLVIEW3D *mView;
00149     int mNr;
00150 
00151     int mStackNo;
00152 
00153     ILOG_VAR_DEC;
00154 };
00155 
00156 ILOG_VAR_INIT(PhysicsPart, Visualization.Application.Videolympics);
00157 
00158 
00159 
00160 
00161 
00162 class PhysicsEngine
00163 {
00164 public:
00165 
00166     PhysicsEngine()
00167     {
00168         mParts = std::vector<PhysicsPart*>();
00169         mStacks = std::map<int, std::vector<PhysicsPart*>* >();
00170         mIsFlushing = false;
00171         mFlushCounter = 0;
00172         Impala::CmdOptions& options = Impala::CmdOptions::GetInstance();
00173         mMaxImagesOnRow = options.GetInt("maxImagesOnRow");
00174         ILOG_DEBUG("Max images on row: " << mMaxImagesOnRow);
00175     }
00176 
00177     void
00178     RegisterPart(PhysicsPart *p, int stackno)
00179     {
00180         if (mIsFlushing)
00181         {
00182             ILOG_DEBUG("RegisterPart: still flushing, ignored.");
00183             return;
00184         }
00185 
00186         if (p == NULL) {
00187             ILOG_ERROR("Trying to register an empty PhysicsPart.");
00188             return;
00189         }
00190         mParts.push_back(p);
00191         std::vector <PhysicsPart*>* s = GetStack(stackno);
00192         s->push_back(p);
00193         MoveStackUp(stackno);
00194         ILOG_DEBUG("Added shot to stack " << stackno << " now " << s->size() << " shots in stack.");
00195     }
00196 
00197     void
00198     UnregisterPart(PhysicsPart *p)
00199     {
00200 /*        for (int i = 0; i < mParts.size(); i++) {
00201             if (p == mParts[i])
00202             {
00203                 mParts.erase(mParts.begin() + i, mParts.begin() + i + 1);
00204                 ILOG_DEBUG("ERASING PPART " << i);
00205                 break;
00206             }
00207         } */
00208     }
00209 
00210     std::vector <PhysicsPart*>*
00211     GetStack(int stackno)
00212     {
00213         if(mStacks.find(stackno) == mStacks.end())
00214         {
00215             mStacks[stackno] = new std::vector<PhysicsPart*>();
00216         }
00217         return mStacks[stackno];
00218     }
00219 
00220     void
00221     MoveStackUp(int stackno)
00222     {
00223         if (mIsFlushing)
00224         {
00225             ILOG_DEBUG("MoveStackUp: still flushing, ignored.");
00226             return;
00227         }
00228 
00229         std::vector <PhysicsPart*>* s = GetStack(stackno);
00230         ILOG_DEBUG("MoveStackUp: " << stackno << " contains " << s->size() << " shots.");
00231         for (int i = 0; i < s->size(); i++) {
00232             PhysicsPart *p = (*s)[i];
00233             if (p == NULL)
00234                 continue;
00235             p->MoveRelative(0.0f, 1.0f, 0.0f);
00236         }
00237 
00238         int mMaxStackSize = mMaxImagesOnRow; // 12
00239         if (s->size() > mMaxStackSize)
00240         {
00241             int toRemove = s->size() - mMaxStackSize;
00242             ILOG_DEBUG("Removing " << toRemove << " shots...");
00243             std::vector<PhysicsPart*>::iterator here = s->begin();
00244             while (toRemove > 0)
00245             {
00246                 PhysicsPart *p = *here;
00247                 if (p == NULL)
00248                     continue;
00249                 p->DoDestroyPart();
00250                 here++;
00251                 toRemove--;
00252             }
00253             here--;
00254             s->erase(s->begin(), here);
00255         }
00256     }
00257 
00258     void
00259     FlushStacks()
00260     {
00261         if (mIsFlushing)
00262             return;
00263 
00264         ILOG_DEBUG("Flushing stacks...");
00265         // clear the stacks:
00266         std::map<int, std::vector<PhysicsPart*>* >::iterator stackiter = mStacks.begin();
00267         for (stackiter = mStacks.begin(); stackiter != mStacks.end(); stackiter++)
00268         {
00269             int stackno = stackiter->first;
00270             ILOG_DEBUG("Cleaning stack " << stackno);
00271             std::vector <PhysicsPart*>* s = GetStack(stackno);
00272             s->clear();
00273         }
00274 
00275         // move the parts, and request deletion:
00276         for (int i = 0; i < mParts.size(); i++) {
00277             PhysicsPart *p = mParts[i];
00278             if (p == NULL) {
00279                 ILOG_ERROR("DoPhysics - PhysicsPart " << i << " = NULL.");
00280                 continue;
00281             }
00282 
00283             if (p->IsDestroying())
00284                 continue;
00285 
00286             p->MoveRelative(0.0f, +10.0f, 0.0f);
00287         }
00288 
00289         mIsFlushing = true;
00290         mFlushCounter = 100;
00291     }
00292 
00293     bool
00294     IsFlushing()
00295     {
00296         return mIsFlushing;
00297     }
00298 
00299     void
00300     DoPhysics()
00301     {
00302         int before = mParts.size();
00303         for (int i = 0; i < mParts.size(); i++) {
00304             PhysicsPart *p = mParts[i];
00305             if (p == NULL) {
00306                 ILOG_ERROR("DoPhysics - PhysicsPart " << i << " = NULL.");
00307                 continue;
00308             }
00309 
00310             if (p->IsDestroying())
00311             {
00312                 mParts.erase(mParts.begin() + i, mParts.begin() + i + 1);
00313                 i--;
00314                 continue;
00315             }
00316             p->DoPhysics();
00317         }
00318 //         if (mParts.size() != before)
00319 //         {
00320 //             ILOG_DEBUG("NR OF PARTS BEFORE: " << before);
00321 //             ILOG_DEBUG("NR OF PARTS AFTER:  " << mParts.size());
00322 //         }
00323 
00324         if (mIsFlushing)
00325         {
00326             if (mFlushCounter <= 0)
00327             {
00328                 ILOG_DEBUG("Flush counter reached zero. Destroying everything in sight.");
00329 
00330                 // Everything flushed, destroy all.
00331                 for (int i = 0; i < mParts.size(); i++) {
00332                     PhysicsPart *p = mParts[i];
00333                     if (p == NULL) {
00334                         ILOG_ERROR("DoPhysics - PhysicsPart " << i << " = NULL.");
00335                         continue;
00336                     }
00337         
00338                     p->DoDestroyPart();
00339                 }
00340 
00341                 mParts.clear();
00342 
00343                 mIsFlushing = false;
00344                 mFlushCounter = 0;
00345             }
00346             mFlushCounter--;
00347         }
00348     }
00349 
00350     std::vector<PhysicsPart*> mParts;
00351 
00352     std::map<int, std::vector<PhysicsPart*>* > mStacks;
00353 
00354     bool mIsFlushing;
00355     int  mFlushCounter;
00356     int  mMaxImagesOnRow;
00357 
00358     ILOG_VAR_DEC;
00359 
00360 };
00361 
00362 ILOG_VAR_INIT(PhysicsEngine, Visualization.Application.Videolympics);
00363 
00364 
00365 
00366 }
00367 }
00368 }
00369 
00370 #endif

Generated on Fri Mar 19 09:30:41 2010 for ImpalaSrc by  doxygen 1.5.1