Logo Search packages:      
Sourcecode: vdrift version File versions

Gl_Car.cc

//  Gl_Car.cc - a car that handles graphics, sound and input devices.
//
//  Copyright (C) 2001--2004 Sam Varner
//
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 2 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

#include <vamos/body/Gl_Car.h>
//#include <vamos/geometry/Ac3d.h>
#include <vamos/geometry/Conversions.h>
#include <vamos/body/Fuel_Tank.h>
#include <vamos/body/Gauge.h>
#include <vamos/body/Wheel.h>

//#include <GL/glut.h>

#include <algorithm>
#include <iomanip>
#include <sstream>
#include <string>

using namespace Vamos_Geometry;

//* Struct Rear_View_Mirror

//** Constructor
Vamos_Body::
Rear_View_Mirror::Rear_View_Mirror (const Three_Vector& position,
                                                      double width, double height,
                                                      double direction,
                                                      double field,
                                                      double near_plane, double far_plane,
                                                      std::string mask_file) :
  m_position (position),
  m_width (width),
  m_height (height),
  m_direction (direction),
  m_field (field),
  m_near_plane (near_plane),
  m_far_plane (far_plane),
  mp_mask (new Gl_Texture_Image (mask_file, false, false))
{
}

//** Destructor
Vamos_Body::
Rear_View_Mirror::~Rear_View_Mirror ()
{
  delete mp_mask;
}

void Vamos_Body::
Rear_View_Mirror::activate_viewport ()
{
  glViewport (m_viewport.x, m_viewport.y, m_viewport.width, m_viewport.height);
  glScissor (m_viewport.x, m_viewport.y, m_viewport.width, m_viewport.height);
}

Three_Vector Vamos_Body::
Rear_View_Mirror::get_center () const
{
  return Three_Vector (m_position [0], 
                                 m_position [1] - m_width / 2.0,
                                 m_position [2] + m_height / 2.0);
}

void Vamos_Body::
Rear_View_Mirror::transform_view () const
{
  glMatrixMode (GL_PROJECTION);
  glLoadIdentity ();
  // Reflect the x-axis.
  glScaled (-1.0, 1.0, 1.0);
  gluPerspective (m_field, m_viewport.aspect (), m_near_plane, m_far_plane);
}

void Vamos_Body::
Rear_View_Mirror::set_view ()
{
  activate_viewport ();
  glClear (GL_DEPTH_BUFFER_BIT);
  transform_view ();
}

//* Class Gl_Car

extern bool verbose_output;

//** Constructor
Vamos_Body::
Gl_Car::Gl_Car (const Three_Vector& pos)
  : Car (pos),
      mp_engine_sample (0),
      mp_dashboard (0)
{
      if (verbose_output)
            std::cout << "gl_car init" << std::endl;
      int i;
      for (i = 0; i < 4; i++)
            tire_source[i] = 0;
      
      num_paintjobs = 0;
}

//** Destructor
Vamos_Body::
Gl_Car::~Gl_Car ()
{
      if (verbose_output)
            std::cout << "gl_car deinit" << std::endl;
      
      //FSOUND_StopSound(real_engine_sample);
      
      //commenting this out stops an error when a spinning car widget changes cars
      /*sound.StopSource(real_engine_sample);
      
      int i;
      for (i = 0; i < 4; i++)
            sound.StopSource(tire_source[i]);*/
      
      /*if (m_body_list_id != 0)
      {
        glDeleteLists (m_body_list_id, 1);
      }
  if (m_interior_list_id != 0)
      {
        glDeleteLists (m_interior_list_id, 1);
      }*/
      
  delete mp_engine_sample;

  delete mp_dashboard;

  for (std::vector <Rear_View_Mirror*>::iterator it = m_mirrors.begin ();
         it != m_mirrors.end ();
         it++)
      {
        delete *it;
      }
      
      //textures.Delete(shadowtex);
      //string tex_size = "";
      //settings.Get( "display.texture_size", tex_size );
      //textures.Delete(settings.GetFullDataPath("cars/" + m_car_file + "/textures/" + tex_size  + "/shadow.png"));
      shadowtex.Unload();
      
      //glDeleteTextures(1, &shadowtex);
}

void Vamos_Body::
Gl_Car::exterior_model (std::string file, double scale, 
                                    const Three_Vector& translation,
                                    const Three_Vector& rotation)
{
  /*if (m_body_list_id != 0)
      {
        glDeleteLists (m_body_list_id, 1);
      }*/

   //Ac3d model (file, scale, translation, rotation);
   //m_body_list_id = model.build ();
      string tex_size = "";
      settings.Get( "display.texture_size", tex_size );
      //shadowtex = textures.Load(settings.GetFullDataPath("cars/" + m_car_file + "/textures/" + tex_size  + "/shadow.png"), false);
      shadowtex.Load(settings.GetFullDataPath("cars/" + m_car_file + "/textures/" + tex_size  + "/shadow.png"), false);
      joeglass.Load(settings.GetFullDataPath("cars/" + m_car_file + "/glass.joe"));
      joeglass.AdditiveTexture(settings.GetFullDataPath("cars/" + m_car_file + "/brake-glass.joe"), 1);
      joeglass.Load(settings.GetFullDataPath("cars/" + m_car_file + "/glass.joe"));
      joeglass.AdditiveTexture(settings.GetFullDataPath("cars/" + m_car_file + "/brake-glass.joe"), 1);
      joeexterior.Load(settings.GetFullDataPath("cars/" + m_car_file + "/body.joe"));
      joeexterior.AdditiveTexture(settings.GetFullDataPath("cars/" + m_car_file + "/brake.joe"), 1);
      
      joecollision.Load(settings.GetFullDataPath("cars/" + m_car_file + "/collision.joe"));
      
      //check for paint jobs
      char texfile[1024];
      int count = 0;
      sprintf(texfile, "cars/%s/textures/%s/body%02i.png", m_car_file.c_str(), tex_size.c_str(), count);
      while (count < 99 && utility.FileExists(settings.GetFullDataPath(texfile)))
      {
            count++;
            sprintf(texfile, "cars/%s/textures/%s/body%02i.png", m_car_file.c_str(), tex_size.c_str(), count);
      }
      num_paintjobs = count;
}

void Vamos_Body::
Gl_Car::interior_model (std::string file, double scale, 
                                    const Three_Vector& translation,
                                    const Three_Vector& rotation)
{
  /*if (m_interior_list_id != 0)
      {
        glDeleteLists (m_interior_list_id, 1);
      }

   Ac3d model (file, scale, translation, rotation);
   m_interior_list_id = model.build ();*/
      
      //joeinterior.Load(file);
      joeinterior.Load(settings.GetFullDataPath("cars/" + m_car_file + "/interior.joe"));
}

void Vamos_Body::
Gl_Car::set_perspective (double aspect)
{
  gluPerspective (m_field_of_view, aspect, m_near_plane, m_far_plane);
}

void Vamos_Body::
Gl_Car::set_view (const Vamos_Geometry::Three_Vector& position,
                          double field_of_view,
                          double near_plane, double far_plane,
                          double pan_angle)
{
  m_driver_view = position;
  m_field_of_view = field_of_view;
  m_near_plane = near_plane;
  m_far_plane = far_plane;
  m_pan_angle = pan_angle;
}

void Vamos_Body::
Gl_Car::add_rear_view (const Vamos_Geometry::Three_Vector& position,
                                 double width, double height,
                                 double direction, double field,
                                 double near_plane, double far_plane,
                                 std::string mask_file)
{
  m_mirrors.push_back (new Rear_View_Mirror (position, width, height,
                                                                   direction, field, 
                                                                   near_plane, far_plane,
                                                                   mask_file));
}


// Fill the stencil buffer for masking the rear-view mirrors.
void Vamos_Body::
Gl_Car::make_rear_view_mask (int window_width, int window_height)
{
  glMatrixMode (GL_PROJECTION);
  glLoadIdentity ();

  glViewport (0, 0, window_width, window_height);
  glScissor (0, 0, window_width, window_height);

  glClearColor (0.0, 0.0, 0.0, 0.0);
  glClearStencil (0);
  glClear (GL_COLOR_BUFFER_BIT 
               | GL_DEPTH_BUFFER_BIT
               | GL_STENCIL_BUFFER_BIT);

  const double near_plane = 0.2;
  const double far_plane = 10.0;
  gluPerspective (field_of_view (), double (window_width)/window_height, 
                          near_plane, far_plane);
  view (0.0);
  glMatrixMode (GL_MODELVIEW);
  transform_body ();

  for (std::vector <Rear_View_Mirror*>::iterator it = m_mirrors.begin ();
         it != m_mirrors.end ();
         it++)
      {
        (*it)->make_mask (window_width, window_height,
                                    m_driver_view, field_of_view ());
      }
}


// Put a mask for one rear-view mirror in the stencil buffer.
void Vamos_Body::
Rear_View_Mirror::make_mask (int window_width, int window_height,
                                           const Three_Vector& driver_position, 
                                           double driver_field_of_view)
{
  glDisable (GL_LIGHTING);
  set_viewport (window_width, window_height, 
                        driver_position, driver_field_of_view);
  draw_mask_shape ();
  set_stencil (window_width, window_height);
  glEnable (GL_LIGHTING);
}


// Find the dimensions for a viewport that's just large enough to hold
// the mirror.
void Vamos_Body::
Rear_View_Mirror::set_viewport (int window_width, int window_height, 
                                                const Three_Vector& driver_position,
                                                double driver_field_of_view)
{
  const Three_Vector pos = m_position - driver_position;
  const double y_factor = 
      -1.0 / (pos [0] * tan (0.5 * deg_to_rad (driver_field_of_view)));
  const double aspect = double (window_width) / window_height;
  const double x_factor = -y_factor / aspect;

  const int x0 = to_pixels (window_width, x_factor, pos [1]) - 1;
  m_viewport.x = clip (x0, 0, window_width - 1);
  const int y0 = to_pixels (window_height, y_factor, pos [2]) - 1;
  m_viewport.y = clip (y0, 0, window_height - 1);

  const int x1 = to_pixels (window_width, x_factor, pos [1] - m_width);
  m_viewport.width = clip (x1, 0, window_width - 1) - m_viewport.x;
  const int y1 = to_pixels (window_height, y_factor, pos [2] + m_height);
  m_viewport.height = clip (y1, 0, window_height - 1) - m_viewport.y;
}


// Draw the mask.
void Vamos_Body::
Rear_View_Mirror::draw_mask_shape ()
{
  glStencilFunc (GL_ALWAYS, 1, 1);
  glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);

  mp_mask->activate ();

  glColor3d (1.0, 1.0, 1.0);
  glBegin (GL_QUADS);
  glTexCoord2d (0.0, 1.0);
  glVertex3d (m_position [0], m_position [1], m_position [2]);
  glTexCoord2d (1.0, 1.0);
  glVertex3d (m_position [0], m_position [1] - m_width, m_position [2]);
  glTexCoord2d (1.0, 0.0);
  glVertex3d (m_position [0], m_position [1] - m_width, 
                    m_position [2] + m_height);
  glTexCoord2d (0.0, 0.0);
  glVertex3d (m_position [0], m_position [1], m_position [2] + m_height);
  glEnd ();

  glFlush ();
}


// Use the pixels in the viewport to set the stencil buffer.
void Vamos_Body::
Rear_View_Mirror::set_stencil (int window_width, int window_height)
{
  unsigned char* stencil_buffer = make_stencil_buffer ();

  glMatrixMode (GL_PROJECTION);
  glPushMatrix ();
  glLoadIdentity ();
  gluOrtho2D (0.0, double (window_width), 0.0, double (window_height));
  glMatrixMode (GL_MODELVIEW);
  glPushMatrix ();
  glLoadIdentity ();
  glStencilFunc (GL_EQUAL, 1, 1);
  glStencilOp (GL_KEEP, GL_REPLACE, GL_REPLACE);
  glRasterPos2i (m_viewport.x, m_viewport.y);
  glDrawPixels (m_viewport.width, m_viewport.height, GL_STENCIL_INDEX,
                        GL_UNSIGNED_BYTE, stencil_buffer);
  glPopMatrix ();

  glMatrixMode (GL_PROJECTION);
  glPopMatrix ();

  glFinish ();

  delete stencil_buffer;
}


// Grab the current buffer as an array of pixels.
unsigned char* Vamos_Body::
Rear_View_Mirror::make_stencil_buffer ()
{
  glReadBuffer (GL_BACK);
  const size_t elements = m_viewport.width * m_viewport.height;
  unsigned char* rgba_buffer = new unsigned char [4 * elements];

  glReadPixels (m_viewport.x, m_viewport.y, 
                        m_viewport.width, m_viewport.height, 
                        GL_RGBA, GL_UNSIGNED_BYTE, rgba_buffer);

  unsigned char* buffer = new unsigned char [elements];
  for (size_t i = 0; i < elements; i++)
      {
        buffer [i] = rgba_buffer [4 * i];
      }
  delete rgba_buffer;
  return buffer;
}


void Vamos_Body::
Gl_Car::draw_rear_view (double aspect, int index)
{
  Rear_View_Mirror* mirror = m_mirrors [index];
  mirror->set_view ();
  view (mirror->get_direction (), mirror->get_center ());
}

// Set the dashboard.
void Vamos_Body::
Gl_Car::dashboard (Dashboard* dash)
{
  delete mp_dashboard;
  mp_dashboard = dash;
}

extern GLfloat LightPosition[4];
#include "quat.h"

void Vamos_Body::
Gl_Car::transform_body ()
{
  // Set the modelview matrix to be the identity matrix
  //glLoadIdentity ();
  
  // Translate and rotate the graphical representation of the object
  Three_Vector cm = m_chassis.position ();
  glTranslatef (cm [0], cm [1], cm [2]);
  
  double angle;
  Three_Vector axis = m_chassis.axis_angle (&angle);
      
      
      
      
      
  glRotatef (angle, axis [0], axis [1], axis [2]);


  
  // The rotation is performed about the origin of the body
  // system.  Since we want the effect to be a rotation about the
  // center of mass, we have to translate the object the distance
  // from the cm to the origin.
  cm = -m_chassis.center_of_mass ();
  glTranslatef (cm [0], cm [1], cm [2]);
  
      QUATERNION carrot;
      carrot.SetAxisAngle(angle*3.141593/180.0, axis[0], axis[2], axis[1]);
      QUATERNION goofyfoot;
      goofyfoot.Rotate(-3.141593/2.0, 1,0,0);
      double tempmat[16];
      goofyfoot.GetMat(tempmat);
      float lp[4];
      lp[0] = LightPosition[0];
      lp[1] = LightPosition[1];
      lp[2] = LightPosition[2];
      lp[3] = 0;
      VERTEX lpv;
      lpv.Set(lp);
      //goofyfoot.PostMultiply(carrot);
      lpv = goofyfoot.ReturnConjugate().RotateVec(lpv);
      lpv = carrot.ReturnConjugate().RotateVec(lpv);
      lp[0] = lpv.x;
      lp[1] = lpv.z;
      lp[2] = lpv.y;
      //glLightfv( GL_LIGHT1, GL_POSITION,  lp);
}

// Render the car according to its current position and orientation.
void Vamos_Body::
Gl_Car::draw (bool transform, float opacity)
{
//  if (m_body_list_id != 0)
      {
            if (transform)
                  transform_body ();

        // Draw the body.
        //glCallList (m_body_list_id);
            //joeexterior.Draw(0, 0);
            
            glPushAttrib(GL_ALL_ATTRIB_BITS);
            //glDisable(GL_LIGHTING);
            //glDepthMask(0);
            
            bool illum = false;
            if (brakesetting != 0)
                  illum = true;
            
            //utility.SelectTU(1);
            //glEnable(GL_TEXTURE_2D);
            //utility.SelectTU(0);

            //putting tree shadows on the car doesn't work because the car's vertices
            // are in local space, not world space
            /*if (utility.numTUs() > 3 && state.GetTreeDetail() != "Off" && state.GetTreeDetail() != "FoliageOnly")
            {
                  utility.SelectTU(3);
                  glEnable(GL_TEXTURE_2D);
                  glBindTexture(GL_TEXTURE_2D, trees.GetCompositeShadow());
                  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
                  glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
                  glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
                  glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB,GL_MODULATE);
                  glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1);
            }*/
            
            glColor4f(1,1,1,opacity);
            //glColor4f(0.5,0,0,opacity);
            glEnable(GL_BLEND);
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
            glCullFace(GL_FRONT);
            glEnable(GL_CULL_FACE);
            //joecollision.DrawStatic();
            joeexterior.SetTU(1, illum);
            joeexterior.DrawStatic();
            
            glCullFace(GL_BACK);
            glColor4f(0,0,0,opacity);
            joeexterior.DrawStatic();
            
            glColor4f(1,1,1,opacity);
            glDisable(GL_CULL_FACE);
            
            joeinterior.DrawStatic();
            
            // Draw the wheels.
              std::for_each (m_wheels.begin (), m_wheels.end (),
                                     std::mem_fun (&Wheel::draw));
            
            //utility.SelectTU(1);
            //glEnable(GL_TEXTURE_2D);
            utility.SelectTU(0);
            
            glEnable(GL_CULL_FACE);
            glEnable(GL_BLEND);
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
            glCullFace(GL_FRONT);
            glEnable(GL_CULL_FACE);
            glDepthMask(0);
            glColor4f(1,1,1,opacity);
            joeglass.SetTU(1, illum);
            joeglass.DrawStatic();
            //joeglass.DrawStatic();
            glDepthMask(1);

            glPopAttrib();
            
            utility.SelectTU(3);
            glDisable(GL_TEXTURE_2D);
            utility.SelectTU(1);
            glDisable(GL_TEXTURE_2D);
            utility.SelectTU(0);
      }
}

void Vamos_Body::
Gl_Car::draw_interior ()
{
  //joeinterior.Draw();
  draw_dashboard ();
}

TEXTURE_HANDLE * Vamos_Body::
Gl_Car::shadow_texture()
{return &shadowtex;}

void Vamos_Body::
Gl_Car::draw_dashboard ()
{
  mp_dashboard->set_tachometer (rad_s_to_rpm (engine ()->rotational_speed ()));
  mp_dashboard->set_speedometer (m_s_to_km_h (wheel (2)->speed ()));
  mp_dashboard->set_fuel_gauge (fuel_tank ()->fuel ());
  mp_dashboard->set_gear_indicator (transmission ()->gear ());
  mp_dashboard->set_steering_wheel (m_steer_key_control.value ());

  mp_dashboard->draw ();
  if (m_show_dashboard_extras)
      {
        draw_dashboard_extras ();
      }
}

void Vamos_Body::
Gl_Car::draw_string (const std::string& str, double x, double y)
{
      font.Print(x, y, str.c_str(), 1, 5, 1);
  /*glRasterPos2d (x, y);
  for (std::string::const_iterator it = str.begin (); it != str.end (); it++)
      {
        glutBitmapCharacter (GLUT_BITMAP_8_BY_13, *it);
      }*/
}

void Vamos_Body::
Gl_Car::draw_dashboard_extras ()
{ 
  glMatrixMode (GL_PROJECTION);
  glPushMatrix ();
  glLoadIdentity ();

  // Set the dimensions of the drawing area.
  gluOrtho2D (0, 10, 0, 10);
  glMatrixMode (GL_MODELVIEW);
  glPushMatrix ();
  glLoadIdentity ();
  
  glDisable (GL_DEPTH_TEST);
  glDisable (GL_LIGHTING);
  glDisable (GL_TEXTURE_2D);
  
  glColor3f (1.0, 1.0, 1.0);

  std::ostringstream b_stream;

  int rpm = 
      int (Vamos_Geometry::rad_s_to_rpm (engine ()->rotational_speed ()));
  b_stream << "RPM " << rpm;
  draw_string (b_stream.str (), 0.4, 1.8);

  b_stream.str ("");
  b_stream << "Torque " << int (engine ()->drive_torque ()) << " Nm";
  draw_string (b_stream.str (), 0.4, 1.4);

  b_stream.str ("");
  b_stream << "Speed " << int (m_s_to_km_h (wheel (2)->speed ()))
               << " km/h";
  draw_string (b_stream.str (), 0.4, 1.0);

  b_stream.str ("");
  b_stream << "Mass " << int (m_chassis.mass ()) << " kg";
  draw_string (b_stream.str (), 0.4, 0.6);

  b_stream.str ("");
  char gear = 'N';
  if (transmission ()->gear () == -1)
      {
        gear = 'R';
      }
  else if (transmission ()->gear () > 0)
      {
        gear = transmission ()->gear () + '0';
      }
  b_stream << "Gear " << gear;
  draw_string (b_stream.str (), 0.4, 0.2);

  b_stream.str ("");
  b_stream << "Fuel " << std::setprecision (1)
               << mp_fuel_tank->fuel () << " L";
  draw_string (b_stream.str (), 2.8, 0.2);


  b_stream.str ("");
  b_stream << "Slip Ratios";
  draw_string (b_stream.str (), 2.8, 1.4);

  b_stream.str ("");
  b_stream.setf (std::ios::fixed);
  b_stream << std::setprecision (3) << m_wheels [0]->slip ();
  draw_string (b_stream.str (), 2.8, 1.0);

  b_stream.str ("");
  b_stream << std::setprecision (3) << m_wheels [1]->slip ();
  draw_string (b_stream.str (), 3.6, 1.0);

  b_stream.str ("");
  b_stream << std::setprecision (3) << m_wheels [2]->slip ();
  draw_string (b_stream.str (), 2.8, 0.6);

  b_stream.str ("");
  b_stream << std::setprecision (3) << m_wheels [3]->slip ();
  draw_string (b_stream.str (), 3.6, 0.6);

  glEnable (GL_DEPTH_TEST);
  glEnable (GL_LIGHTING);
  glEnable (GL_TEXTURE_2D);

  glMatrixMode (GL_PROJECTION);
  glPopMatrix ();
  glMatrixMode (GL_MODELVIEW);
  glPopMatrix ();
}

// Perform the transformations for the driver's view.
void Vamos_Body::
Gl_Car::view (double pan, const Three_Vector& view_position)
{
  if (pan == 0.0)
      {
        pan = m_pan_key_control.value ();
      }

  // Find the angle-axis representation of the car's orientation.
  double angle;
  Three_Vector axis = m_chassis.axis_angle (&angle);

  // Rotate the view.
  glRotated (90, 0.0, 1.0, 0.0);
  glRotated (-90, 1.0, 0.0, 0.0);
  glRotated (-angle, axis [0], axis [1], axis [2]);

  Three_Vector z = m_chassis.rotate_out (Three_Vector (0.0, 0.0, 1.0));
  glRotated (-pan, z [0], z [1], z [2]);

  Three_Vector pos = 
    -m_chassis.transform_out (view_position - m_chassis.center_of_mass ());
  glTranslated (pos [0], pos [1], pos [2]);
}

//extern string car_file;

void Vamos_Body::
Gl_Car::engine_sound (std::string file, 
                                double volume, 
                                double throttle_volume_factor, 
                                double engine_speed_volume_factor,
                                double pitch)
{
  delete mp_engine_sample;

//  if (file != "")
      {
        m_throttle_volume_factor = throttle_volume_factor;
        m_engine_speed_volume_factor = engine_speed_volume_factor;
        mp_engine_sample = new Sample (file, volume, pitch, true, true);
            //real_engine_sample = sound.NewSource(settings.GetDataDir() + "/sounds/engine.wav");
            //cout << "Car " << car_file << endl;
            bool error = false;
            real_engine_sample = sound.NewSource(settings.GetFullDataPath("cars/" + m_car_file + "/engine.wav"), error);
            if (!error)
                  sound.SetGain(real_engine_sample, 0);
            //sound.PlaySource(real_engine_sample);
            
            int i;
            for (i = 0; i < 4; i++)
            {
                  error = false;
                  tire_source[i] = sound.NewSource(settings.GetFullDataPath("sounds/tire_squeal.wav"), error);
                  if (!error)
                        sound.SetGain(tire_source[i], 0.0);
                  //sound.PlaySource(tire_source[i]);
            }
      }
}

double Vamos_Body::
Gl_Car::engine_pitch ()
{
  return engine ()->rotational_speed ();
}

double Vamos_Body::
Gl_Car::engine_volume ()
{
  return 1.0 + m_throttle_volume_factor * engine ()->throttle ()
      + m_engine_speed_volume_factor * engine ()->rotational_speed ();
}

int Vamos_Body::Gl_Car::GetSoundSource()
{
      return real_engine_sample;
}

int Vamos_Body::Gl_Car::GetTireSoundSource(int i)
{
      return tire_source[i];
}

void Vamos_Body::Gl_Car::SetPaint(int pid)
{
      //joeexterior.SetBaseTexture(pid);
      
      if (num_paintjobs <= 0)
            return;
      
      //cout << pid << ", ";
      
      char texfile[1024];
      if (pid < 0)
            pid = num_paintjobs - ((-pid) % num_paintjobs);
      pid = pid % num_paintjobs;
      sprintf(texfile, "cars/%s/body%02i.png", m_car_file.c_str(), pid);
      joeexterior.Texture(settings.GetFullDataPath(texfile), 0);
      
      //cout << texfile << endl;
      //cout << pid << endl;
}

Generated by  Doxygen 1.6.0   Back to index