src/vamos/body/Gl_Car.cc

Go to the documentation of this file.
00001 //  Gl_Car.cc - a car that handles graphics, sound and input devices.
00002 //
00003 //  Copyright (C) 2001--2004 Sam Varner
00004 //
00005 //  This program is free software; you can redistribute it and/or modify
00006 //  it under the terms of the GNU General Public License as published by
00007 //  the Free Software Foundation; either version 2 of the License, or
00008 //  (at your option) any later version.
00009 //
00010 //  This program is distributed in the hope that it will be useful,
00011 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 //  GNU General Public License for more details.
00014 //
00015 //  You should have received a copy of the GNU General Public License
00016 //  along with this program; if not, write to the Free Software
00017 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 
00019 #include <vamos/body/Gl_Car.h>
00020 //#include <vamos/geometry/Ac3d.h>
00021 #include <vamos/geometry/Conversions.h>
00022 #include <vamos/body/Fuel_Tank.h>
00023 #include <vamos/body/Gauge.h>
00024 #include <vamos/body/Wheel.h>
00025 
00026 //#include <GL/glut.h>
00027 
00028 #include <algorithm>
00029 #include <iomanip>
00030 #include <sstream>
00031 #include <string>
00032 
00033 using namespace Vamos_Geometry;
00034 
00035 //* Struct Rear_View_Mirror
00036 
00037 //** Constructor
00038 Vamos_Body::
00039 Rear_View_Mirror::Rear_View_Mirror (const Three_Vector& position,
00040                                                                         double width, double height,
00041                                                                         double direction,
00042                                                                         double field,
00043                                                                         double near_plane, double far_plane,
00044                                                                         std::string mask_file) :
00045   m_position (position),
00046   m_width (width),
00047   m_height (height),
00048   m_direction (direction),
00049   m_field (field),
00050   m_near_plane (near_plane),
00051   m_far_plane (far_plane),
00052   mp_mask (new Gl_Texture_Image (mask_file, false, false))
00053 {
00054 }
00055 
00056 //** Destructor
00057 Vamos_Body::
00058 Rear_View_Mirror::~Rear_View_Mirror ()
00059 {
00060   delete mp_mask;
00061 }
00062 
00063 void Vamos_Body::
00064 Rear_View_Mirror::activate_viewport ()
00065 {
00066   glViewport (m_viewport.x, m_viewport.y, m_viewport.width, m_viewport.height);
00067   glScissor (m_viewport.x, m_viewport.y, m_viewport.width, m_viewport.height);
00068 }
00069 
00070 Three_Vector Vamos_Body::
00071 Rear_View_Mirror::get_center () const
00072 {
00073   return Three_Vector (m_position [0], 
00074                                            m_position [1] - m_width / 2.0,
00075                                            m_position [2] + m_height / 2.0);
00076 }
00077 
00078 void Vamos_Body::
00079 Rear_View_Mirror::transform_view () const
00080 {
00081   glMatrixMode (GL_PROJECTION);
00082   glLoadIdentity ();
00083   // Reflect the x-axis.
00084   glScaled (-1.0, 1.0, 1.0);
00085   gluPerspective (m_field, m_viewport.aspect (), m_near_plane, m_far_plane);
00086 }
00087 
00088 void Vamos_Body::
00089 Rear_View_Mirror::set_view ()
00090 {
00091   activate_viewport ();
00092   glClear (GL_DEPTH_BUFFER_BIT);
00093   transform_view ();
00094 }
00095 
00096 //* Class Gl_Car
00097 
00098 extern bool verbose_output;
00099 
00100 //** Constructor
00101 Vamos_Body::
00102 Gl_Car::Gl_Car (const Three_Vector& pos)
00103   : Car (pos),
00104         mp_engine_sample (0),
00105         mp_dashboard (0)
00106 {
00107         if (verbose_output)
00108                 std::cout << "gl_car init" << std::endl;
00109         int i;
00110         for (i = 0; i < 4; i++)
00111                 tire_source[i] = 0;
00112         
00113         num_paintjobs = 0;
00114 }
00115 
00116 //** Destructor
00117 Vamos_Body::
00118 Gl_Car::~Gl_Car ()
00119 {
00120         if (verbose_output)
00121                 std::cout << "gl_car deinit" << std::endl;
00122         
00123         //FSOUND_StopSound(real_engine_sample);
00124         
00125         //commenting this out stops an error when a spinning car widget changes cars
00126         /*sound.StopSource(real_engine_sample);
00127         
00128         int i;
00129         for (i = 0; i < 4; i++)
00130                 sound.StopSource(tire_source[i]);*/
00131         
00132         /*if (m_body_list_id != 0)
00133         {
00134           glDeleteLists (m_body_list_id, 1);
00135         }
00136   if (m_interior_list_id != 0)
00137         {
00138           glDeleteLists (m_interior_list_id, 1);
00139         }*/
00140         
00141   delete mp_engine_sample;
00142 
00143   delete mp_dashboard;
00144 
00145   for (std::vector <Rear_View_Mirror*>::iterator it = m_mirrors.begin ();
00146            it != m_mirrors.end ();
00147            it++)
00148         {
00149           delete *it;
00150         }
00151         
00152         //textures.Delete(shadowtex);
00153         //string tex_size = "";
00154         //settings.Get( "display.texture_size", tex_size );
00155         //textures.Delete(settings.GetFullDataPath("cars/" + m_car_file + "/textures/" + tex_size  + "/shadow.png"));
00156         shadowtex.Unload();
00157         
00158         //glDeleteTextures(1, &shadowtex);
00159 }
00160 
00161 void Vamos_Body::
00162 Gl_Car::exterior_model (std::string file, double scale, 
00163                                                 const Three_Vector& translation,
00164                                                 const Three_Vector& rotation)
00165 {
00166   /*if (m_body_list_id != 0)
00167         {
00168           glDeleteLists (m_body_list_id, 1);
00169         }*/
00170 
00171    //Ac3d model (file, scale, translation, rotation);
00172    //m_body_list_id = model.build ();
00173         string tex_size = "";
00174         settings.Get( "display.texture_size", tex_size );
00175         //shadowtex = textures.Load(settings.GetFullDataPath("cars/" + m_car_file + "/textures/" + tex_size  + "/shadow.png"), false);
00176         shadowtex.Load(settings.GetFullDataPath("cars/" + m_car_file + "/textures/" + tex_size  + "/shadow.png"), false);
00177         joeglass.Load(settings.GetFullDataPath("cars/" + m_car_file + "/glass.joe"));
00178         joeglass.AdditiveTexture(settings.GetFullDataPath("cars/" + m_car_file + "/brake-glass.joe"), 1);
00179         joeglass.Load(settings.GetFullDataPath("cars/" + m_car_file + "/glass.joe"));
00180         joeglass.AdditiveTexture(settings.GetFullDataPath("cars/" + m_car_file + "/brake-glass.joe"), 1);
00181         joeexterior.Load(settings.GetFullDataPath("cars/" + m_car_file + "/body.joe"));
00182         joeexterior.AdditiveTexture(settings.GetFullDataPath("cars/" + m_car_file + "/brake.joe"), 1);
00183         
00184         joecollision.Load(settings.GetFullDataPath("cars/" + m_car_file + "/collision.joe"));
00185         
00186         //check for paint jobs
00187         char texfile[1024];
00188         int count = 0;
00189         sprintf(texfile, "cars/%s/textures/%s/body%02i.png", m_car_file.c_str(), tex_size.c_str(), count);
00190         while (count < 99 && utility.FileExists(settings.GetFullDataPath(texfile)))
00191         {
00192                 count++;
00193                 sprintf(texfile, "cars/%s/textures/%s/body%02i.png", m_car_file.c_str(), tex_size.c_str(), count);
00194         }
00195         num_paintjobs = count;
00196 }
00197 
00198 void Vamos_Body::
00199 Gl_Car::interior_model (std::string file, double scale, 
00200                                                 const Three_Vector& translation,
00201                                                 const Three_Vector& rotation)
00202 {
00203   /*if (m_interior_list_id != 0)
00204         {
00205           glDeleteLists (m_interior_list_id, 1);
00206         }
00207 
00208    Ac3d model (file, scale, translation, rotation);
00209    m_interior_list_id = model.build ();*/
00210         
00211         //joeinterior.Load(file);
00212         joeinterior.Load(settings.GetFullDataPath("cars/" + m_car_file + "/interior.joe"));
00213 }
00214 
00215 void Vamos_Body::
00216 Gl_Car::set_perspective (double aspect)
00217 {
00218   gluPerspective (m_field_of_view, aspect, m_near_plane, m_far_plane);
00219 }
00220 
00221 void Vamos_Body::
00222 Gl_Car::set_view (const Vamos_Geometry::Three_Vector& position,
00223                                   double field_of_view,
00224                                   double near_plane, double far_plane,
00225                                   double pan_angle)
00226 {
00227   m_driver_view = position;
00228   m_field_of_view = field_of_view;
00229   m_near_plane = near_plane;
00230   m_far_plane = far_plane;
00231   m_pan_angle = pan_angle;
00232 }
00233 
00234 void Vamos_Body::
00235 Gl_Car::add_rear_view (const Vamos_Geometry::Three_Vector& position,
00236                                            double width, double height,
00237                                            double direction, double field,
00238                                            double near_plane, double far_plane,
00239                                            std::string mask_file)
00240 {
00241   m_mirrors.push_back (new Rear_View_Mirror (position, width, height,
00242                                                                                          direction, field, 
00243                                                                                          near_plane, far_plane,
00244                                                                                          mask_file));
00245 }
00246 
00247 
00248 // Fill the stencil buffer for masking the rear-view mirrors.
00249 void Vamos_Body::
00250 Gl_Car::make_rear_view_mask (int window_width, int window_height)
00251 {
00252   glMatrixMode (GL_PROJECTION);
00253   glLoadIdentity ();
00254 
00255   glViewport (0, 0, window_width, window_height);
00256   glScissor (0, 0, window_width, window_height);
00257 
00258   glClearColor (0.0, 0.0, 0.0, 0.0);
00259   glClearStencil (0);
00260   glClear (GL_COLOR_BUFFER_BIT 
00261                    | GL_DEPTH_BUFFER_BIT
00262                    | GL_STENCIL_BUFFER_BIT);
00263 
00264   const double near_plane = 0.2;
00265   const double far_plane = 10.0;
00266   gluPerspective (field_of_view (), double (window_width)/window_height, 
00267                                   near_plane, far_plane);
00268   view (0.0);
00269   glMatrixMode (GL_MODELVIEW);
00270   transform_body ();
00271 
00272   for (std::vector <Rear_View_Mirror*>::iterator it = m_mirrors.begin ();
00273            it != m_mirrors.end ();
00274            it++)
00275         {
00276           (*it)->make_mask (window_width, window_height,
00277                                                 m_driver_view, field_of_view ());
00278         }
00279 }
00280 
00281 
00282 // Put a mask for one rear-view mirror in the stencil buffer.
00283 void Vamos_Body::
00284 Rear_View_Mirror::make_mask (int window_width, int window_height,
00285                                                          const Three_Vector& driver_position, 
00286                                                          double driver_field_of_view)
00287 {
00288   glDisable (GL_LIGHTING);
00289   set_viewport (window_width, window_height, 
00290                                 driver_position, driver_field_of_view);
00291   draw_mask_shape ();
00292   set_stencil (window_width, window_height);
00293   glEnable (GL_LIGHTING);
00294 }
00295 
00296 
00297 // Find the dimensions for a viewport that's just large enough to hold
00298 // the mirror.
00299 void Vamos_Body::
00300 Rear_View_Mirror::set_viewport (int window_width, int window_height, 
00301                                                                 const Three_Vector& driver_position,
00302                                                                 double driver_field_of_view)
00303 {
00304   const Three_Vector pos = m_position - driver_position;
00305   const double y_factor = 
00306         -1.0 / (pos [0] * tan (0.5 * deg_to_rad (driver_field_of_view)));
00307   const double aspect = double (window_width) / window_height;
00308   const double x_factor = -y_factor / aspect;
00309 
00310   const int x0 = to_pixels (window_width, x_factor, pos [1]) - 1;
00311   m_viewport.x = clip (x0, 0, window_width - 1);
00312   const int y0 = to_pixels (window_height, y_factor, pos [2]) - 1;
00313   m_viewport.y = clip (y0, 0, window_height - 1);
00314 
00315   const int x1 = to_pixels (window_width, x_factor, pos [1] - m_width);
00316   m_viewport.width = clip (x1, 0, window_width - 1) - m_viewport.x;
00317   const int y1 = to_pixels (window_height, y_factor, pos [2] + m_height);
00318   m_viewport.height = clip (y1, 0, window_height - 1) - m_viewport.y;
00319 }
00320 
00321 
00322 // Draw the mask.
00323 void Vamos_Body::
00324 Rear_View_Mirror::draw_mask_shape ()
00325 {
00326   glStencilFunc (GL_ALWAYS, 1, 1);
00327   glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
00328 
00329   mp_mask->activate ();
00330 
00331   glColor3d (1.0, 1.0, 1.0);
00332   glBegin (GL_QUADS);
00333   glTexCoord2d (0.0, 1.0);
00334   glVertex3d (m_position [0], m_position [1], m_position [2]);
00335   glTexCoord2d (1.0, 1.0);
00336   glVertex3d (m_position [0], m_position [1] - m_width, m_position [2]);
00337   glTexCoord2d (1.0, 0.0);
00338   glVertex3d (m_position [0], m_position [1] - m_width, 
00339                           m_position [2] + m_height);
00340   glTexCoord2d (0.0, 0.0);
00341   glVertex3d (m_position [0], m_position [1], m_position [2] + m_height);
00342   glEnd ();
00343 
00344   glFlush ();
00345 }
00346 
00347 
00348 // Use the pixels in the viewport to set the stencil buffer.
00349 void Vamos_Body::
00350 Rear_View_Mirror::set_stencil (int window_width, int window_height)
00351 {
00352   unsigned char* stencil_buffer = make_stencil_buffer ();
00353 
00354   glMatrixMode (GL_PROJECTION);
00355   glPushMatrix ();
00356   glLoadIdentity ();
00357   gluOrtho2D (0.0, double (window_width), 0.0, double (window_height));
00358   glMatrixMode (GL_MODELVIEW);
00359   glPushMatrix ();
00360   glLoadIdentity ();
00361   glStencilFunc (GL_EQUAL, 1, 1);
00362   glStencilOp (GL_KEEP, GL_REPLACE, GL_REPLACE);
00363   glRasterPos2i (m_viewport.x, m_viewport.y);
00364   glDrawPixels (m_viewport.width, m_viewport.height, GL_STENCIL_INDEX,
00365                                 GL_UNSIGNED_BYTE, stencil_buffer);
00366   glPopMatrix ();
00367 
00368   glMatrixMode (GL_PROJECTION);
00369   glPopMatrix ();
00370 
00371   glFinish ();
00372 
00373   delete stencil_buffer;
00374 }
00375 
00376 
00377 // Grab the current buffer as an array of pixels.
00378 unsigned char* Vamos_Body::
00379 Rear_View_Mirror::make_stencil_buffer ()
00380 {
00381   glReadBuffer (GL_BACK);
00382   const size_t elements = m_viewport.width * m_viewport.height;
00383   unsigned char* rgba_buffer = new unsigned char [4 * elements];
00384 
00385   glReadPixels (m_viewport.x, m_viewport.y, 
00386                                 m_viewport.width, m_viewport.height, 
00387                                 GL_RGBA, GL_UNSIGNED_BYTE, rgba_buffer);
00388 
00389   unsigned char* buffer = new unsigned char [elements];
00390   for (size_t i = 0; i < elements; i++)
00391         {
00392           buffer [i] = rgba_buffer [4 * i];
00393         }
00394   delete rgba_buffer;
00395   return buffer;
00396 }
00397 
00398 
00399 void Vamos_Body::
00400 Gl_Car::draw_rear_view (double aspect, int index)
00401 {
00402   Rear_View_Mirror* mirror = m_mirrors [index];
00403   mirror->set_view ();
00404   view (mirror->get_direction (), mirror->get_center ());
00405 }
00406 
00407 // Set the dashboard.
00408 void Vamos_Body::
00409 Gl_Car::dashboard (Dashboard* dash)
00410 {
00411   delete mp_dashboard;
00412   mp_dashboard = dash;
00413 }
00414 
00415 extern GLfloat LightPosition[4];
00416 #include "quat.h"
00417 
00418 void Vamos_Body::
00419 Gl_Car::transform_body ()
00420 {
00421   // Set the modelview matrix to be the identity matrix
00422   //glLoadIdentity ();
00423   
00424   // Translate and rotate the graphical representation of the object
00425   Three_Vector cm = m_chassis.position ();
00426   glTranslatef (cm [0], cm [1], cm [2]);
00427   
00428   double angle;
00429   Three_Vector axis = m_chassis.axis_angle (&angle);
00430         
00431         
00432         
00433         
00434         
00435   glRotatef (angle, axis [0], axis [1], axis [2]);
00436 
00437 
00438   
00439   // The rotation is performed about the origin of the body
00440   // system.  Since we want the effect to be a rotation about the
00441   // center of mass, we have to translate the object the distance
00442   // from the cm to the origin.
00443   cm = -m_chassis.center_of_mass ();
00444   glTranslatef (cm [0], cm [1], cm [2]);
00445   
00446         QUATERNION carrot;
00447         carrot.SetAxisAngle(angle*3.141593/180.0, axis[0], axis[2], axis[1]);
00448         QUATERNION goofyfoot;
00449         goofyfoot.Rotate(-3.141593/2.0, 1,0,0);
00450         double tempmat[16];
00451         goofyfoot.GetMat(tempmat);
00452         float lp[4];
00453         lp[0] = LightPosition[0];
00454         lp[1] = LightPosition[1];
00455         lp[2] = LightPosition[2];
00456         lp[3] = 0;
00457         VERTEX lpv;
00458         lpv.Set(lp);
00459         //goofyfoot.PostMultiply(carrot);
00460         lpv = goofyfoot.ReturnConjugate().RotateVec(lpv);
00461         lpv = carrot.ReturnConjugate().RotateVec(lpv);
00462         lp[0] = lpv.x;
00463         lp[1] = lpv.z;
00464         lp[2] = lpv.y;
00465         //glLightfv( GL_LIGHT1, GL_POSITION,  lp);
00466 }
00467 
00468 // Render the car according to its current position and orientation.
00469 void Vamos_Body::
00470 Gl_Car::draw (bool transform, float opacity)
00471 {
00472 //  if (m_body_list_id != 0)
00473         {
00474                 if (transform)
00475                         transform_body ();
00476 
00477           // Draw the body.
00478           //glCallList (m_body_list_id);
00479                 //joeexterior.Draw(0, 0);
00480                 
00481                 glPushAttrib(GL_ALL_ATTRIB_BITS);
00482                 //glDisable(GL_LIGHTING);
00483                 //glDepthMask(0);
00484                 
00485                 bool illum = false;
00486                 if (brakesetting != 0)
00487                         illum = true;
00488                 
00489                 //utility.SelectTU(1);
00490                 //glEnable(GL_TEXTURE_2D);
00491                 //utility.SelectTU(0);
00492 
00493                 //putting tree shadows on the car doesn't work because the car's vertices
00494                 // are in local space, not world space
00495                 /*if (utility.numTUs() > 3 && state.GetTreeDetail() != "Off" && state.GetTreeDetail() != "FoliageOnly")
00496                 {
00497                         utility.SelectTU(3);
00498                         glEnable(GL_TEXTURE_2D);
00499                         glBindTexture(GL_TEXTURE_2D, trees.GetCompositeShadow());
00500                         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
00501                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
00502                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
00503                         glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB,GL_MODULATE);
00504                         glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1);
00505                 }*/
00506                 
00507                 glColor4f(1,1,1,opacity);
00508                 //glColor4f(0.5,0,0,opacity);
00509                 glEnable(GL_BLEND);
00510                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00511                 glCullFace(GL_FRONT);
00512                 glEnable(GL_CULL_FACE);
00513                 //joecollision.DrawStatic();
00514                 joeexterior.SetTU(1, illum);
00515                 joeexterior.DrawStatic();
00516                 
00517                 glCullFace(GL_BACK);
00518                 glColor4f(0,0,0,opacity);
00519                 joeexterior.DrawStatic();
00520                 
00521                 glColor4f(1,1,1,opacity);
00522                 glDisable(GL_CULL_FACE);
00523                 
00524                 joeinterior.DrawStatic();
00525                 
00526                 // Draw the wheels.
00527                   std::for_each (m_wheels.begin (), m_wheels.end (),
00528                                                  std::mem_fun (&Wheel::draw));
00529                 
00530                 //utility.SelectTU(1);
00531                 //glEnable(GL_TEXTURE_2D);
00532                 utility.SelectTU(0);
00533                 
00534                 glEnable(GL_CULL_FACE);
00535                 glEnable(GL_BLEND);
00536                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00537                 glCullFace(GL_FRONT);
00538                 glEnable(GL_CULL_FACE);
00539                 glDepthMask(0);
00540                 glColor4f(1,1,1,opacity);
00541                 joeglass.SetTU(1, illum);
00542                 joeglass.DrawStatic();
00543                 //joeglass.DrawStatic();
00544                 glDepthMask(1);
00545 
00546                 glPopAttrib();
00547                 
00548                 utility.SelectTU(3);
00549                 glDisable(GL_TEXTURE_2D);
00550                 utility.SelectTU(1);
00551                 glDisable(GL_TEXTURE_2D);
00552                 utility.SelectTU(0);
00553         }
00554 }
00555 
00556 void Vamos_Body::
00557 Gl_Car::draw_interior ()
00558 {
00559   //joeinterior.Draw();
00560   draw_dashboard ();
00561 }
00562 
00563 TEXTURE_HANDLE * Vamos_Body::
00564 Gl_Car::shadow_texture()
00565 {return &shadowtex;}
00566 
00567 void Vamos_Body::
00568 Gl_Car::draw_dashboard ()
00569 {
00570   mp_dashboard->set_tachometer (rad_s_to_rpm (engine ()->rotational_speed ()));
00571   mp_dashboard->set_speedometer (m_s_to_km_h (wheel (2)->speed ()));
00572   mp_dashboard->set_fuel_gauge (fuel_tank ()->fuel ());
00573   mp_dashboard->set_gear_indicator (transmission ()->gear ());
00574   mp_dashboard->set_steering_wheel (m_steer_key_control.value ());
00575 
00576   mp_dashboard->draw ();
00577   if (m_show_dashboard_extras)
00578         {
00579           draw_dashboard_extras ();
00580         }
00581 }
00582 
00583 void Vamos_Body::
00584 Gl_Car::draw_string (const std::string& str, double x, double y)
00585 {
00586         font.Print(x, y, str.c_str(), 1, 5, 1);
00587   /*glRasterPos2d (x, y);
00588   for (std::string::const_iterator it = str.begin (); it != str.end (); it++)
00589         {
00590           glutBitmapCharacter (GLUT_BITMAP_8_BY_13, *it);
00591         }*/
00592 }
00593 
00594 void Vamos_Body::
00595 Gl_Car::draw_dashboard_extras ()
00596 { 
00597   glMatrixMode (GL_PROJECTION);
00598   glPushMatrix ();
00599   glLoadIdentity ();
00600 
00601   // Set the dimensions of the drawing area.
00602   gluOrtho2D (0, 10, 0, 10);
00603   glMatrixMode (GL_MODELVIEW);
00604   glPushMatrix ();
00605   glLoadIdentity ();
00606   
00607   glDisable (GL_DEPTH_TEST);
00608   glDisable (GL_LIGHTING);
00609   glDisable (GL_TEXTURE_2D);
00610   
00611   glColor3f (1.0, 1.0, 1.0);
00612 
00613   std::ostringstream b_stream;
00614 
00615   int rpm = 
00616         int (Vamos_Geometry::rad_s_to_rpm (engine ()->rotational_speed ()));
00617   b_stream << "RPM " << rpm;
00618   draw_string (b_stream.str (), 0.4, 1.8);
00619 
00620   b_stream.str ("");
00621   b_stream << "Torque " << int (engine ()->drive_torque ()) << " Nm";
00622   draw_string (b_stream.str (), 0.4, 1.4);
00623 
00624   b_stream.str ("");
00625   b_stream << "Speed " << int (m_s_to_km_h (wheel (2)->speed ()))
00626                    << " km/h";
00627   draw_string (b_stream.str (), 0.4, 1.0);
00628 
00629   b_stream.str ("");
00630   b_stream << "Mass " << int (m_chassis.mass ()) << " kg";
00631   draw_string (b_stream.str (), 0.4, 0.6);
00632 
00633   b_stream.str ("");
00634   char gear = 'N';
00635   if (transmission ()->gear () == -1)
00636         {
00637           gear = 'R';
00638         }
00639   else if (transmission ()->gear () > 0)
00640         {
00641           gear = transmission ()->gear () + '0';
00642         }
00643   b_stream << "Gear " << gear;
00644   draw_string (b_stream.str (), 0.4, 0.2);
00645 
00646   b_stream.str ("");
00647   b_stream << "Fuel " << std::setprecision (1)
00648                    << mp_fuel_tank->fuel () << " L";
00649   draw_string (b_stream.str (), 2.8, 0.2);
00650 
00651 
00652   b_stream.str ("");
00653   b_stream << "Slip Ratios";
00654   draw_string (b_stream.str (), 2.8, 1.4);
00655 
00656   b_stream.str ("");
00657   b_stream.setf (std::ios::fixed);
00658   b_stream << std::setprecision (3) << m_wheels [0]->slip ();
00659   draw_string (b_stream.str (), 2.8, 1.0);
00660 
00661   b_stream.str ("");
00662   b_stream << std::setprecision (3) << m_wheels [1]->slip ();
00663   draw_string (b_stream.str (), 3.6, 1.0);
00664 
00665   b_stream.str ("");
00666   b_stream << std::setprecision (3) << m_wheels [2]->slip ();
00667   draw_string (b_stream.str (), 2.8, 0.6);
00668 
00669   b_stream.str ("");
00670   b_stream << std::setprecision (3) << m_wheels [3]->slip ();
00671   draw_string (b_stream.str (), 3.6, 0.6);
00672 
00673   glEnable (GL_DEPTH_TEST);
00674   glEnable (GL_LIGHTING);
00675   glEnable (GL_TEXTURE_2D);
00676 
00677   glMatrixMode (GL_PROJECTION);
00678   glPopMatrix ();
00679   glMatrixMode (GL_MODELVIEW);
00680   glPopMatrix ();
00681 }
00682 
00683 // Perform the transformations for the driver's view.
00684 void Vamos_Body::
00685 Gl_Car::view (double pan, const Three_Vector& view_position)
00686 {
00687   if (pan == 0.0)
00688         {
00689           pan = m_pan_key_control.value ();
00690         }
00691 
00692   // Find the angle-axis representation of the car's orientation.
00693   double angle;
00694   Three_Vector axis = m_chassis.axis_angle (&angle);
00695 
00696   // Rotate the view.
00697   glRotated (90, 0.0, 1.0, 0.0);
00698   glRotated (-90, 1.0, 0.0, 0.0);
00699   glRotated (-angle, axis [0], axis [1], axis [2]);
00700 
00701   Three_Vector z = m_chassis.rotate_out (Three_Vector (0.0, 0.0, 1.0));
00702   glRotated (-pan, z [0], z [1], z [2]);
00703 
00704   Three_Vector pos = 
00705     -m_chassis.transform_out (view_position - m_chassis.center_of_mass ());
00706   glTranslated (pos [0], pos [1], pos [2]);
00707 }
00708 
00709 //extern string car_file;
00710 
00711 void Vamos_Body::
00712 Gl_Car::engine_sound (std::string file, 
00713                                           double volume, 
00714                                           double throttle_volume_factor, 
00715                                           double engine_speed_volume_factor,
00716                                           double pitch)
00717 {
00718   delete mp_engine_sample;
00719 
00720 //  if (file != "")
00721         {
00722           m_throttle_volume_factor = throttle_volume_factor;
00723           m_engine_speed_volume_factor = engine_speed_volume_factor;
00724           mp_engine_sample = new Sample (file, volume, pitch, true, true);
00725                 //real_engine_sample = sound.NewSource(settings.GetDataDir() + "/sounds/engine.wav");
00726                 //cout << "Car " << car_file << endl;
00727                 bool error = false;
00728                 real_engine_sample = sound.NewSource(settings.GetFullDataPath("cars/" + m_car_file + "/engine.wav"), error);
00729                 if (!error)
00730                         sound.SetGain(real_engine_sample, 0);
00731                 //sound.PlaySource(real_engine_sample);
00732                 
00733                 int i;
00734                 for (i = 0; i < 4; i++)
00735                 {
00736                         error = false;
00737                         tire_source[i] = sound.NewSource(settings.GetFullDataPath("sounds/tire_squeal.wav"), error);
00738                         if (!error)
00739                                 sound.SetGain(tire_source[i], 0.0);
00740                         //sound.PlaySource(tire_source[i]);
00741                 }
00742         }
00743 }
00744 
00745 double Vamos_Body::
00746 Gl_Car::engine_pitch ()
00747 {
00748   return engine ()->rotational_speed ();
00749 }
00750 
00751 double Vamos_Body::
00752 Gl_Car::engine_volume ()
00753 {
00754   return 1.0 + m_throttle_volume_factor * engine ()->throttle ()
00755         + m_engine_speed_volume_factor * engine ()->rotational_speed ();
00756 }
00757 
00758 int Vamos_Body::Gl_Car::GetSoundSource()
00759 {
00760         return real_engine_sample;
00761 }
00762 
00763 int Vamos_Body::Gl_Car::GetTireSoundSource(int i)
00764 {
00765         return tire_source[i];
00766 }
00767 
00768 void Vamos_Body::Gl_Car::SetPaint(int pid)
00769 {
00770         //joeexterior.SetBaseTexture(pid);
00771         
00772         if (num_paintjobs <= 0)
00773                 return;
00774         
00775         //cout << pid << ", ";
00776         
00777         char texfile[1024];
00778         if (pid < 0)
00779                 pid = num_paintjobs - ((-pid) % num_paintjobs);
00780         pid = pid % num_paintjobs;
00781         sprintf(texfile, "cars/%s/body%02i.png", m_car_file.c_str(), pid);
00782         joeexterior.Texture(settings.GetFullDataPath(texfile), 0);
00783         
00784         //cout << texfile << endl;
00785         //cout << pid << endl;
00786 }

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