src/vamos/body/Gauge.cc

Go to the documentation of this file.
00001 #include <vamos/body/Gauge.h>
00002 
00003 #include <algorithm>
00004 #include <iostream>
00005 #include <functional>
00006 
00007 using namespace Vamos_Geometry;
00008 
00009 namespace Vamos_Body
00010 {
00011 
00012 //* Class Facade
00013 Facade::Facade (double x, double y, double above, double width, double height,
00014                                 std::string image) :
00015   Gl_Texture_Image (image, true, true),
00016   m_x (x),
00017   m_y (y),
00018   m_above (above),
00019   m_width (width),
00020   m_height (height),
00021   m_list_index (glGenLists (1))
00022 {
00023   build_facade ();
00024 }
00025 
00026 Facade::Facade (double center_x, double center_y, double above, double radius,
00027                                 std::string image) :
00028   Gl_Texture_Image (image, true, true)
00029 {
00030   m_above = above;
00031   m_width = 2.0 * radius * width_pixels () / height_pixels ();
00032   m_height = 2.0 * radius;
00033   m_x = center_x - m_width / 2.0;
00034   m_y = center_y - m_height / 2.0;
00035   m_list_index = glGenLists (1);
00036   build_facade ();
00037 }
00038 
00039 void
00040 Facade::build_facade ()
00041 {
00042   clamp_to_edge ();
00043   glNewList (m_list_index, GL_COMPILE);
00044   build_image ();
00045   glEndList ();
00046 }
00047 
00048 void
00049 Facade::build_image ()
00050 {
00051   activate ();
00052 
00053   glColor3d (1.0, 1.0, 1.0);
00054   glBegin (GL_QUADS);
00055   glTexCoord2d (0.0, 0.0);
00056   glVertex3d (-m_above, -m_x, m_y + m_height);
00057   glTexCoord2d (1.0, 0.0);
00058   glVertex3d (-m_above, -m_x - m_width, m_y + m_height);
00059   glTexCoord2d (1.0, 1.0);
00060   glVertex3d (-m_above, -m_x - m_width, m_y);
00061   glTexCoord2d (0.0, 1.0);
00062   glVertex3d (-m_above, -m_x, m_y);
00063   glEnd ();
00064 }
00065 
00066 void
00067 Facade::rotate (double degrees) const
00068 {
00069   glRotated (degrees, 1.0, 0.0, 0.0);
00070 }
00071 
00072 void
00073 Facade::draw () const 
00074 {
00075   glCallList (m_list_index);
00076 }
00077 
00078 //* Class Scaler
00079 Scaler::Scaler (double min_in, double min_out, double max_in, double max_out) :
00080   m_minimum_input (min_in),
00081   m_maximum_input (max_in),
00082   m_offset (min_out),
00083   m_factor ((max_out - min_out) / (max_in - min_in))
00084 {
00085 }
00086 
00087 double
00088 Scaler::scale (double value_in)
00089 {
00090   value_in = std::max (m_minimum_input, value_in);
00091   value_in = std::min (m_maximum_input, value_in);
00092   return m_offset + (value_in - m_minimum_input) * m_factor;
00093 }
00094 
00095 //* Class Dial
00096 Dial::Dial (double center_x, double center_y, double above, double radius, 
00097                         double min, double min_angle, double max, double max_angle,
00098                         std::string face_image, std::string needle_image) : 
00099   m_above (above),
00100   m_scaler (min, min_angle, max, max_angle),
00101   mp_face (0),
00102   m_center_x (center_x),
00103   m_center_y (center_y)
00104 {
00105   if (face_image != "")
00106         {
00107           mp_face = new Facade (center_x, center_y, above, radius, face_image); 
00108         }
00109   if (needle_image != "")
00110         {
00111           mp_needle = new Facade (0.0, 0.0, above + 0.01, radius, 
00112                                                           needle_image); 
00113         }
00114 }
00115 
00116 Dial::~Dial ()
00117 {
00118   delete mp_needle;
00119   delete mp_face;
00120 }
00121 
00122 void
00123 Dial::set (double value)
00124 {
00125   m_angle = m_scaler.scale (value);
00126 }
00127 
00128 void
00129 Dial::draw () const
00130 {
00131   glPushMatrix ();
00132   mp_face->draw ();
00133   glTranslated (0.0, -m_center_x, m_center_y);
00134   mp_needle->rotate (m_angle);
00135   mp_needle->draw ();
00136   glPopMatrix ();
00137 }
00138 
00139 //* Class LED_Gauge
00140 LED_Gauge::LED_Gauge (double x, double y, double above, double width, 
00141                                           int elements, double min, double redline, 
00142                                           std::string image, bool on_wheel) :
00143   m_x (x),
00144   m_y (y),
00145   m_above (above),
00146   m_width (width),
00147   m_elements (elements),
00148   m_min (min),
00149   m_range (redline - min),
00150   m_leds_on (0),
00151   m_list_index (glGenLists (1))
00152 {
00153   m_on_steering_wheel = on_wheel;
00154   mp_leds = new Gl_Texture_Image (image, true, true);
00155 
00156   m_height = (0.5 * m_width * mp_leds->height_pixels ()) 
00157         / mp_leds->width_pixels ();
00158 
00159   glNewList (m_list_index, GL_COMPILE);
00160 
00161   mp_leds->activate ();
00162           
00163   glTranslated (-m_above, -m_x, m_y);
00164 
00165   glColor3d (1.0, 1.0, 1.0);
00166   glBegin (GL_QUADS);
00167   glTexCoord2d (0.0, 0.5);
00168   glVertex3d (0.0, 0.0, 0.0);
00169   glTexCoord2d (1.0, 0.5);
00170   glVertex3d (0.0, -m_width, 0.0);
00171   glTexCoord2d (1.0, 1.0);
00172   glVertex3d (0.0, -m_width, m_height);
00173   glTexCoord2d (0.0, 1.0);
00174   glVertex3d (0.0, 0.0, m_height);
00175   glEnd ();
00176 
00177   glEndList ();
00178 }
00179 
00180 LED_Gauge::~LED_Gauge ()
00181 {
00182   delete mp_leds;
00183 }
00184 
00185 void
00186 LED_Gauge::set (double value)
00187 {
00188   m_leds_on = int ((value - m_min)*(m_elements - 1)/m_range + 1.0);
00189   m_leds_on = std::max (m_leds_on, 0);
00190   m_leds_on = std::min (m_leds_on, m_elements);
00191 }
00192 
00193 void
00194 LED_Gauge::draw () const
00195 {
00196   glPushMatrix ();
00197 
00198   // Draw the LEDs all off...
00199   glCallList (m_list_index);
00200 
00201   // ...then draw the ones that are on over top.
00202   double frac = double (m_leds_on) / m_elements;
00203 
00204   mp_leds->activate ();
00205           
00206   glColor3d (1.0, 1.0, 1.0);
00207   glBegin (GL_QUADS);
00208   glTexCoord2d (0.0, 0.5);
00209   glVertex3d (0.0, 0.0, 0.0);
00210   glTexCoord2d (frac, 0.5);
00211   glVertex3d (0.0, -m_width * frac, 0.0);
00212   glTexCoord2d (frac, 0.0);
00213   glVertex3d (0.0, -m_width * frac, m_height);
00214   glTexCoord2d (0.0, 0.0);
00215   glVertex3d (0.0, 0.0, m_height);
00216   glEnd ();
00217 
00218   glPopMatrix ();
00219 }
00220 
00221 //* Class Digital Gauge
00222 Digital_Gauge::Digital_Gauge (double x, double y, double above,
00223                                                           double width, double height, size_t places,
00224                                                           std::string digits, bool on_wheel) :
00225   m_x (x),
00226   m_y (y),
00227   m_above (above),
00228   m_width (width),
00229   m_height (height),
00230   m_places (places)
00231 {
00232   m_on_steering_wheel = on_wheel;
00233   m_digits.resize (places);
00234   mp_digits = new Gl_Texture_Image (digits, true, true);
00235 }
00236 
00237 Digital_Gauge::~Digital_Gauge ()
00238 {
00239   delete mp_digits;
00240 }
00241 
00242 void
00243 Digital_Gauge::set (double value)
00244 {
00245   int n = int (value);
00246   int denom = 1;
00247   int sub = 0;
00248   for (size_t index = 0; index < m_places; index++)
00249         {
00250           int m = denom * 10;
00251           int place = (n % m) / denom; 
00252           m_digits [m_places - 1 - index] = place;
00253           denom = m;
00254           sub += place;
00255         }
00256 }
00257 
00258 void
00259 Digital_Gauge::draw () const
00260 {
00261   mp_digits->activate ();
00262 
00263   bool nonzero = false;
00264   for (size_t i = 0; i < m_places; i++)
00265         {
00266           int n = m_digits [i];
00267           if ((!nonzero) && (n == 0) && (i != (m_places - 1)))
00268                 {
00269                   continue;
00270                 }
00271           nonzero = true;
00272 
00273           double tex_x1 =  n * 0.1;
00274           double tex_x2 = tex_x1 + 0.1;
00275 
00276           double x1 = i * m_width / m_places;
00277           double x2 = x1 + m_width / m_places;
00278 
00279           glColor3d (1.0, 1.0, 1.0);
00280           glBegin (GL_QUADS);
00281           glTexCoord2d (tex_x1, 1.0);
00282           glVertex3d (-m_above, -m_x - x1, m_y);
00283           glTexCoord2d (tex_x2, 1.0);
00284           glVertex3d (-m_above, -m_x - x2, m_y);
00285           glTexCoord2d (tex_x2, 0.0);
00286           glVertex3d (-m_above, -m_x - x2, m_y + m_height);
00287           glTexCoord2d (tex_x1, 0.0);
00288           glVertex3d (-m_above, -m_x - x1, m_y + m_height);
00289           glEnd ();
00290         }
00291 }
00292 
00293 //* Class Steering_Wheel
00294 Steering_Wheel::Steering_Wheel (double center_x, double center_y, 
00295                                                                 double above, double radius, 
00296                                                                 double min, double min_angle, 
00297                                                                 double max, double max_angle,
00298                                                                 std::string image) :
00299   Facade (0.0, 0.0, above, radius, image),
00300   m_center_x (center_x),
00301   m_center_y (center_y),
00302   m_scaler (min, min_angle, max, max_angle)
00303 {
00304 }
00305 
00306 void
00307 Steering_Wheel::set (double value)
00308 {
00309   m_angle = m_scaler.scale (value);
00310 }
00311 
00312 void
00313 Steering_Wheel::draw () const
00314 {
00315   glTranslated (0.0, -m_center_x, m_center_y);
00316   rotate (m_angle);
00317   Facade::draw ();
00318 }
00319 
00320 //* Class Gear_Indicator
00321 Gear_Indicator::Gear_Indicator (double x, double y, double above,
00322                                                                 double width, double height, 
00323                                                                 int numbers, std::string image,
00324                                                                 bool on_wheel) :
00325   m_number_width (1.0 / numbers),
00326   mp_numbers (0),
00327   m_x (x),
00328   m_y (y),
00329   m_above (above),
00330   m_width (width),
00331   m_height (height)
00332 {
00333   m_on_steering_wheel = on_wheel;
00334   if (image != "")
00335         {
00336           mp_numbers = new Gl_Texture_Image (image, true, true);
00337         }
00338 }
00339 
00340 Gear_Indicator::~Gear_Indicator ()
00341 {
00342   delete mp_numbers;
00343 }
00344 
00345 void
00346 Gear_Indicator::draw () const
00347 {
00348   mp_numbers->activate ();
00349 
00350   double x1 = m_number_width * (m_gear + 1);
00351   double x2 = x1 + m_number_width;
00352 
00353   glColor3d (1.0, 1.0, 1.0);
00354   glBegin (GL_QUADS);
00355   glTexCoord2d (x2, 1.0);
00356   glVertex3d (-m_above, -m_x, m_y);
00357   glTexCoord2d (x1, 1.0);
00358   glVertex3d (-m_above, -m_x + m_width, m_y);
00359   glTexCoord2d (x1, 0.0);
00360   glVertex3d (-m_above, -m_x + m_width, m_y + m_height);
00361   glTexCoord2d (x2, 0.0);
00362   glVertex3d (-m_above, -m_x, m_y + m_height);
00363   glEnd ();
00364 }
00365 
00366 
00367 //* Class Gear_Shift
00368 Gear_Shift::Gear_Shift (double x, double y, double z, 
00369                                                 double width, double height,
00370                                                 const Vamos_Geometry::Three_Vector& rotation,
00371                                                 const std::vector <Vamos_Geometry::Two_Point>& 
00372                                                 positions,
00373                                                 std::string plate_image, std::string stick_image) :
00374   Gear_Indicator (x, y, z, width, height, 0, "", false),
00375   m_rotation (rotation),
00376   m_positions (positions),
00377   m_top_gear (m_positions.size () - 2),
00378   m_list_index (glGenLists (2))
00379 {
00380   mp_gate = new Gl_Texture_Image (plate_image, true, true);
00381   mp_stick = new Gl_Texture_Image (stick_image, true, true);
00382 
00383   m_stick_width = 
00384         m_width * mp_stick->width_pixels () / mp_gate->width_pixels ();
00385   m_stick_height = 
00386         m_height * mp_stick->height_pixels () / mp_gate->height_pixels ();
00387 
00388   glNewList (m_list_index, GL_COMPILE);
00389 
00390   mp_gate->activate ();
00391 
00392   glRotated (rotation [0], 0.0, -1.0, 0.0);
00393   glRotated (rotation [1], 0.0, 0.0, 1.0);
00394   glRotated (rotation [2], 1.0, 0.0, 0.0);
00395   glTranslated (-m_above, -m_x, m_y);
00396 
00397   glColor3d (1.0, 1.0, 1.0);
00398   glBegin (GL_QUADS);
00399   glTexCoord2d (0.0, 0.0);
00400   glVertex3d (0.0, 0.0, 0.0);
00401   glTexCoord2d (1.0, 0.0);
00402   glVertex3d (0.0, -m_width, 0.0);
00403   glTexCoord2d (1.0, 1.0);
00404   glVertex3d (0.0, -m_width, m_height);
00405   glTexCoord2d (0.0, 1.0);
00406   glVertex3d (0.0, 0.0, m_height);
00407   glEnd ();
00408 
00409   glTranslated (0.0, (-m_width + m_stick_width) / 2.0, m_height / 2.0);
00410   glEndList ();
00411 
00412   glNewList (m_list_index + 1, GL_COMPILE);
00413 
00414   mp_stick->activate ();
00415 
00416   glRotated (-rotation [0], 0.0, -1.0, 0.0);
00417   glRotated (-rotation [1], 0.0, 0.0, 1.0);
00418   glRotated (-rotation [2], 1.0, 0.0, 0.0);
00419 
00420   glColor3d (1.0, 1.0, 1.0);
00421   glBegin (GL_QUADS);
00422   glTexCoord2d (0.0, 1.0);
00423   glVertex3d (0.0, 0.0, 0.0);
00424   glTexCoord2d (1.0, 1.0);
00425   glVertex3d (0.0, -m_stick_width, 0.0);
00426   glTexCoord2d (1.0, 0.0);
00427   glVertex3d (0.0, -m_stick_width, m_stick_height);
00428   glTexCoord2d (0.0, 0.0);
00429   glVertex3d (0.0, 0.0, m_stick_height);
00430   glEnd ();
00431 
00432   glEndList ();
00433 }
00434 
00435 Gear_Shift::~Gear_Shift ()
00436 {
00437   delete mp_stick;
00438   delete mp_gate;
00439 }
00440 
00441 void
00442 Gear_Shift::set (int gear)
00443 {
00444   m_gear = std::min (m_top_gear, gear);
00445 }
00446 
00447 void
00448 Gear_Shift::draw () const
00449 {
00450   glPushMatrix ();
00451   glCallList (m_list_index);
00452   glTranslated (0.0, -m_positions [m_gear + 1].x, m_positions [m_gear + 1].y);
00453   glCallList (m_list_index + 1);
00454   glPopMatrix ();
00455 }
00456 
00457 
00458 //* Class Dashboard
00459 Dashboard::Dashboard (double x, double y, double z, double tilt) :
00460   m_x (x),
00461   m_y (y),
00462   m_z (z),
00463   m_tilt (tilt),
00464   mp_tachometer (0),
00465   mp_speedometer (0),
00466   mp_fuel_gauge (0),
00467   mp_gear_indicator (0),
00468   mp_steering_wheel (0)
00469 {
00470 }
00471 
00472 Dashboard::~Dashboard ()
00473 {
00474   delete mp_steering_wheel;
00475   delete mp_gear_indicator;
00476   delete mp_fuel_gauge;
00477   delete mp_speedometer;
00478   delete mp_tachometer;
00479   for (std::vector <Facade*>::iterator it = ma_facades.begin ();
00480            it != ma_facades.end ();
00481            it++)
00482         {
00483           delete *it;
00484         }
00485 }
00486 
00487 void
00488 Dashboard::add_tachometer (Gauge* tachometer)
00489 {
00490   delete mp_tachometer;
00491   mp_tachometer = tachometer;
00492 }
00493 
00494 void
00495 Dashboard::add_speedometer (Gauge* speedometer)
00496 {
00497   delete mp_speedometer;
00498   mp_speedometer = speedometer;
00499 }
00500 
00501 void
00502 Dashboard::add_fuel_gauge (Gauge* fuel_gauge)
00503 {
00504   delete mp_fuel_gauge;
00505   mp_fuel_gauge = fuel_gauge;
00506 }
00507 
00508 void
00509 Dashboard::add_gear_indicator (Gear_Indicator* gear_indicator)
00510 {
00511   delete mp_gear_indicator;
00512   mp_gear_indicator = gear_indicator;
00513 }
00514 
00515 void
00516 Dashboard::add_steering_wheel (Steering_Wheel* steering_wheel)
00517 {
00518   delete mp_steering_wheel;
00519   mp_steering_wheel = steering_wheel;
00520 }
00521 
00522 void
00523 Dashboard::add_facade (Facade* facade)
00524 {
00525   ma_facades.push_back (facade);
00526 }
00527 
00528 void
00529 Dashboard::set_tachometer (double rpm)
00530 {
00531   if (mp_tachometer != 0)
00532         {
00533           mp_tachometer->set (rpm);
00534         }
00535 }
00536 
00537 void
00538 Dashboard::set_speedometer (double speed)
00539 {
00540   if (mp_speedometer != 0)
00541         {
00542           mp_speedometer->set (speed);
00543         }
00544 }
00545 
00546 void
00547 Dashboard::set_fuel_gauge (double fuel)
00548 {
00549   if (mp_fuel_gauge != 0)
00550         {
00551           mp_fuel_gauge->set (fuel);
00552         }
00553 }
00554 
00555 void
00556 Dashboard::set_gear_indicator (int gear)
00557 {
00558   if (mp_gear_indicator != 0)
00559         {
00560           mp_gear_indicator->set (gear);
00561         }
00562 }
00563 
00564 void
00565 Dashboard::set_steering_wheel (double angle)
00566 {
00567   if (mp_steering_wheel != 0)
00568         {
00569           mp_steering_wheel->set (angle);
00570         }
00571 }
00572 
00573 void
00574 Dashboard::draw () const
00575 {
00576   glTranslated (m_x, m_y, m_z);
00577 
00578   std::for_each (ma_facades.begin (), ma_facades.end (),
00579                                  std::mem_fun (&Facade::draw));
00580 
00581   glRotated (m_tilt, 0.0, 1.0, 0.0);
00582 
00583   if ((mp_tachometer != 0) && !mp_tachometer->on_steering_wheel ())
00584         {
00585           mp_tachometer->draw ();
00586         }
00587   if ((mp_speedometer != 0) && !mp_speedometer->on_steering_wheel ())
00588         {
00589           mp_speedometer->draw ();
00590         }
00591   if ((mp_fuel_gauge != 0) && !mp_fuel_gauge->on_steering_wheel ())
00592         {
00593           mp_fuel_gauge->draw ();
00594         }
00595   if ((mp_gear_indicator != 0) && !mp_gear_indicator->on_steering_wheel ())
00596         {
00597           mp_gear_indicator->draw ();
00598         }
00599   if (mp_steering_wheel != 0)
00600         {
00601           mp_steering_wheel->draw ();
00602         }
00603 
00604   glDisable (GL_DEPTH_TEST);
00605   if ((mp_tachometer != 0) && mp_tachometer->on_steering_wheel ())
00606         {
00607           mp_tachometer->draw ();
00608         }
00609   if ((mp_speedometer != 0) && mp_speedometer->on_steering_wheel ())
00610         {
00611           mp_speedometer->draw ();
00612         }
00613   if ((mp_fuel_gauge != 0) && mp_fuel_gauge->on_steering_wheel ())
00614         {
00615           mp_fuel_gauge->draw ();
00616         }
00617   if ((mp_gear_indicator != 0) && mp_gear_indicator->on_steering_wheel ())
00618         {
00619           mp_gear_indicator->draw ();
00620         }
00621   glEnable (GL_DEPTH_TEST);
00622 }
00623 
00624 } // namespace Vamos_Body

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