src/BilliardPhysics.cpp

Go to the documentation of this file.
00001 
00002 #ifndef DOLOG
00003 //#define DOLOG
00004 #undef  DOLOG
00005 #endif
00006 
00007 
00008 #include <algorithm>
00009 #include <iomanip>
00010 #include <sstream>
00011 #include <stdexcept>
00012 
00013 #include "BilliardPhysics.h"
00014 #include "Object.h"
00015 #include "TableBorder.h"
00016 #include "Collision.h"
00017 #include "defines.h"
00018 
00019 
00022 BilliardPhysics::BilliardPhysics()
00023     : mObjects(),
00024         mBorders(),
00025         mCollisions(),
00026         mTime(0.0f),
00027         mLoadFile(),
00028         mInFile(),
00029         mSaveFile(),
00030         mOutFile()
00031 {
00032     mBorders[0] = new TableBorder("left",   TABLE_MIN.z(), true,    Vec3f(0, 0, 1));
00033     mBorders[1] = new TableBorder("top",    TABLE_MAX.x(), false,   Vec3f(-1, 0, 0));
00034     mBorders[2] = new TableBorder("right",  TABLE_MAX.z(), true,    Vec3f(0, 0, -1));
00035     mBorders[3] = new TableBorder("bottom", TABLE_MIN.x(), false,   Vec3f(1, 0, 0));
00036     LOG("");
00037     LOG("physics init");
00038     LOG("------------");
00039     LOG("constants:");
00040     LOG("EPSILON        = " << std::setprecision(8) << EPSILON);
00041     LOG("PHYS_EPS       = " << std::setprecision(8) << PHYS_EPS);
00042     LOG("MUE_SLIDING    = " << std::setprecision(8) << MUE_SLIDING);
00043     LOG("MUE_ROLLING    = " << std::setprecision(8) << MUE_ROLLING);
00044     LOG("MUE_BALLS      = " << std::setprecision(8) << MUE_BALLS);
00045     LOG("COLLISION_LOSS = " << std::setprecision(8) << COLLISION_LOSS);
00046     LOG("T_IMPULSE      = " << std::setprecision(8) << T_IMPULSE);
00047     LOG("GRAVITY        = " << std::setprecision(8) << GRAVITY);
00048     LOG("CONTACT_RADIUS = " << std::setprecision(8) << CONTACT_RADIUS);
00049     LOG("BALL_MASS      = " << std::setprecision(8) << BALL_MASS);
00050     LOG("FRAME_LENGTH   = " << std::setprecision(8) << FRAME_LENGTH);
00051     LOG("");
00052 }
00053 
00056 BilliardPhysics::~BilliardPhysics()
00057 {
00058     for (int i=0; i<4; i++)
00059         delete mBorders[i];
00060     for (unsigned int i =0; i<mCollisions.size(); i++)
00061         delete mCollisions[i];
00062 }
00063 
00066 void BilliardPhysics::remove(Object * obj)
00067 {/*{{{*/
00068     for (std::vector<Object*>::iterator it=mObjects.begin(); it != mObjects.end(); ++it)
00069     {
00070         if ((*it) == obj)
00071         {
00072             mObjects.erase(it);
00073             break;
00074         }
00075     }
00076 }/*}}}*/
00077 
00078 
00081 void BilliardPhysics::step()
00082 {/*{{{*/
00083     LOG("physics step()");
00084     // load frame
00085     if (mLoadFile != "")
00086     {
00087         LOG("Loading frame...");
00088         std::stringstream s;
00089         mInFile.read(reinterpret_cast<char *>(&mTime), sizeof(float));
00090         unsigned int tmp;
00091         mInFile.read(reinterpret_cast<char *>(&tmp), sizeof(unsigned int));
00092         if (tmp != mObjects.size())
00093         {
00094             s << "Unexpected number of objects (" << tmp << ") in file \"" << mLoadFile << "\" ";
00095             s << "should be: " << mObjects.size();
00096             throw std::logic_error(s.str());
00097         }
00098         for (unsigned int i=0; i<mObjects.size(); i++)
00099         {
00100             mObjects[i]->readDump(mInFile);
00101         }
00102         return;
00103     }
00104 
00105     createCollisionList();
00106     dumpCollisions();   // FIXME DEBUG
00107 
00108     // collide all objects
00109     int nrcollisions = 0;
00110     std::vector<Collision *>    sameTime;
00111     while (mCollisions.size() > 0)
00112     {
00113         assert(mCollisions.at(0));
00114         LLOG("collecting");
00115         // collect collisions that happen at the same time
00116         sameTime.clear();
00117         sameTime.push_back(mCollisions[0]);
00118         unsigned int j = 1;
00119         while (j < mCollisions.size() && mCollisions[j]->time < sameTime[0]->time + EPSILON)
00120         {
00121             assert(mCollisions.at(j));
00122             sameTime.push_back(mCollisions[j]);
00123             j++;
00124         }
00125 
00126         LLOG("colliding");
00127         // collide all this objects
00128         for (unsigned int i = 0; i<sameTime.size(); i++)
00129         {
00130             assert(sameTime.at(i));
00131             sameTime[i]->collide();
00132             nrcollisions++;
00133         }
00134 
00135         LLOG("updating");
00136         // list is sorted -> we can update time of all objects and safely recalculate collisions
00137         for (unsigned int i=0; i<mObjects.size(); i++)
00138         {
00139             mObjects[i]->updateProperties(sameTime[0]->time);
00140         }
00141         updateCollisionList(sameTime);
00142     }
00143     LOG("processed " << nrcollisions << " collisions");
00144 
00145     LOG("update properties of " << mObjects.size() << " objects");
00146     // update properties of all objects for the next frame
00147     for (unsigned int i=0; i<mObjects.size(); i++)
00148     {
00149         mObjects[i]->updateProperties(mTime + FRAME_LENGTH);
00150 #ifndef DOLOG
00151         LOG(mObjects[i]->name() << " : pos = " << mObjects[i]->position()
00152                 << "  v = " << mObjects[i]->velocity() << "  w = " << mObjects[i]->angularVelocity());
00153 #endif
00154     }
00155     mTime += FRAME_LENGTH;
00156 
00157     // dump frame
00158     if (mSaveFile != "")
00159     {
00160         LOG("Dumping frame...");
00161         mOutFile.write(reinterpret_cast<char *>(&mTime), sizeof(float));
00162         unsigned int tmp = mObjects.size();
00163         mOutFile.write(reinterpret_cast<char *>(&tmp), sizeof(unsigned int));
00164         for (unsigned int i=0; i<mObjects.size(); i++)
00165         {
00166             mObjects[i]->writeDump(mOutFile);
00167         }
00168         mOutFile.flush();
00169     }
00170 }/*}}}*/
00171 
00172 
00175 void BilliardPhysics::createCollisionList()
00176 {/*{{{*/
00177     for (unsigned int i =0; i<mCollisions.size(); i++)
00178         delete mCollisions[i];
00179     mCollisions.clear();
00180     for (unsigned int i=0; i<mObjects.size(); i++)
00181     {
00182         // test for collisions between all balls
00183         for (unsigned int j=i+1; j<mObjects.size(); j++)
00184         {
00185             float time = mTime;
00186             if (willCollide(time, mObjects[i], mObjects[j]))
00187                 mCollisions.push_back(new BallCollision(time, mObjects[i], mObjects[j]));
00188         }
00189         // test for collisions between balls and borders
00190         for (int j=0; j<4; j++)
00191         {
00192             float time = mTime;
00193             if (willHitBorder(time, mObjects[i], mBorders[j]))
00194                 mCollisions.push_back(new BorderCollision(time, mObjects[i], mBorders[j]));
00195         }
00196     }
00197     std::sort(mCollisions.begin(), mCollisions.end(), Collision::compare);
00198 }/*}}}*/
00199 
00200 
00204 bool BilliardPhysics::willCollide(float & time, const Object * o1, const Object * o2) const
00205 {/*{{{*/
00206     assert(o1);
00207     assert(o2);
00208     LLOG("testing possible collision of " << o1->name() << " vs " << o2->name() << "  time: " << std::setprecision(6) << time);
00209     if (!o1->applyPhysics() || !o2->applyPhysics())
00210         return false;
00211     assert(time >= -0.0f);
00212     assert(o1->time() <= time + EPSILON);
00213     assert(o2->time() <= time + EPSILON);
00214     assert(fabs(o1->time() - o2->time()) < EPSILON);
00215 
00216 //    return false; // FIXME DEBUG
00217 
00218     // range check
00219     if (o1 == o2 || time < mTime || mTime + FRAME_LENGTH <= time)
00220         return false;
00221     // not moving balls
00222 //    if (o1->velocity().length() < PHYS_EPS && o2->velocity().length() < PHYS_EPS)
00223 //        return false;
00224 
00225     // simple formula for monotonic motion, since formula for accelerated motion yelds to
00226     // 4-th degree equation
00227     Vec3f dv = o1->velocity() - o2->velocity();
00228     Vec3f dp = o1->position() - o2->position();
00229     LLOG("dv : " << dv << " |dv| : " << dv.length() << "  dp : " << dp << " |dp| : " << dp.length());
00230     LLOG("v1 = " << o1->velocity() << " v2 = " << o2->velocity());
00231     if (dp.length() < BALL_RADIUS*2 - EPSILON)
00232     {
00233         // avoid numerical problems
00234         time = o1->time() + EPSILON;
00235         return true;
00236     }
00237     float a = dv.dot(dv);
00238     float b = 2*dp.dot(dv);
00239     float c = dp.dot(dp) - 4*BALL_RADIUS*BALL_RADIUS;
00240     float D = b*b - 4*a*c;
00241 //    LOG("a : " << a << " b : " << b << " c : " << c << "  D : " << D);
00242     if (D < 0.0f)
00243         return false;
00244     D = sqrtf(D);
00245     float t1;
00246     float t2;
00247     if (fabs(a) > EPSILON)
00248     {
00249         t1 = (- b + D)*0.5f/a;
00250         t2 = (- b - D)*0.5f/a;
00251     }
00252     else
00253     {
00254         if (fabs(b) < EPSILON)
00255             return false;
00256         t1 = -c / b;
00257         t2 = -c / b;
00258     }
00259     t1 += o1->time();
00260     t2 += o2->time();
00261 
00262     LLOG("(" << mTime << " .. " << mTime + FRAME_LENGTH << ") time : " << time << "  t1 : " << t1 << " t2 : " << t2);
00263     // bounds check
00264     float t = t1;
00265     t1 = t1 < t2 ? t1 : t2;
00266     t2 = t < t2 ? t2 : t;
00267     LLOG("(" << mTime << " .. " << mTime + FRAME_LENGTH << ") time : " << time << "  t1 : " << t1 << " t2 : " << t2);
00268     if (time <= t1 && t1 <= mTime + FRAME_LENGTH)
00269     {
00270         time = t1 + EPSILON;
00271         return true;
00272     }
00273     if (time <= t2 && t2 <= mTime + FRAME_LENGTH)
00274     {
00275         time = t2 + EPSILON;
00276         return true;
00277     }
00278     return false;
00279 }/*}}}*/
00280 
00281 
00285 bool BilliardPhysics::willHitBorder(float & time, const Object * obj, const TableBorder * border) const
00286 {/*{{{*/
00287     assert(obj);
00288     assert(border);
00289     LLOG("testing possible collision of " << obj->name() << " vs " << border->name() << " border  time: " << std::setprecision(6) << time);
00290     assert(time >= -0.0f);
00291     assert(obj->time() <= time + EPSILON);
00292 
00293 //    return false;   // FIXME DEBUG
00294 
00295     if (time < mTime || mTime + FRAME_LENGTH <= time)
00296         return false;
00297     for (int i=0; i<4; i++)
00298         if (obj == mBorders[i])
00299             return false;
00300 
00301     // since borders are axis aligned, we only need to consider one dimension
00302     // assume monotonic motion FIXME calculate using friction force
00303     float t = INFINITY;
00304     if (border->xAligned())
00305     {
00306         // left or right
00307         if (fabs(obj->velocity().z()) > PHYS_EPS)
00308         {
00309             t = border->dist() - obj->position().z();
00310             LLOG("t = " << t);
00311             if (t * obj->velocity().z() > 0.0f && fabs(t) < BALL_RADIUS - EPSILON)
00312             {
00313                 t = time - obj->time();
00314             }
00315             else
00316             {
00317                 t = t < 0.0f ? t + BALL_RADIUS : t - BALL_RADIUS;
00318                 t /= obj->velocity().z();
00319             }
00320         }
00321     }
00322     else
00323     {
00324         // top or bottom
00325         if (fabs(obj->velocity().x()) > PHYS_EPS)
00326         {
00327             t = border->dist() - obj->position().x();
00328             LLOG("t = " << t);
00329             if (t * obj->velocity().x() > 0.0f && fabs(t) < BALL_RADIUS - EPSILON)
00330             {
00331                 t = time - obj->time();
00332             }
00333             else
00334             {
00335                 t = t < 0.0f ? t + BALL_RADIUS : t - BALL_RADIUS;
00336                 t /= obj->velocity().x();
00337             }
00338         }
00339     }
00340     t += obj->time();
00341     LLOG("(" << mTime << " .. " << mTime + FRAME_LENGTH << ") time : " << time << "  t : " << t);
00342 
00343     // range check
00344     if (time - EPSILON < t && t <= mTime + FRAME_LENGTH)
00345     {
00346         time = t + EPSILON;
00347         return true;
00348     }
00349     return false;
00350 }/*}}}*/
00351 
00352 
00358 void BilliardPhysics::updateCollisionList(const std::vector<Collision *> & clsns)
00359 {/*{{{*/
00360     assert(clsns.size() > 0);
00361 #ifdef DOLOG
00362     LLOG("collisions to update with:");
00363     for (unsigned int j = 0; j < clsns.size(); j++)
00364     {
00365         assert(clsns[j]);
00366         assert(clsns[j]->first);
00367         assert(clsns[j]->second);
00368         LLOG("clsn " << j << "  " << clsns[j]->dump());
00369     }
00370     LLOG(" # # # ");
00371     dumpCollisions();
00372 #endif
00373 
00374     // delete invalid collisions
00375     std::vector<Collision *>    toFree(clsns);
00376     for (unsigned int i = 0; i < mCollisions.size(); )
00377     {
00378         bool notDeleted = true;
00379         for (unsigned int j = 0; j < clsns.size(); j++)
00380         {
00381             if (mCollisions[i]->isAffected(clsns[j]))
00382             {
00383                 // remove
00384                 toFree.push_back(mCollisions[i]);
00385                 mCollisions[i] = mCollisions[mCollisions.size()-1];
00386                 mCollisions.pop_back();
00387                 notDeleted = false;
00388                 break;
00389             }
00390         }
00391         if (notDeleted)
00392             i++;
00393     }
00394 
00395     LLOG("removed invalid collisions");
00396     dumpCollisions();   // FIXME DEBUG
00397 
00398     // add new collisions
00399     for (unsigned int i = 0; i < mObjects.size(); i++)
00400     {
00401         for (unsigned int j = 0; j < clsns.size(); j++)
00402         {
00403             LLOG("current (" << j << " / " << clsns.size() << ") collision: " << clsns.at(j)->dump());
00404             // collisions between balls
00405             float time = clsns[j]->time;
00406             Collision * cs[6] = {NULL, NULL, NULL, NULL, NULL, NULL};
00407             if (willCollide(time, clsns[j]->first, mObjects[i])
00408                     && clsns[j]->second != mObjects[i]
00409                     && clsns[j]->time < time)
00410                 cs[5] = new BallCollision(time, clsns[j]->first, mObjects[i]);
00411 
00412             time = clsns[j]->time;
00413             if (willCollide(time, clsns[j]->second, mObjects[i])
00414                     && clsns[j]->first != mObjects[i]
00415                     && clsns[j]->time < time)
00416                 cs[4] = new BallCollision(time, clsns[j]->second, mObjects[i]);
00417 
00418             // test for collisions between balls and borders
00419             for (int k=0; k<4; k++)
00420             {
00421                 time = clsns[j]->time;
00422                 if (willHitBorder(time, mObjects[i], mBorders[k])
00423                         && (clsns[j]->first != mObjects[i] || clsns[j]->second != mBorders[k])
00424                         && clsns[j]->time < time)
00425                     cs[k] = new BorderCollision(time, mObjects[i], mBorders[k]);
00426             }
00427 
00428             // avoid readding of old collisions
00429             for (int l=0; l<6; l++)
00430             {
00431 //                for (unsigned int k = 0; k < clsns.size(); k++)
00432 //                {
00433 //                    if (cs[l] && ((clsns[k]->first == cs[l]->first && clsns[k]->second == cs[l]->second)
00434 //                                    || (clsns[k]->first == cs[l]->second && clsns[k]->second == cs[l]->first)))
00435 //                    {
00436 //                        delete cs[l];
00437 //                        cs[l] = NULL;
00438 //                    }
00439 //                }
00440                 if (cs[l])
00441                     mCollisions.push_back(cs[l]);
00442             }
00443         }
00444     }
00445     LLOG("unsorted");
00446     dumpCollisions();   // FIXME DEBUG
00447     // remove duplicates
00448     std::sort(mCollisions.begin(), mCollisions.end(), Collision::ucompare);
00449     LLOG("sorted by duplicates");
00450     dumpCollisions();   // FIXME DEBUG
00451     // free duplicated collisions
00452     Collision * last = NULL;
00453     for (unsigned int i = 0; i < mCollisions.size(); i++)
00454     {
00455         if (last && Collision::predicate(last, mCollisions[i]))
00456         {
00457             delete mCollisions[i];
00458             mCollisions[i] = NULL;
00459             continue;
00460         }
00461         else
00462         {
00463             last = mCollisions[i];
00464         }
00465         for (unsigned int j = 0; j < clsns.size(); j++)
00466         {
00467             if (Collision::predicate(clsns[j], mCollisions[i]))
00468             {
00469                 delete mCollisions[i];
00470                 mCollisions[i] = NULL;
00471             }
00472         }
00473     }
00474     mCollisions.erase(std::unique(mCollisions.begin(), mCollisions.end(), Collision::predicate), mCollisions.end());
00475     LLOG("deleted");
00476     dumpCollisions();   // FIXME DEBUG
00477 
00478     // sort by time
00479     std::sort(mCollisions.begin(), mCollisions.end(), Collision::compare);
00480     LLOG("sorted by time");
00481     dumpCollisions();   // FIXME DEBUG
00482     if (mCollisions.size() > 0 && !mCollisions[0])
00483     {
00484         std::vector<Collision *>::iterator endnull = mCollisions.begin();
00485         while (mCollisions.size() > 0 && endnull != mCollisions.end() && !*endnull)
00486             ++endnull;
00487         mCollisions.erase(mCollisions.begin(), endnull);
00488     }
00489     LLOG("no nulls");
00490     dumpCollisions();   // FIXME DEBUG
00491 
00492     // free memory
00493     LLOG("free memory");
00494     for (unsigned int j = 0; j < toFree.size(); j++)
00495     {
00496         LLOG(j << " / " << toFree.size() << "  " << toFree[j] << "  " << toFree[j]->dump());
00497     }
00498     std::sort(toFree.begin(), toFree.end());
00499     std::vector<Collision *>::iterator endit = std::unique(toFree.begin(), toFree.end());
00500     for (std::vector<Collision *>::iterator it = toFree.begin(); it != endit; ++it)
00501         delete *it;
00502 
00503     LLOG("added new collisions");
00504     dumpCollisions();   // FIXME DEBUG
00505     LLOG("\n");
00506 }/*}}}*/
00507 
00510 void BilliardPhysics::dumpCollisions() const
00511 {/*{{{*/
00512 #ifdef DOLOG
00513     LOG("dumping " << mCollisions.size() << " collisions:");
00514     for (unsigned int i = 0; i < mCollisions.size(); i++)
00515     {
00516         if (!mCollisions[i])
00517         {
00518             LOG(std::setw(3) << i << " : NULL");
00519         }
00520         else
00521         {
00522             LOG(std::setw(3) << i << " : " << mCollisions[i]->dump());
00523         }
00524     }
00525     LOG("\n");
00526 #endif
00527 }/*}}}*/
00528 
00529 
00534 void BilliardPhysics::dumpToFile(const std::string & file)
00535 {/*{{{*/
00536     if (mOutFile)
00537         mOutFile.close();
00538     mOutFile.clear();
00539     if (file == "")
00540         return;
00541     mOutFile.open(file.c_str(), std::ios::out | std::ios::binary | std::ios::trunc);
00542     if (!mOutFile)
00543     {
00544         mSaveFile = "";
00545         throw std::logic_error("Can not open file \"" + file + "\" for physics");
00546     }
00547     mSaveFile = file;
00548 
00549     int magic = 0x31796870;
00550     mOutFile.write(reinterpret_cast<const char *>(&magic), sizeof(int));
00551 
00552     mOutFile.write(reinterpret_cast<const char *>(&BALL_RADIUS), sizeof(float));
00553     mOutFile.write(reinterpret_cast<const char *>(&PHYS_EPS), sizeof(float));
00554     mOutFile.write(reinterpret_cast<const char *>(&MUE_SLIDING), sizeof(float));
00555     mOutFile.write(reinterpret_cast<const char *>(&MUE_ROLLING), sizeof(float));
00556     mOutFile.write(reinterpret_cast<const char *>(&MUE_BALLS), sizeof(float));
00557     mOutFile.write(reinterpret_cast<const char *>(&COLLISION_LOSS), sizeof(float));
00558     mOutFile.write(reinterpret_cast<const char *>(&T_IMPULSE), sizeof(float));
00559     mOutFile.write(reinterpret_cast<const char *>(&GRAVITY), sizeof(float));
00560     mOutFile.write(reinterpret_cast<const char *>(&CONTACT_RADIUS), sizeof(float));
00561     mOutFile.write(reinterpret_cast<const char *>(&BALL_MASS), sizeof(float));
00562     mOutFile.write(reinterpret_cast<const char *>(&SPREAD_POW), sizeof(float));
00563     mOutFile.write(reinterpret_cast<const char *>(&SPREAD_MAX_V), sizeof(float));
00564     mOutFile.write(reinterpret_cast<const char *>(&FRAME_LENGTH), sizeof(float));
00565 
00566     mOutFile.clear();
00567     mOutFile.flush();
00568 }/*}}}*/
00569 
00570 
00575 void BilliardPhysics::loadFromFile(const std::string & file)
00576 {/*{{{*/
00577     if (mInFile)
00578         mInFile.close();
00579     mInFile.clear();
00580     if (file == "")
00581         return;
00582     mInFile.open(file.c_str(), std::ios::in | std::ios::binary);
00583     if (!mInFile)
00584     {
00585         mLoadFile = "";
00586         return;
00587     }
00588 
00589     // test type etc
00590     int magic = 0x31796870;
00591     float tmpf;
00592     std::stringstream strs;
00593     mInFile.read(reinterpret_cast<char *>(&magic), sizeof(int));
00594     if (magic != 0x31796870)
00595     {
00596         strs << "Unknown physics file format \"" << magic << "\", file: \"" << file << "\"";
00597         throw std::logic_error(strs.str());
00598     }
00599 
00600     mInFile.read(reinterpret_cast<char *>(&tmpf), sizeof(float));
00601     mInFile.clear();
00602     if (fabs(tmpf - BALL_RADIUS) > EPSILON)
00603     {
00604         strs << "BALL_RADIUS constant differ from built in, expected: " << std::setprecision(8) << BALL_RADIUS;
00605         strs << " got: " << std::setprecision(8) << tmpf;
00606         throw std::logic_error(strs.str());
00607     }
00608 
00609     mInFile.read(reinterpret_cast<char *>(&tmpf), sizeof(float));
00610     mInFile.clear();
00611     if (fabs(tmpf - PHYS_EPS) > EPSILON)
00612     {
00613         strs << "PHYS_EPS constant differ from built in, expected: " << std::setprecision(8) << PHYS_EPS;
00614         strs << " got: " << std::setprecision(8) << tmpf;
00615         throw std::logic_error(strs.str());
00616     }
00617 
00618     mInFile.read(reinterpret_cast<char *>(&tmpf), sizeof(float));
00619     mInFile.clear();
00620     if (fabs(tmpf - MUE_SLIDING) > EPSILON)
00621     {
00622         strs << "MUE_SLIDING constant differ from built in, expected: " << std::setprecision(8) << MUE_SLIDING;
00623         strs << " got: " << std::setprecision(8) << tmpf;
00624         throw std::logic_error(strs.str());
00625     }
00626 
00627     mInFile.read(reinterpret_cast<char *>(&tmpf), sizeof(float));
00628     mInFile.clear();
00629     if (fabs(tmpf - MUE_ROLLING) > EPSILON)
00630     {
00631         strs << "MUE_ROLLING constant differ from built in, expected: " << std::setprecision(8) << MUE_ROLLING;
00632         strs << " got: " << std::setprecision(8) << tmpf;
00633         throw std::logic_error(strs.str());
00634     }
00635 
00636     mInFile.read(reinterpret_cast<char *>(&tmpf), sizeof(float));
00637     mInFile.clear();
00638     if (fabs(tmpf - MUE_BALLS) > EPSILON)
00639     {
00640         strs << "MUE_BALLS constant differ from built in, expected: " << std::setprecision(8) << MUE_BALLS;
00641         strs << " got: " << std::setprecision(8) << tmpf;
00642         throw std::logic_error(strs.str());
00643     }
00644 
00645     mInFile.read(reinterpret_cast<char *>(&tmpf), sizeof(float));
00646     mInFile.clear();
00647     if (fabs(tmpf - COLLISION_LOSS) > EPSILON)
00648     {
00649         strs << "COLLISION_LOSS constant differ from built in, expected: " << std::setprecision(8) << COLLISION_LOSS;
00650         strs << " got: " << std::setprecision(8) << tmpf;
00651         throw std::logic_error(strs.str());
00652     }
00653 
00654     mInFile.read(reinterpret_cast<char *>(&tmpf), sizeof(float));
00655     mInFile.clear();
00656     if (fabs(tmpf - T_IMPULSE) > EPSILON)
00657     {
00658         strs << "T_IMPULSE constant differ from built in, expected: " << std::setprecision(8) << T_IMPULSE;
00659         strs << " got: " << std::setprecision(8) << tmpf;
00660         throw std::logic_error(strs.str());
00661     }
00662 
00663     mInFile.read(reinterpret_cast<char *>(&tmpf), sizeof(float));
00664     mInFile.clear();
00665     if (fabs(tmpf - GRAVITY) > EPSILON)
00666     {
00667         strs << "GRAVITY constant differ from built in, expected: " << std::setprecision(8) << GRAVITY;
00668         strs << " got: " << std::setprecision(8) << tmpf;
00669         throw std::logic_error(strs.str());
00670     }
00671 
00672     mInFile.read(reinterpret_cast<char *>(&tmpf), sizeof(float));
00673     mInFile.clear();
00674     if (fabs(tmpf - CONTACT_RADIUS) > EPSILON)
00675     {
00676         strs << "CONTACT_RADIUS constant differ from built in, expected: " << std::setprecision(8) << CONTACT_RADIUS;
00677         strs << " got: " << std::setprecision(8) << tmpf;
00678         throw std::logic_error(strs.str());
00679     }
00680 
00681     mInFile.read(reinterpret_cast<char *>(&tmpf), sizeof(float));
00682     mInFile.clear();
00683     if (fabs(tmpf - BALL_MASS) > EPSILON)
00684     {
00685         strs << "BALL_MASS constant differ from built in, expected: " << std::setprecision(8) << BALL_MASS;
00686         strs << " got: " << std::setprecision(8) << tmpf;
00687         throw std::logic_error(strs.str());
00688     }
00689 
00690     mInFile.read(reinterpret_cast<char *>(&tmpf), sizeof(float));
00691     mInFile.clear();
00692     if (fabs(tmpf - SPREAD_POW) > EPSILON)
00693     {
00694         strs << "SPREAD_POW constant differ from built in, expected: " << std::setprecision(8) << SPREAD_POW;
00695         strs << " got: " << std::setprecision(8) << tmpf;
00696         throw std::logic_error(strs.str());
00697     }
00698 
00699     mInFile.read(reinterpret_cast<char *>(&tmpf), sizeof(float));
00700     mInFile.clear();
00701     if (fabs(tmpf - SPREAD_MAX_V) > EPSILON)
00702     {
00703         strs << "SPREAD_MAX_V constant differ from built in, expected: " << std::setprecision(8) << SPREAD_MAX_V;
00704         strs << " got: " << std::setprecision(8) << tmpf;
00705         throw std::logic_error(strs.str());
00706     }
00707 
00708     mInFile.read(reinterpret_cast<char *>(&tmpf), sizeof(float));
00709     mInFile.clear();
00710     if (fabs(tmpf - FRAME_LENGTH) > EPSILON)
00711     {
00712         strs << "FRAME_LENGTH constant differ from built in, expected: " << std::setprecision(8) << FRAME_LENGTH;
00713         strs << " got: " << std::setprecision(8) << tmpf;
00714         throw std::logic_error(strs.str());
00715     }
00716 
00717     mLoadFile = file;
00718 }/*}}}*/
00719 
00720 

Generated on Fri Feb 1 00:01:42 2008 for Grayfall by  doxygen 1.5.1