src/vamos/world/World.cc

Go to the documentation of this file.
00001 //  Vamos Automotive Simulator
00002 //  Copyright (C) 2001--2004 Sam Varner
00003 //
00004 //  This program is free software; you can redistribute it and/or modify
00005 //  it under the terms of the GNU General Public License as published by
00006 //  the Free Software Foundation; either version 2 of the License, or
00007 //  (at your option) any later version.
00008 //
00009 //  This program is distributed in the hope that it will be useful,
00010 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 //  GNU General Public License for more details.
00013 //
00014 //  You should have received a copy of the GNU General Public License
00015 //  along with this program; if not, write to the Free Software
00016 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 
00018 #include <vamos/world/World.h>
00019 
00020 #include <cassert>
00021 
00022 using Vamos_Geometry::Three_Vector;
00023 using Vamos_Geometry::Three_Matrix;
00024 
00025 //-----------------------------------------------------------------------------
00026 Vamos_World::
00027 Times::Times () :
00028   m_current (0.0),
00029   m_previous (0.0),
00030   m_best (0.0),
00031   m_difference (0.0)
00032 {
00033 }
00034 
00035 void Vamos_World::
00036 Times::update (double time_step)
00037 {
00038   m_current += time_step;
00039 }
00040 
00041 void Vamos_World::
00042 Times::finalize ()
00043 {
00044   if (m_best != 0.0)
00045     {
00046       m_difference = m_current - m_best;
00047     }
00048 
00049   if ((m_current < m_best) || (m_best == 0.0))
00050     {
00051       m_best = m_current;
00052     }
00053 
00054   m_previous = m_current;
00055   m_current = 0.0;
00056 }
00057 
00058 void Vamos_World::
00059 Times::reset ()
00060 {
00061   m_current = 0.0;
00062 }
00063 
00064 //-----------------------------------------------------------------------------
00065 Vamos_World::
00066 Timing_Info::Timing_Info () :
00067   m_sector (-1),
00068   m_previous_sector (-1),
00069   m_distance (0.0)
00070 {
00071 }
00072 
00073 void Vamos_World::
00074 Timing_Info::update_sector_info (int sector)
00075 {
00076   if (sector == int (ma_sector_times.size ()))
00077     { // We're entering a sector for the first time.
00078       ma_sector_times.push_back (Times ());
00079     }
00080 
00081   if ((sector != m_sector) && (sector != -1))
00082     { // We have left a sector.
00083       if (m_sector != -1)
00084         {
00085           ma_sector_times [m_sector].finalize ();
00086           
00087           if (sector == 0)
00088             { // We have finished a lap.
00089               m_lap_times.finalize ();
00090             }
00091         }
00092       m_previous_sector = m_sector;
00093       m_sector = sector;
00094     }
00095 }
00096 
00097 void Vamos_World::
00098 Timing_Info::update_times (int sector, double time_step)
00099 {
00100   m_lap_times.update (time_step);
00101   if (sector != -1)
00102     {
00103       ma_sector_times [sector].update (time_step);
00104     }
00105 }
00106 
00107 void Vamos_World::
00108 Timing_Info::update (double time_step, double distance, int sector)
00109 {
00110   update_sector_info (sector);
00111   update_times (sector, time_step);
00112   m_distance = distance;
00113 }
00114 
00115 void Vamos_World::
00116 Timing_Info::reset ()
00117 {
00118   m_lap_times.reset ();
00119   ma_sector_times [m_sector].reset ();
00120 
00121   m_sector = -1;
00122   m_previous_sector = -1;
00123   m_distance = 0.0;
00124 }
00125 
00126 //-----------------------------------------------------------------------------
00127 void Vamos_World::
00128 Car_Information::reset ()
00129 {
00130   timing.reset ();
00131   segment_index = 0;
00132   car->reset ();
00133 }
00134 
00135 //-----------------------------------------------------------------------------
00136 Vamos_World::
00137 World::World (TRACK * track) 
00138   : m_focused_car_index (0),
00139     p_track (track),
00140     m_gravity (-9.8)
00141 {
00142 }
00143 
00144 extern bool verbose_output;
00145 
00146 Vamos_World::
00147 World::~World ()
00148 {
00149         if (verbose_output)
00150                 std::cout << "world deinit" << std::endl;
00151   for (std::vector <Car_Information>::iterator it = m_cars.begin ();
00152        it != m_cars.end ();
00153        it++)
00154     {
00155       delete it->car;
00156     }
00157         //std::cout << (void*)mp_track << std::endl;
00158         //delete mp_track;
00159         
00160         if (verbose_output)
00161                 std::cout << "world deinit done" << std::endl;
00162 }
00163 
00164 extern float FrameTime();
00165 
00166 void Vamos_World::
00167 World::interact (Vamos_Body::Car* car, size_t segment_index)
00168 {
00169         bool verbose = false;
00170         
00171         Vamos_Geometry::Material * tmatroad = new Vamos_Geometry::Material(
00172                 Vamos_Geometry::Material::ASPHALT, 1.0, 1.0,
00173                 1.0, 0.0, 
00174                 0.0, 0.0, 
00175                 0);
00176         Vamos_Geometry::Material * tmatwall = new Vamos_Geometry::Material(
00177                 Vamos_Geometry::Material::CONCRETE, 1.0, -0.8,
00178                 1.0, 0.0, 
00179                 0.0, 0.0, 
00180                 0);
00181         Vamos_Geometry::Material_Handle material = tmatroad;
00182         Vamos_Geometry::Material_Handle materialwall = tmatwall;
00183         
00184         size_t i;
00185         
00186         //do additional collisions for walls and stuff
00187         int loopcount = 0;
00188         bool col = true;
00189         const int maxloops = 4;
00190         while (col && loopcount < maxloops)
00191         {
00192                 loopcount++;
00193                 col = false;
00194                 //find the orientation of the car
00195                 QUATERNION rot;         
00196                 double angle;
00197                 Three_Vector aa = car->chassis().axis_angle(&angle);
00198                 //rot.SetAxisAngle(angle*(3.141593/180.0),aa[0],aa[1],aa[2]);
00199                 //rot.SetAxisAngle(angle*(3.141593/180), -aa[0], -aa[2], aa[1]);
00200                 //rot.Rotate(3.141593/2.0,0,1,0);
00201                 rot.SetAxisAngle(angle*(3.141593/180), aa[0], aa[2], -aa[1]);
00202                 
00203                 //find the position of the car
00204                 Three_Vector chassispos = car->chassis().position();
00205                 VERTEX cp;
00206                 cp.Set(chassispos[0],chassispos[2],-chassispos[1]);
00207                 
00208                 VERTEX cmv;
00209                 Vamos_Geometry::Three_Vector cm = car->chassis().center_of_mass();
00210                 cmv.Set(cm[0], cm[2], -cm[1]);
00211                 
00212                 //get the collision mesh
00213                 JOEMODEL * mod = car->GetCollisionModel();
00214                 if (mod != NULL)
00215                 {       
00216                         unsigned int nfaces = mod->GetFaces();
00217                         
00218                         //for the AABB calculation
00219                         float maxv[3];
00220                         float minv[3];
00221                         bool havevals[6];
00222                         int n = 0;
00223                         for (n = 0; n < 6; n++)
00224                                 havevals[n] = false;
00225                         
00226                         unsigned int f;
00227                         unsigned int v;
00228                         VERTEX modelfaces[nfaces*3];
00229                         for (f = 0; f < nfaces; f++)
00230                         {
00231                                 for (v = 0; v < 3; v++)
00232                                 {
00233                                         //transform the mesh faces to the world frame
00234                                         modelfaces[f*3+v].Set(mod->GetVert(mod->GetFace(f)[v]));
00235                                         //modelfaces[f*3+v].z = -modelfaces[f*3+v].z;
00236                                         modelfaces[f*3+v] = cp + rot.RotateVec(cmv.ScaleR(-1.0)) + 
00237                                                                                 rot.RotateVec(modelfaces[f*3+v]);
00238                                         
00239                                         //z mirror due to weirdness in the object code
00240                                         modelfaces[f*3+v].z = -modelfaces[f*3+v].z;
00241                                         
00242                                         //cache for bbox stuff
00243                                         for (n = 0; n < 3; n++)
00244                                         {
00245                                                 if (modelfaces[f*3+v].v3()[n] > maxv[n] || !havevals[n])
00246                                                 {
00247                                                         maxv[n] = modelfaces[f*3+v].v3()[n];
00248                                                         havevals[n] = true;
00249                                                 }
00250                                                 if (modelfaces[f*3+v].v3()[n] < minv[n] || !havevals[n+3])
00251                                                 {
00252                                                         minv[n] = modelfaces[f*3+v].v3()[n];
00253                                                         havevals[n+3] = true;
00254                                                 }
00255                                         }
00256                                 }
00257                         }
00258                         
00259                         //assign the world space AABB
00260                         AABB modelbbox;
00261                         VERTEX minvals, maxvals;
00262                         minvals.Set(minv);
00263                         maxvals.Set(maxv);
00264                         modelbbox.SetFromCorners(minvals, maxvals);
00265                         
00266                         VERTEX normal, colpt;
00267                         float depth;
00268                         
00269                         col = p_track->CollideModel(modelfaces, nfaces, modelbbox, colpt, false, normal, depth);
00270                         
00271                         if (verbose && col)
00272                         {
00273                                 float miny = 10000;
00274                                 for (f = 0; f < nfaces; f++)
00275                                 {
00276                                         for (v = 0; v < 3; v++)
00277                                         {
00278                                                 if (modelfaces[f*3+v].y < miny)
00279                                                         miny = modelfaces[f*3+v].y;
00280                                         }
00281                                 }
00282                                 
00283                                 cout << "Loop " << loopcount << endl;
00284                                 colpt.DebugPrint();
00285                                 cout << miny << endl;
00286                                 normal.DebugPrint();
00287                                 cout << "depth: " << depth << endl << endl;
00288                         }
00289                         
00290                         if (col && !colpt.nan() && !normal.nan() && (depth >= 0 || depth < 0))
00291                         {
00292                                 Three_Vector colpos;
00293                                 Three_Vector norm;
00294                                 
00295                                 //normal.y = 0;
00296                                 //normal = normal.normalize();
00297                                 
00298                                 norm.m_vec[0] = normal.x;
00299                                 norm.m_vec[1] = -normal.z;
00300                                 norm.m_vec[2] = normal.y;
00301                                 
00302                                 colpos.m_vec[0] = colpt.x;
00303                                 colpos.m_vec[1] = -colpt.z;
00304                                 colpos.m_vec[2] = colpt.y;
00305                                 
00306                                 car->chassis().single_point_contact(colpos, depth+0.001, norm, materialwall, FrameTime());
00307                         }
00308                 }
00309         }
00310         
00311         //keep the wheels on the track
00312         i = 0;
00313         int wheelcount = 0;
00314         for (i = 0; i < 4; i++)
00315                 car->SetColPatch(i, NULL);
00316         for (std::vector <Vamos_Body::Particle*>::iterator 
00317                  it = car->chassis ().particles ().begin ();
00318            it != car->chassis ().particles ().end ();
00319            it++, i++)
00320     {
00321         if (!(*it)->single_contact ())
00322                 {
00323                         const Three_Vector& pos = car->chassis ().contact_position (*it);
00324                         //const Three_Vector& lastpos = car->chassis ().last_contact_position (*it);
00325                         //double bump_parameter = car->distance_traveled () + (*it)->position () [0];
00326                         
00327                         VERTEX particlepos;
00328                         particlepos.Set(pos.m_vec[0],pos.m_vec[2],-pos.m_vec[1]);
00329                         
00330                         bool con = false;
00331                         Three_Vector norm;
00332                         double depth = 0;
00333                         VERTEX normal;
00334                         VERTEX origin = particlepos;
00335                         origin.y += 0.5;
00336                         BEZIER * tcolpatch = NULL;
00337                         OBJECTNODE * tcolnode = NULL;
00338                         depth = p_track->ElevationSeg(origin, normal, 10.0, tcolpatch, tcolnode) - particlepos.y;
00339                         
00340                         car->SetColPatch(wheelcount, tcolpatch);
00341                         
00342                         //calculate friction coefficients from collision data and track data
00343                         float f1 = 1.0;
00344                         float f2 = 1.0;
00345                         float rr = 1.0;
00346                         float rd = 0.0;
00347                         if (tcolpatch != NULL)
00348                         {
00349                                 p_track->GetFrictionParams(f1, f2);
00350                         }
00351                         else if (tcolnode != NULL)
00352                         {
00353                                 f1 = tcolnode->friction1;
00354                                 f2 = tcolnode->friction2;
00355                                 //cout << "Setting friction wheel " << wheelcount << " to " << f1 << "," << f2 << endl;
00356                         
00357                                 //add in bump effects                           
00358                                 float posx = origin.x;
00359                                 float posz = origin.z;
00360                                 float phase = 2*3.141593*(posx+posz) / tcolnode->bumplength;
00361                                 float shift = 2.0*sin(phase*1.414214);
00362                                 float amplitude = 0.25*tcolnode->bumpmag;
00363                                 float bumpoffset = amplitude * (sin (phase + shift) + sin (1.414214*phase) - 2.0);
00364                                 depth += bumpoffset;
00365                                 
00366                                 rr = tcolnode->rolling_resistance_factor;
00367                                 rd = tcolnode->rolling_drag;
00368                         }
00369                         car->SetColParams(wheelcount, f1, f2, rr, rd);
00370                         
00371                         wheelcount++;
00372 
00373                         //depth = p_track->Elevation(particlepos, normal) - particlepos.y;
00374                         
00375                         if (depth < 0 || depth >= 0)
00376                         {
00377                                 //depth = -particlepos.y;
00378                                 //normal.Set(0,1,0);
00379                                 if (depth > 0)
00380                                         con = true;
00381                                 norm.m_vec[0] = normal.x;
00382                                 norm.m_vec[1] = -normal.z;
00383                                 norm.m_vec[2] = normal.y;
00384                                 if (con)
00385                                 {
00386                                         if (depth > 1.0)
00387                                         {
00388                                                 cout << "Large suspension displacement detected: " << depth << endl;
00389                                         }
00390                                         
00391                                         //cout << p_track->Elevation(particlepos, normal) << endl;
00392                                         //cout << depth << endl;
00393                                         //particlepos.DebugPrint();     cout << endl;
00394                                         //Vamos_Geometry::Material_Handle mat = &info.material;
00395                                         car->chassis ().contact (*it, depth, 
00396                                                                                    norm, material);
00397                                         //car->chassis().propagate_contact();
00398                                 }
00399                         }
00400                         else
00401                                 cout << "Not contacting with NaN surface" << endl;
00402                 }
00403         }
00404         
00405         /*int loopcount = 0;
00406         int numcols = 1;
00407         const int maxloops = 50;
00408         while (numcols > 0 && loopcount < maxloops)
00409         {
00410                 loopcount++;
00411                 numcols = 0;
00412                 i = 0;
00413                 for (std::vector <Vamos_Body::Particle*>::iterator 
00414                          it = car->chassis ().particles ().begin ();
00415                    it != car->chassis ().particles ().end ();
00416                    it++, i++)
00417                 {       
00418                         if ((*it)->single_contact ())
00419                         {
00420                                 bool con = false;
00421                                 
00422                                 const Three_Vector& pos = car->chassis ().contact_position (*it);
00423                                 const Three_Vector& lastpos = car->chassis ().last_contact_position (*it);
00424                                 
00425                                 Three_Vector norm;
00426                                 double depth = 0;
00427                                 
00428                                 VERTEXD lastparticlepos;
00429                                 lastparticlepos.Set(lastpos.m_vec[0],lastpos.m_vec[2],-lastpos.m_vec[1]);
00430                                 
00431                                 VERTEXD particleposd;
00432                                 particleposd.Set(pos.m_vec[0],pos.m_vec[2],-pos.m_vec[1]);
00433                                 
00434                                 VERTEXD colpt;
00435                                 double coldist = 0;
00436                                 VERTEXD coldir;
00437                                 VERTEXD normald;
00438                                 coldir.Set(pos.m_vec[0]-lastpos.m_vec[0],pos.m_vec[2]-lastpos.m_vec[2],-(pos.m_vec[1]-lastpos.m_vec[1]));
00439                                 double seglen = coldir.len();
00440                                 //const float fluff = 0.5;
00441                                 const double fluff = 0.00001;
00442                                 if (seglen < fluff)
00443                                         seglen = fluff;
00444                                 //lastparticlepos = lastparticlepos - coldir.normalize().ScaleR(fluff/2.0);
00445                                 con = p_track->CollideD(lastparticlepos, coldir, seglen, colpt, true, normald, coldist);
00446                                 //con = p_track->Collide(lastparticlepos, particlepos, colpt, true, normal, coldist);
00447                                 //if (particleposd.y < 0)
00448                                 if (con)
00449                                 //while (con && numcols < 5)
00450                                 {
00451                                         //car->chassis ().roll_back();
00452                                         
00453                                         //normal.Scale(100.0);
00454                                         
00455                                         norm.m_vec[0] = normald.x;
00456                                         norm.m_vec[1] = -normald.z;
00457                                         norm.m_vec[2] = normald.y;
00458                                         
00459                                         depth = (seglen - coldist)*coldir.normalize().dot(normald.ScaleR(-1.0));
00460                                         //depth *= 2.0;
00461                                         //depth = seglen - coldist;
00462                                         //depth = - ((particleposd - colpt).dot(normald));
00463                                         depth += fluff;
00464                                         
00465                                         //depth = -particleposd.y;
00466                                         //normald.Set(0,1,0);
00467                                         
00468                                         if (verbose)
00469                                         {
00470                                                 cout << "Loop " << loopcount << endl;
00471                                                 cout << "Collision " << numcols << endl;
00472                                                 cout << "Particle " << i << endl;
00473                                                 particleposd.DebugPrint();
00474                                                 lastparticlepos.DebugPrint();
00475                                                 colpt.DebugPrint();
00476                                                 coldir.DebugPrint();
00477                                                 coldir.normalize().DebugPrint();
00478                                                 normald.DebugPrint();
00479                                                 cout << coldir.len() << endl;
00480                                                 cout << seglen << endl;
00481                                                 cout << (colpt - lastparticlepos).len() << endl;
00482                                                 cout << coldist << endl;
00483                                                 cout << "depth: " << depth << endl << endl;
00484                                         }
00485                                         
00486                                         if (depth >= 0)
00487                                         {
00488                                                 //roll back chassis state
00489                                                 //car->chassis ().roll_back();
00490                                                 
00491                                                 //depth = 1.0;
00492                                                 
00493                                                 numcols++;
00494                                                 
00495                                                 car->chassis ().contact (*it, depth, norm, materialwall);
00496                                                 car->chassis().propagate_contact();
00497                                                 //Three_Vector colpos;
00498                                                 //colpos.m_vec[0] = colpt.x;
00499                                                 //colpos.m_vec[1] = -colpt.z;
00500                                                 //colpos.m_vec[2] = colpt.y;
00501                                                 //car->chassis().single_point_contact(colpos, depth, norm, materialwall, FrameTime());
00502                                                 
00503                                                 //car->chassis().kill_vel();
00504 
00505                                         }
00506                                         else 
00507                                         {
00508                                                 con = false;
00509                                                 if (verbose)
00510                                                         cout << "weird collision depth" << endl << endl;
00511                                         }
00512                                 }
00513                         }
00514                 }
00515         }
00516         
00517         if (loopcount == maxloops)
00518         {
00519                 car->chassis().roll_back();
00520                 car->chassis().kill_vel();
00521         }*/
00522 
00523         // Handle air resistance.
00524         i = 0;
00525         for (std::vector <Vamos_Body::Particle*>::iterator 
00526                  it = car->chassis ().particles ().begin ();
00527            it != car->chassis ().particles ().end ();
00528            it++, i++)
00529         {
00530                 car->chassis ().wind (*it, Three_Vector(0,0,0)
00531                                                         - car->chassis ().velocity (*it),
00532                                         1.2);
00533         }
00534         
00535         /*for (std::vector <Vamos_Body::Particle*>::iterator 
00536                  it = car->chassis ().particles ().begin ();
00537            it != car->chassis ().particles ().end ();
00538            it++, i++)
00539     {
00540         const Three_Vector& pos = car->chassis ().contact_position (*it);
00541                 const Three_Vector& lastpos = car->chassis ().last_contact_position (*it);
00542         //double bump_parameter = car->distance_traveled () + (*it)->position () [0];
00543                 
00544         //Vamos_Track::Track_Contact_Info info = mp_track->test_for_contact (pos, bump_parameter, segment_index);
00545                 
00546                 VERTEX particlepos;
00547                 particlepos.Set(pos.m_vec[0],pos.m_vec[2],-pos.m_vec[1]);
00548                 
00549                 //keep the tires on the track
00550                 bool con = false;
00551                 Three_Vector norm;
00552                 Vamos_Geometry::Material * tmat = new Vamos_Geometry::Material;
00553                 Vamos_Geometry::Material_Handle material = tmat;
00554                 double depth = 0;
00555                 
00556                 //do additional collisions for walls and stuff
00557                 VERTEXD lastparticlepos;
00558                 lastparticlepos.Set(lastpos.m_vec[0],lastpos.m_vec[2],-lastpos.m_vec[1]);
00559                 
00560                 VERTEXD particleposd;
00561                 particleposd.Set(pos.m_vec[0],pos.m_vec[2],-pos.m_vec[1]);
00562                 
00563                 VERTEXD colpt;
00564                 double coldist;
00565                 VERTEXD coldir;
00566                 VERTEXD normald;
00567                 coldir.Set(pos.m_vec[0]-lastpos.m_vec[0],pos.m_vec[2]-lastpos.m_vec[2],-(pos.m_vec[1]-lastpos.m_vec[1]));
00568                 double seglen = coldir.len();
00569                 //const float fluff = 0.5;
00570                 const double fluff = 0.00001;
00571                 if (seglen < fluff)
00572                         seglen = fluff;
00573                 //lastparticlepos = lastparticlepos - coldir.normalize().ScaleR(fluff/2.0);
00574                 con = p_track->CollideD(lastparticlepos, coldir, seglen, colpt, false, normald, coldist);
00575                 //OLD con = p_track->Collide(lastparticlepos, particlepos, colpt, true, normal, coldist);
00576                 int numcols = 0;
00577                 //while (con && numcols < 5)
00578                 if (con)
00579                 {
00580                         //car->chassis ().roll_back();
00581                         
00582                         //normal.Scale(100.0);
00583                         
00584                         norm.m_vec[0] = normald.x;
00585                         norm.m_vec[1] = -normald.z;
00586                         norm.m_vec[2] = normald.y;
00587                         
00588                         depth = (seglen - coldist)*coldir.normalize().dot(normald.ScaleR(-1.0));
00589                         //depth *= 10.0;
00590                         //depth = seglen - coldist;
00591                         //depth = - ((particleposd - colpt).dot(normald));
00592                         depth += fluff;
00593                         
00594                         if (verbose)
00595                         //if (0)
00596                         {
00597                                 cout << "Second pass:  Collision " << count << " particle " << i << endl;
00598                                 if (numcols != 0)
00599                                         cout << "Sub-collision " << numcols << endl;
00600                                 particleposd.DebugPrint();
00601                                 lastparticlepos.DebugPrint();
00602                                 colpt.DebugPrint();
00603                                 coldir.DebugPrint();
00604                                 coldir.normalize().DebugPrint();
00605                                 normald.DebugPrint();
00606                                 cout << coldir.len() << endl;
00607                                 cout << seglen << endl;
00608                                 cout << (colpt - lastparticlepos).len() << endl;
00609                                 cout << coldist << endl;
00610                                 cout << "depth: " << depth << endl << endl;
00611                         }
00612                         
00613                         count++;
00614                         
00615                         if (depth >= 0)
00616                         {
00617                                 //roll back chassis state
00618                                 //car->chassis ().roll_back();
00619                                 
00620                                 //depth = 1.0;
00621                                 
00622                                 numcols++;
00623                                 
00624                                 car->chassis ().contact (*it, depth, 
00625                                                                    norm, materialwall);
00626                                 
00627                                 //car->chassis().propagate_contact();
00628                         }
00629                         //else if (verbose)     cout << "weird collision depth" << endl << endl;
00630                 }
00631         }*/
00632 }
00633 
00634 void Vamos_World::
00635 World::collide (Vamos_Body::Car* car1, Vamos_Body::Car* car2)
00636 {
00637   // Handle collisions between the contact points of car1 and the
00638   // crash box of car 2. 
00639   for (std::vector <Vamos_Body::Particle*>::iterator 
00640          it = car1->chassis ().particles ().begin ();
00641        it != car1->chassis ().particles ().end ();
00642        it++)
00643     {
00644       if (car2->collision (car1->chassis ().transform_out ((*it)->position ())))
00645         {
00646           std::cout << "boom" << std::endl;
00647         }
00648     }
00649 }
00650 void Vamos_World::
00651 World::reset ()
00652 {
00653         reset(false);
00654 }
00655 
00656 // Place the car back on the track at its current position.
00657 void Vamos_World::
00658 World::reset (bool all)
00659 {
00660         //if (all)
00661         {
00662                 for (std::vector <Vamos_World::Car_Information>::iterator carit = m_cars.begin ();
00663                            carit != m_cars.end ();
00664                            carit++)
00665                         reset(&(*carit));
00666         }
00667         //else reset(focused_car());
00668         
00669         /*if (all)
00670         {
00671                 for (std::vector <Vamos_World::Car_Information>::iterator carit = m_cars.begin ();
00672                    carit != m_cars.end ();
00673                    carit++)
00674                 {
00675 //                      size_t& segment_index = carit->segment_index;
00676                         
00677                           // Find the position and orientation specified by the track.
00678 //                        const Three_Vector& car_pos = carit->car->chassis ().position ();
00679                         Three_Matrix orientation(1.0);
00680                         orientation.identity();
00681                         VERTEX vpos = p_track->GetStart();
00682                         Three_Vector position(vpos.x, -vpos.z, vpos.y);
00683                         //const Three_Vector& position(p_track->GetStart().v3());
00684                         
00685                           // Adjust the vertical position so that at least one point on the
00686                           // car is in contact with the road, and the rest are above it.
00687                         
00688                           std::vector <Vamos_Body::Particle*>::iterator 
00689                                 it = carit->car->chassis ().particles ().begin (); 
00690                         
00691                           const Three_Vector& pos = 
00692                                 carit->car->chassis ().contact_position (*it);
00693                           double dist = carit->car->distance_traveled () 
00694                                 + (*it)->position () [0];
00695                           //double elevation = mp_track->elevation (pos, dist, segment_index);
00696                           VERTEX cp;
00697                           cp.Set(pos.m_vec[0], pos.m_vec[2], -pos.m_vec[1]);
00698                           double elevation = p_track->Elevation (cp);
00699                           double max_diff = elevation - pos [2];
00700                         
00701                           for (size_t i = 0; 
00702                                    it != carit->car->chassis ().particles ().end (); 
00703                                    it++, i++)
00704                                 {
00705                                   const Three_Vector& pos = 
00706                                         carit->car->chassis ().contact_position (*it);
00707                                   dist = carit->car->distance_traveled () 
00708                                         + (*it)->position () [0];
00709                                         
00710                                 cp.Set(pos.m_vec[0], pos.m_vec[2], -pos.m_vec[1]);
00711                                 elevation = p_track->Elevation (cp);
00712                                         
00713                         
00714                                   double diff = elevation - pos [2];
00715                                   if (diff > max_diff)
00716                                         {
00717                                           max_diff = diff;
00718                                         }
00719                                 }
00720                         
00721                           // Set the car's position and orientation.
00722                           carit->car->reset (position + Three_Vector (0.0, 0.0, max_diff), orientation);
00723                 }
00724         }
00725         else
00726         {
00727 //              size_t& segment_index = focused_car ()->segment_index;
00728                 
00729                 // Find the position and orientation specified by the track.
00730 //              const Three_Vector& car_pos = focused_car ()->car->chassis ().position ();
00731 
00732                 Three_Matrix orientation(1.0);
00733                 orientation.identity();
00734                 VERTEX vpos = p_track->GetStart();
00735                 Three_Vector position(vpos.x, -vpos.z, vpos.y);
00736                 
00737                 // Adjust the vertical position so that at least one point on the
00738                 // car is in contact with the road, and the rest are above it.
00739                 
00740                 std::vector <Vamos_Body::Particle*>::iterator 
00741                 it = focused_car ()->car->chassis ().particles ().begin (); 
00742                 
00743                 const Three_Vector& pos = 
00744                 focused_car ()->car->chassis ().contact_position (*it);
00745                 double dist = focused_car ()->car->distance_traveled () 
00746                 + (*it)->position () [0];
00747                 //double elevation = mp_track->elevation (pos, dist, segment_index);
00748                 
00749                 VERTEX cp;
00750                 cp.Set(pos.m_vec[0], pos.m_vec[2], -pos.m_vec[1]);
00751                 double elevation = p_track->Elevation (cp);
00752                 
00753                 double max_diff = elevation - pos [2];
00754                 
00755                 for (size_t i = 0; 
00756                    it != focused_car ()->car->chassis ().particles ().end (); 
00757                    it++, i++)
00758                 {
00759                   const Three_Vector& pos = 
00760                         focused_car ()->car->chassis ().contact_position (*it);
00761                   dist = focused_car ()->car->distance_traveled () 
00762                         + (*it)->position () [0];
00763                         
00764                         cp.Set(pos.m_vec[0], pos.m_vec[2], -pos.m_vec[1]);
00765                         elevation = p_track->Elevation (cp);
00766                 
00767                   double diff = elevation - pos [2];
00768                   if (diff > max_diff)
00769                         {
00770                           max_diff = diff;
00771                         }
00772                 }
00773                 
00774                 // Set the car's position and orientation.
00775                 focused_car ()->car->reset (position + Three_Vector (0.0, 0.0, max_diff), orientation);
00776         }*/
00777 }
00778 
00779 void Vamos_World:: 
00780 World::reset (Car_Information * cartoreset)
00781 {
00782 //      size_t& segment_index = cartoreset->segment_index;
00783                 
00784         // Find the position and orientation specified by the track.
00785 //      const Three_Vector& car_pos = cartoreset->car->chassis ().position ();
00786         /*const Three_Vector& position = 
00787         mp_track->reset_position (car_pos, segment_index);
00788         const Three_Matrix& orientation = 
00789         mp_track->reset_orientation (car_pos, segment_index);*/
00790         
00791         VERTEX vpos = p_track->GetStart();
00792         Three_Vector position(vpos.x, -vpos.z, vpos.y);
00793         
00794         QUATERNION qstart;
00795         /*qstart = p_track->GetStartOrientation();
00796         //qstart = qstart.ReturnConjugate();
00797         //qstart.Rotate(3.141593/2.0, 0,0,1);
00798         //qstart.Rotate(3.141593/2.0, 0,1,0);
00799         //qstart.Rotate(-3.141593/2.0, 1,0,0);
00800         //qstart.Rotate(3.141593/2.0, 0,1,0);
00801         qstart.Rotate(-3.141593/2.0, 1,0,0);
00802         QUATERNION goofyfoot;
00803         goofyfoot.Rotate(3.141593/2.0, 1,0,0);
00804         qstart.Multiply(goofyfoot);*/
00805         
00806         double o3x3[3][3];
00807         float orient[16];
00808         
00809         qstart = p_track->GetStartOrientation();
00810         QUATERNION qtemp = qstart;
00811         qstart.x = qtemp.x;
00812         qstart.y = qtemp.z;
00813         qstart.z = -qtemp.y;
00814         
00815         qstart.Rotate(-3.141593/2.0, 0,0,1);
00816         
00817         qstart.GetMat(orient);
00818         bool flip = false;
00819         for (int i = 0; i < 3; i++)
00820         {
00821                 if (flip)
00822                 o3x3[i][0] = orient[i+0];
00823                 else
00824                 o3x3[0][i] = orient[i+0];
00825         }
00826         for (int i = 0; i < 3; i++)
00827         {
00828                 if (flip)
00829                 o3x3[i][1] = orient[i+4];
00830                 else
00831                 o3x3[1][i] = orient[i+4];
00832         }
00833         for (int i = 0; i < 3; i++)
00834         {
00835                 if (flip)
00836                 o3x3[i][2] = orient[i+8];
00837                 else
00838                 o3x3[2][i] = orient[i+8];
00839         }
00840         //Three_Matrix orientation(1.0);
00841         //orientation.identity();
00842         Three_Matrix orientation(o3x3);
00843         
00844         cartoreset->car->reset (position, orientation);
00845         
00846         // Adjust the vertical position so that at least one point on the
00847         // car is in contact with the road, and the rest are above it.
00848         
00849         
00850         
00851         //Three_Vector mpos = 
00852                 //cartoreset->car->chassis ().contact_position (*it);
00853         //double mdist = cartoreset->car->distance_traveled () 
00854                 //+ (*it)->position () [0];
00855         //double elevation = mp_track->elevation (pos, dist, segment_index);
00856         
00857         VERTEX cp;
00858         //cp.Set(mpos.m_vec[0], mpos.m_vec[2], -mpos.m_vec[1]);
00859         double elevation;
00860         //elevation = p_track->Elevation (cp);
00861                 
00862         //double max_diff = elevation - mpos [2];
00863         bool have_max = false;
00864         double max_diff = 0.0;
00865         
00866         //const Three_Vector& car_pos = cartoreset->car->chassis ().position ();
00867         
00868         for (std::vector <Vamos_Body::Particle*>::iterator it = 
00869                 cartoreset->car->chassis ().particles ().begin (); 
00870            it != cartoreset->car->chassis ().particles ().end (); 
00871            it++)
00872         {
00873           Three_Vector pos = 
00874                 cartoreset->car->chassis ().contact_position (*it);
00875           //dist = cartoreset->car->distance_traveled () 
00876                 //+ (*it)->position () [0];
00877           //elevation = mp_track->elevation (pos, dist, segment_index);
00878                 
00879                 cp.Set(pos.m_vec[0], pos.m_vec[2], -pos.m_vec[1]);
00880                 elevation = p_track->Elevation (cp);
00881         
00882                 double diff = elevation - pos [2];
00883                 //double diff = pos[2];
00884                 if (diff > max_diff || !have_max)
00885                 {
00886                         max_diff = diff;
00887                         have_max = true;
00888                 }
00889                 
00890                 //cout << diff << endl;
00891         }
00892         
00893         // Set the car's position and orientation.
00894         cartoreset->car->reset (position + Three_Vector (0.0, 0.0, max_diff+0.0), orientation);
00895         //cartoreset->car->reset (position, orientation);
00896         //cout << max_diff << endl;
00897 }
00898 
00899 // Place the car back on the track at the starting line.
00900 void Vamos_World::
00901 World::restart ()
00902 {
00903   focused_car ()->reset ();
00904 }
00905 
00906 // Set the acceleration due to gravity.  Always downward, regardless
00907 // of sign.
00908 void Vamos_World::
00909 World::gravity (double g)
00910 {
00911   m_gravity = -std::abs (g);
00912   if (focused_car () != 0)
00913     {
00914       focused_car ()->car->chassis ().
00915         gravity (Three_Vector (0.0, 0.0, m_gravity));
00916     }
00917 }
00918 
00919 void Vamos_World::
00920 World::add_car (Vamos_Body::Car* car)
00921 {
00922   car->chassis ().gravity (Three_Vector (0.0, 0.0, m_gravity));
00923   m_cars.push_back (Car_Information (car));
00924 }
00925 
00926 void Vamos_World::
00927 World::set_focused_car (size_t index)
00928 {
00929   assert (index < m_cars.size ());
00930   m_focused_car_index = index;
00931 }
00932 
00933 void Vamos_World::
00934 World::focus_other_car (int delta)
00935 {
00936   set_focused_car ((m_focused_car_index + delta) % m_cars.size ());
00937 }
00938 
00939 Vamos_World::Car_Information* Vamos_World::
00940 World::focused_car ()
00941 {
00942   if (m_focused_car_index >= m_cars.size ()) return 0;
00943   return &m_cars [m_focused_car_index];
00944 }

Generated on Thu Oct 19 04:05:56 2006 by  doxygen 1.4.6