00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <vamos/track/Strip_Track.h>
00021 #include <vamos/geometry/Spline.h>
00022 #include <vamos/geometry/Gl_Texture_Image.h>
00023
00024 #include <GL/glu.h>
00025
00026 #include <cmath>
00027 #include <sstream>
00028 #include <cassert>
00029
00030 using namespace Vamos_Geometry;
00031
00032
00033
00034 Vamos_Track::
00035 Strip_Track::Strip_Track () :
00036 m_min_x (0.0),
00037 m_max_x (0.0),
00038 m_min_y (0.0),
00039 m_max_y (0.0),
00040
00041 m_length (0.0),
00042 m_sky_list_id (0)
00043 {
00044 m_timing_lines.clear ();
00045 }
00046
00047 extern bool verbose_output;
00048
00049 Vamos_Track::
00050 Strip_Track::~Strip_Track ()
00051 {
00052 if (verbose_output)
00053 std::cout << "track deinit" << std::endl;
00054 for (std::vector <Road_Segment*>::iterator it = m_segments.begin ();
00055 it != m_segments.end ();
00056 it++)
00057 {
00058 delete (*it);
00059 }
00060
00061
00062 if (verbose_output)
00063 std::cout << "track deinit done" << std::endl;
00064 }
00065
00066
00067 void Vamos_Track::
00068 Strip_Track::read (std::string data_dir, std::string track_file)
00069 {
00070
00071 if ((data_dir != "") && (track_file != ""))
00072 {
00073 m_data_dir = data_dir;
00074 m_track_file = track_file;
00075 }
00076
00077 m_min_x = 0.0;
00078 m_max_x = 0.0;
00079 m_min_y = 0.0;
00080 m_max_y = 0.0;
00081
00082 for (std::vector <Road_Segment*>::iterator it = m_segments.begin ();
00083 it != m_segments.end ();
00084 it++)
00085 {
00086 delete (*it);
00087 }
00088 m_segments.clear ();
00089 m_timing_lines.clear ();
00090
00091 Strip_Track_Reader reader (m_data_dir, m_track_file, this);
00092 }
00093
00094 void Vamos_Track::
00095 Strip_Track::build_sky_box (std::string sides_image,
00096 std::string top_image,
00097 std::string bottom_image,
00098 bool smooth)
00099 {
00100 if (m_sky_list_id != 0)
00101 {
00102 glDeleteLists (m_sky_list_id, 1);
00103 }
00104
00105 double height = 400.0;
00106 double length = 400.0;
00107 double width = 400.0;
00108
00109 double x = -length / 2.0;
00110 double y = -width / 2.0;
00111 double z = -height / 2.0;
00112
00113 Gl_Texture_Image sky_sides (sides_image, smooth);
00114 Gl_Texture_Image sky_top (top_image, smooth);
00115 Gl_Texture_Image sky_bottom (bottom_image, smooth);
00116
00117
00118 sky_sides.clamp_to_edge ();
00119 sky_top.clamp_to_edge ();
00120 sky_bottom.clamp_to_edge ();
00121
00122 m_sky_list_id = glGenLists (1);
00123 glNewList (m_sky_list_id, GL_COMPILE);
00124
00125 glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
00126
00127 sky_sides.activate ();
00128
00129
00130 glBegin (GL_QUAD_STRIP);
00131 glTexCoord2d (0.0, 0.0);
00132 glVertex3d (x + length, y + width, z + height);
00133 glTexCoord2d (0.0, 1.0);
00134 glVertex3d (x + length, y + width, z);
00135 glTexCoord2d (0.25, 0.0);
00136 glVertex3d (x + length, y, z + height);
00137 glTexCoord2d (0.25, 1.0);
00138 glVertex3d (x + length, y, z);
00139
00140
00141 glTexCoord2d (0.25, 0.0);
00142 glVertex3d (x + length, y, z + height);
00143 glTexCoord2d (0.25, 1.0);
00144 glVertex3d (x + length, y, z);
00145 glTexCoord2d (0.5, 0.0);
00146 glVertex3d (x, y, z + height);
00147 glTexCoord2d (0.5, 1.0);
00148 glVertex3d (x, y, z);
00149
00150
00151 glTexCoord2d (0.5, 0.0);
00152 glVertex3d (x, y, z + height);
00153 glTexCoord2d (0.5, 1.0);
00154 glVertex3d (x, y, z);
00155 glTexCoord2d (0.75, 0.0);
00156 glVertex3d (x, y + width, z + height);
00157 glTexCoord2d (0.75, 1.0);
00158 glVertex3d (x, y + width, z);
00159
00160
00161 glTexCoord2d (0.75, 0.0);
00162 glVertex3d (x, y + width, z + height);
00163 glTexCoord2d (0.75, 1.0);
00164 glVertex3d (x, y + width, z);
00165 glTexCoord2d (1.0, 0.0);
00166 glVertex3d (x + length, y + width, z + height);
00167 glTexCoord2d (1.0, 1.0);
00168 glVertex3d (x + length, y + width, z);
00169 glEnd();
00170
00171
00172 sky_top.activate ();
00173
00174 glBegin (GL_QUADS);
00175 glTexCoord2d (0.0, 0.0);
00176 glVertex3d (x, y + width, z + height);
00177 glTexCoord2d (0.0, 1.0);
00178 glVertex3d (x + length, y + width, z + height);
00179 glTexCoord2d (1.0, 1.0);
00180 glVertex3d (x + length, y, z + height);
00181 glTexCoord2d (1.0, 0.0);
00182 glVertex3d (x, y, z + height);
00183 glEnd();
00184
00185
00186 sky_bottom.activate ();
00187
00188 glBegin (GL_QUADS);
00189 glTexCoord2d (0.0, 0.0);
00190 glVertex3d (x, y + width, z);
00191 glTexCoord2d (0.0, 1.0);
00192 glVertex3d (x, y + width, z);
00193 glTexCoord2d (1.0, 1.0);
00194 glVertex3d (x + length, y, z);
00195 glTexCoord2d (1.0, 0.0);
00196 glVertex3d (x + length, y, z);
00197 glEnd();
00198
00199 glFlush ();
00200 glEndList ();
00201 }
00202
00203
00204 void Vamos_Track::
00205 Strip_Track::add_segment (Road_Segment* seg)
00206 {
00207 m_segments.push_back (seg);
00208 }
00209
00210
00211 void Vamos_Track::
00212 Strip_Track::build (bool is_closed, double track_length)
00213 {
00214 set_skews ();
00215 if (is_closed)
00216 {
00217 build_circuit ();
00218 }
00219 if (track_length != 0.0)
00220 {
00221 set_length (track_length);
00222 }
00223
00224 m_length = 0.0;
00225
00226
00227
00228
00229 Three_Vector start_coords (0.0, 0.0, 0.0);
00230 double start_angle = 0.0;
00231 double start_bank = 0.0;
00232
00233 for (std::vector <Road_Segment*>::iterator it = m_segments.begin ();
00234 it != m_segments.end ();
00235 it++)
00236 {
00237
00238 m_length += (*it)->length ();
00239 }
00240
00241 size_t strips = (*(m_segments.begin ()))->materials ().size ();
00242 std::vector <double> texture_offsets (strips);
00243
00244
00245 utility.SelectTU(1);
00246 glEnable(GL_TEXTURE_2D);
00247 detailtex = textures.Load("track/track2.png", true);
00248 glBindTexture(GL_TEXTURE_2D, detailtex);
00249 utility.SelectTU(0);
00250
00251 m_length = 0.0;
00252 for (std::vector <Road_Segment*>::iterator it = m_segments.begin ();
00253 it != m_segments.end ();
00254 it++)
00255 {
00256 (*it)->build (m_length, start_coords, start_angle, start_bank,
00257 texture_offsets, detailtex);
00258 texture_offsets = (*it)->texture_offsets ();
00259
00260
00261 if ((*it)->min_x () < m_min_x)
00262 m_min_x = (*it)->min_x ();
00263 if ((*it)->max_x () > m_max_x)
00264 m_max_x = (*it)->max_x ();
00265 if ((*it)->min_y () < m_min_y)
00266 m_min_y = (*it)->min_y ();
00267 if ((*it)->max_y () > m_max_y)
00268 m_max_y = (*it)->max_y ();
00269
00270 m_length += (*it)->length ();
00271 start_coords = (*it)->end_coords ();
00272 start_angle = (*it)->end_angle ();
00273 start_bank = (*it)->end_bank ();
00274 }
00275 }
00276
00277 void Vamos_Track::
00278 Strip_Track::set_skews ()
00279 {
00280 for (std::vector <Road_Segment*>::iterator it = m_segments.begin () + 1;
00281 it != m_segments.end ();
00282 it++)
00283 {
00284 double skew = (*it)->skew ();
00285 if ((skew != 0.0) && ((*it)->arc () != 0.0))
00286 {
00287 if ((*(it - 1))->arc () == 0.0)
00288 (*(it - 1))->set_end_skew (skew);
00289 if ((*(it + 1))->arc () == 0.0)
00290 (*(it + 1))->set_start_skew (-skew);
00291 }
00292 }
00293 }
00294
00295 void Vamos_Track::
00296 Strip_Track::build_circuit ()
00297 {
00298 Road_Segment* last_straight = *(m_segments.end () - 1);
00299 Road_Segment* last_curve = *(m_segments.end () - 2);
00300 Road_Segment* other_straight = *(m_segments.end () - 3);
00301
00302 if ((last_straight->radius () != 0.0)
00303 || (last_curve->radius () == 0.0)
00304 || (other_straight->radius () != 0.0))
00305 {
00306 throw Can_Not_Close ();
00307 }
00308
00309 double end_x = 0.0;
00310 double end_y = 0.0;
00311 double end_angle = 0.0;
00312 double straight_angle = 0.0;
00313 double center_x = 0.0;
00314 double center_y = 0.0;
00315 for (std::vector <Road_Segment*>::iterator it = m_segments.begin ();
00316 it != m_segments.end () - 1;
00317 it++)
00318 {
00319 if ((*it)->radius () == 0.0)
00320 {
00321 end_x += (*it)->length () * cos (end_angle);
00322 end_y += (*it)->length () * sin (end_angle);
00323 straight_angle = end_angle;
00324 }
00325 else
00326 {
00327 center_x = end_x - (*it)->radius () * sin (end_angle);
00328 center_y = end_y + (*it)->radius () * cos (end_angle);
00329 end_angle += (*it)->arc ();
00330 end_x = center_x + (*it)->radius () * sin (end_angle);
00331 end_y = center_y - (*it)->radius () * cos (end_angle);
00332 }
00333 }
00334
00335
00336
00337 end_angle -= last_curve->arc ();
00338 if (end_angle > pi)
00339 {
00340 end_angle = 2.0 * pi - end_angle;
00341 }
00342 else if (end_angle < -pi)
00343 {
00344 end_angle = -2.0 * pi - end_angle;
00345 }
00346 else
00347 {
00348 end_angle = -end_angle;
00349 }
00350
00351 last_curve->set_arc (end_angle);
00352
00353 double delta_length =
00354 -(center_y - last_curve->radius ()) / sin (straight_angle);
00355 other_straight->set_length (other_straight->length () + delta_length);
00356
00357 last_straight->set_length (-center_x
00358 - delta_length * cos (straight_angle)
00359 + 0.5);
00360
00361
00362 last_straight->last_segment (true);
00363 }
00364
00365 void Vamos_Track::
00366 Strip_Track::draw_sky (const Vamos_Geometry::Three_Vector& view) const
00367 {
00368 glLoadIdentity ();
00369 glTranslatef (view [0], view [1], view [2]);
00370
00371
00372
00373 glCallList (m_sky_list_id);
00374 glClear (GL_DEPTH_BUFFER_BIT);
00375 }
00376
00377 void Vamos_Track::
00378 Strip_Track::draw () const
00379 {
00380
00381 for (std::vector <Road_Segment*>::const_iterator it = m_segments.begin ();
00382 it != m_segments.end ();
00383 it++)
00384 {
00385 (*it)->draw ();
00386 }
00387 }
00388
00389 void Vamos_Track::Strip_Track::
00390 speed_trap (double start, double end)
00391 {
00392 m_speed_trap_start = start;
00393 m_speed_trap_end = end;
00394 }
00395
00396
00397 void Vamos_Track::
00398 Strip_Track::set_length (double length)
00399 {
00400 assert (m_segments.size () != 0);
00401
00402
00403 double old_length = 0.0;
00404 for (std::vector <Road_Segment*>::iterator it = m_segments.begin ();
00405 it != m_segments.end ();
00406 it++)
00407 {
00408 old_length += (*it)->length ();
00409 }
00410
00411 assert (old_length != 0.0);
00412 double factor = length / old_length;
00413
00414
00415 for (std::vector <Road_Segment*>::iterator it = m_segments.begin ();
00416 it != m_segments.end ();
00417 it++)
00418 {
00419 (*it)->scale (factor);
00420 }
00421 }
00422
00424
00425
00426
00427 Three_Vector Vamos_Track::
00428 Strip_Track::reset_position (const Three_Vector& pos,
00429 size_t& segment_index)
00430 {
00431 const Three_Vector& track_pos = track_coordinates (pos, segment_index);
00432
00433 const Road_Segment* segment = m_segments [segment_index];
00434 const double along = track_pos [0] - segment->start_distance ();
00435 Three_Vector direction = segment->barrier_normal (along, -1.0);
00436 direction [2] = -sin (segment->bank (along));
00437
00438 const double across = track_pos [1];
00439 return pos - across * direction;
00440 }
00441
00442
00443
00444 Three_Matrix Vamos_Track::
00445 Strip_Track::reset_orientation (const Three_Vector& pos,
00446 size_t& segment_index)
00447 {
00448 Three_Matrix orientation;
00449 orientation.identity ();
00450
00451
00452 const Three_Vector& track_pos = track_coordinates (pos, segment_index);
00453
00454 const Road_Segment* segment = m_segments [segment_index];
00455 const double along = track_pos [0] - segment->start_distance ();
00456 const double across = track_pos [1];
00457 Three_Vector normal = segment->normal (along, across);
00458 orientation.rotate (Three_Vector (-asin (normal [1]),
00459 asin (normal [0]),
00460 segment->angle (along)));
00461 return orientation;
00462 }
00463
00464
00465 double Vamos_Track::
00466 Strip_Track::elevation (const Three_Vector& pos,
00467 double bump_parameter,
00468 size_t& segment_index)
00469 {
00470
00471
00472
00473 track_coordinates(pos, segment_index);
00474
00475 return m_segments[segment_index]->elevationxy(pos[0], pos[1])
00476 + m_material->bump (bump_parameter);
00477 }
00478
00479 bool Vamos_Track::Strip_Track::ontrack(const Vamos_Geometry::Three_Vector& world_pos)
00480 {
00481 size_t segment_index = 0;
00482 int i = 0;
00483
00484 for (i = 0; i < (int) m_segments.size(); i++)
00485 {
00486 bool found = false;
00487 segment_index = i;
00488 Three_Vector track_pos = segment_coordinates (world_pos, segment_index, found);
00489
00490
00491 if (found)
00492 {
00493 if ((track_pos[1] >= 0 && track_pos[1] < m_segments[segment_index]->left_width(track_pos[0])) || (track_pos[1] < 0 && track_pos[1] > -m_segments[segment_index]->right_width(track_pos[0])))
00494 {
00495
00496
00497 return true;
00498 }
00499 }
00500 }
00501
00502 return false;
00503 }
00504
00505 size_t Vamos_Track::Strip_Track::getsegment(const Vamos_Geometry::Three_Vector& pos)
00506 {
00507
00508
00509
00510
00511
00512
00513 size_t segment_index = 0;
00514 int i = 0;
00515
00516 size_t insegment = 0;
00517
00518 for (i = 0; i < (int) m_segments.size(); i++)
00519 {
00520 segment_index = i;
00521
00522 Three_Vector track_pos;
00523 double innit = m_segments[segment_index]->coordinates (pos, track_pos);
00524
00525
00526
00527 if (innit == 0.0f && ((track_pos[1] >= 0 && track_pos[1] < m_segments[segment_index]->left_width(track_pos[0])) || (track_pos[1] < 0 && track_pos[1] > -m_segments[segment_index]->right_width(track_pos[0]))))
00528 {
00529
00530
00531
00532 insegment = i;
00533 }
00534 }
00535
00536 return insegment;
00537 }
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616 Three_Vector Vamos_Track::
00617 Strip_Track::track_coordinates (const Three_Vector& world_pos,
00618 size_t& segment_index)
00619 {
00620
00621
00622
00623 Three_Vector track_pos;
00624 assert (segment_index < m_segments.size ());
00625 Road_Segment* segment = m_segments [segment_index];
00626
00627
00628
00629
00630 double off = -1337;
00631
00632 size_t i = 0;
00633
00634 while (i < m_segments.size ())
00635 {
00636
00637 off = segment->coordinates (world_pos, track_pos);
00638
00639 if (off == 0.0)
00640 {
00641
00642 break;
00643 }
00644
00645 if (off > 0.0)
00646 {
00647 segment_index++;
00648 if (segment_index == m_segments.size ())
00649 {
00650 segment_index = 0;
00651 }
00652 }
00653 else
00654 {
00655 if (segment_index == 0)
00656 {
00657 segment_index = m_segments.size ();
00658 }
00659 segment_index--;
00660 }
00661 segment = m_segments [segment_index];
00662 i++;
00663 }
00664
00665
00666 if (i == m_segments.size ())
00667 {
00668 std::cout << "road segment not found" << std::endl;
00669
00670 throw Segment_Not_Found (world_pos);
00671 }
00672
00673 assert (segment_index < m_segments.size ());
00674 m_material = segment->material_at (track_pos [0], track_pos [1]);
00675 track_pos[0] += segment->start_distance ();
00676 return track_pos;
00677 }
00678
00679 Three_Vector Vamos_Track::
00680 Strip_Track::segment_coordinates (const Three_Vector& world_pos,
00681 size_t& segment_index, bool &found)
00682 {
00683
00684
00685
00686 Three_Vector track_pos;
00687 assert (segment_index < m_segments.size ());
00688 Road_Segment* segment = m_segments [segment_index];
00689
00690
00691
00692
00693 double off = -1337;
00694
00695 size_t i = 0;
00696
00697 while (i < m_segments.size ())
00698 {
00699
00700 off = segment->coordinates (world_pos, track_pos);
00701
00702 if (off == 0.0)
00703 {
00704 break;
00705 }
00706
00707 if (off > 0.0)
00708 {
00709 segment_index++;
00710 if (segment_index == m_segments.size ())
00711 {
00712 segment_index = 0;
00713 }
00714 }
00715 else
00716 {
00717 if (segment_index == 0)
00718 {
00719 segment_index = m_segments.size ();
00720 }
00721 segment_index--;
00722 }
00723 segment = m_segments [segment_index];
00724 i++;
00725 }
00726
00727
00728 if (i == m_segments.size ())
00729 {
00730
00731
00732 found = false;
00733 return track_pos;
00734 }
00735
00736
00737
00738
00739 found = true;
00740 assert (segment_index < m_segments.size ());
00741 m_material = segment->material_at (track_pos [0], track_pos [1]);
00742 track_pos [0] += segment->start_distance ();
00743 return track_pos;
00744 }
00745
00746 Vamos_Track::Track_Contact_Info Vamos_Track::
00747 Strip_Track::test_for_contact (const Three_Vector& pos,
00748 double bump_parameter,
00749 size_t& segment_index)
00750 {
00751 Three_Vector track_pos = track_coordinates (pos, segment_index);
00752 const Road_Segment* segment = m_segments [segment_index];
00753 track_pos [0] -= segment->start_distance ();
00754
00755 bool contact = false;
00756 Three_Vector normal;
00757
00758
00759 double diff = elevation (pos, bump_parameter, segment_index) - pos [2];
00760 if (diff >= 0.0)
00761 {
00762 contact = true;
00763 normal = segment->normal (track_pos [0], track_pos [1]);
00764 }
00765
00766
00767
00768 if (!contact)
00769 {
00770 const Material_Handle material = segment->left_material ();
00771 double bump = material->bump (bump_parameter);
00772 diff = track_pos [1] - (segment->left_width (track_pos [0]) + bump);
00773 if (diff >= 0.0)
00774 {
00775 contact = true;
00776 normal = segment->barrier_normal (track_pos [0], track_pos [1]);
00777 }
00778 }
00779
00780
00781 if (!contact)
00782 {
00783 const Material_Handle material = segment->right_material ();
00784 double bump = material->bump (bump_parameter);
00785 diff = -track_pos [1] - (segment->right_width (track_pos [0]) + bump);
00786 if (diff >= 0.0)
00787 {
00788 contact = true;
00789 normal = segment->barrier_normal (track_pos [0], track_pos [1]);
00790 }
00791 }
00792
00793 return Track_Contact_Info (contact, diff, normal, m_material);
00794 }
00795
00796
00797 double Vamos_Track::
00798 Strip_Track::distance (const Three_Vector& pos, size_t& segment_index)
00799 {
00800 return track_coordinates (pos, segment_index)[0];
00801 }
00802
00803 Three_Vector Vamos_Track::
00804 Strip_Track::position (double along, double from_center) const
00805 {
00806 assert ((along >= 0.0) && (along <= m_length));
00807 double distance = 0.0;
00808 for (std::vector <Road_Segment*>::const_iterator it = m_segments.begin ();
00809 it != m_segments.end ();
00810 it++)
00811 {
00812 if (distance + (*it)->length () >= along)
00813 {
00814 return (*it)->position (along - distance, from_center);
00815 }
00816 distance += (*it)->length ();
00817 }
00818 assert (false);
00819 return Three_Vector (0.0, 0.0, 0.0);
00820 }
00821
00822
00823 int Vamos_Track::
00824 Strip_Track::sector (double distance)
00825 {
00826 for (size_t i = 0; i < m_timing_lines.size (); i++)
00827 {
00828 if (m_timing_lines [i] > distance)
00829 return i - 1;
00830 }
00831 return m_timing_lines.size () - 1;
00832 }
00833
00834
00835
00836
00837 Vamos_Track::
00838 Strip_Track_Reader::Strip_Track_Reader (std::string data_dir,
00839 std::string track_file,
00840 Strip_Track* road)
00841 : m_first_road (true),
00842 m_data_dir (data_dir),
00843 mp_road (road),
00844 m_circuit (false),
00845 m_length (0.0)
00846 {
00847 read (data_dir + track_file);
00848 }
00849
00850 void Vamos_Track::
00851 Strip_Track_Reader::on_start_tag (const Vamos_Geometry::XML_Tag& tag)
00852 {
00853
00854 m_tag = tag.get_label ();
00855 m_path = m_path + '/' + m_tag;
00856
00857 const Vamos_Geometry::XML_Tag::Attribute_List&
00858 attribs = tag.get_attributes ();
00859
00860 if (m_tag == "sky")
00861 {
00862 m_strings.clear ();
00863 m_strings.resize (3);
00864 m_bools.clear ();
00865 m_bools.resize (1);
00866 }
00867 else if (m_tag == "material")
00868 {
00869 m_name = attribs [0].value;
00870 std::string type = attribs [1].value;
00871 if (type == "rubber")
00872 m_material_type = Material::RUBBER;
00873 else if (type == "metal")
00874 m_material_type = Material::METAL;
00875 else if (type == "asphalt")
00876 m_material_type = Material::ASPHALT;
00877 else if (type == "concrete")
00878 m_material_type = Material::CONCRETE;
00879 else if (type == "grass")
00880 m_material_type = Material::GRASS;
00881 else if (type == "gravel")
00882 m_material_type = Material::GRAVEL;
00883 else if (type == "dirt")
00884 m_material_type = Material::DIRT;
00885 else
00886 {
00887 std::cerr << "Strip_Track_Reader: Warning: Unknown material \""
00888 << attribs [1].value << '\"' << std::endl;
00889 m_material_type = Material::UNKNOWN;
00890 }
00891
00892 m_bools.clear ();
00893 m_bools.resize (2);
00894 m_doubles.clear ();
00895 m_doubles.resize (8);
00896 m_strings.clear ();
00897 }
00898 else if (m_tag == "segment")
00899 {
00900 m_name = attribs [0].value;
00901 m_strings.resize (7);
00902 }
00903 else if (m_tag == "road")
00904 {
00905 if (m_first_road)
00906 {
00907
00908
00909 m_doubles.clear ();
00910 m_doubles.resize (21);
00911 m_bools.clear ();
00912 m_bools.resize (6);
00913 m_points.clear ();
00914 m_points.resize (2);
00915 m_left_profile.clear ();
00916 m_right_profile.clear ();
00917
00918 m_first_road = false;
00919 }
00920
00921 m_doubles [3] = 0.0;
00922 m_doubles [6] = 0.0;
00923 m_doubles [9] = 0.0;
00924 m_doubles [12] = 0.0;
00925 m_doubles [20] = 0.0;
00926 m_strings.clear ();
00927 m_strings.resize (2);
00928 m_strings [0] = attribs [0].value;
00929 m_bools [0] = false;
00930 m_bools [1] = false;
00931 m_bools [2] = false;
00932 m_bools [3] = false;
00933 m_bools [4] = false;
00934 m_elev_points.clear ();
00935
00936 for (size_t i = 0; i < 4; i++)
00937 {
00938 if (m_point_vectors [i].size () > 0)
00939 {
00940 Two_Point last_point = *(m_point_vectors [i].end () - 1);
00941 last_point.x = 0.0;
00942 m_point_vectors [i].clear ();
00943 m_point_vectors [i].push_back (last_point);
00944 }
00945 }
00946
00947 m_braking_markers.clear ();
00948 m_model_info.clear ();
00949 }
00950 else if (m_tag == "left-kerb")
00951 {
00952 m_doubles [6] = -1.0;
00953 }
00954 else if (m_tag == "right-kerb")
00955 {
00956 m_doubles [12] = -1.0;
00957 }
00958 else if (m_tag == "circuit")
00959 {
00960 m_circuit = true;
00961 }
00962 else if (m_tag == "timing-line")
00963 {
00964 m_doubles.clear ();
00965 }
00966 else if (m_tag == "track-length")
00967 {
00968 m_doubles.clear ();
00969 }
00970
00971 if (m_path == "/track/road/left-kerb/start/transition")
00972 {
00973 m_bools [1] = true;
00974 }
00975 else if (m_path == "/track/road/left-kerb/end/transition")
00976 {
00977 m_bools [2] = true;
00978 }
00979 else if (m_path == "/track/road/right-kerb/start/transition")
00980 {
00981 m_bools [3] = true;
00982 }
00983 else if (m_path == "/track/road/right-kerb/end/transition")
00984 {
00985 m_bools [4] = true;
00986 }
00987 }
00988
00989 void Vamos_Track::
00990 Strip_Track_Reader::on_end_tag (const Vamos_Geometry::XML_Tag& tag)
00991 {
00992
00993 m_tag = tag.get_label ();
00994 m_path = m_path.substr (0, m_path.find_last_of ("/"));
00995
00996 if (m_tag == "sky")
00997 {
00998 mp_road->build_sky_box (m_data_dir + m_strings [0],
00999 m_data_dir + m_strings [1],
01000 m_data_dir + m_strings [2],
01001 m_bools [0]);
01002 }
01003 else if (m_tag == "material")
01004 {
01005 m_materials [m_name] =
01006 Material_Handle (new Material
01007 (m_material_type,
01008 m_doubles [0], m_doubles [1],
01009 m_doubles [2], m_doubles [3],
01010 m_doubles [4], m_doubles [5],
01011 new Gl_Texture_Image (m_data_dir + m_strings [0],
01012 m_bools [0],
01013 m_bools [1],
01014 m_doubles [6],
01015 m_doubles [7])));
01016 }
01017 else if (m_tag == "smooth")
01018 {
01019 m_bools [0] = true;
01020 }
01021 else if (m_tag == "mipmap")
01022 {
01023 m_bools [1] = true;
01024 }
01025 else if (m_tag == "segment")
01026 {
01027 std::vector <Material_Handle> mat;
01028 mat.resize (7);
01029 mat [0] = m_materials [m_strings [0]];
01030 mat [1] = m_materials [m_strings [1]];
01031 mat [2] = m_materials [m_strings [2]];
01032 mat [3] = m_materials [m_strings [3]];
01033 mat [4] = m_materials [m_strings [4]];
01034 mat [5] = m_materials [m_strings [5]];
01035 mat [6] = m_materials [m_strings [6]];
01036 m_segments [m_name] = mat;
01037 }
01038 else if (m_tag == "braking-marker")
01039 {
01040 Side side = m_bools [5] ? RIGHT : LEFT;
01041 m_braking_markers.
01042 push_back (new Braking_Marker (m_doubles [19],
01043 m_points [0],
01044 m_points [1],
01045 side,
01046 m_data_dir + m_strings [1]));
01047 }
01048 else if (m_tag == "model")
01049 {
01050 m_model_info.push_back (m_current_model_info);
01051 }
01052 else if (m_tag == "road")
01053 {
01054 double left_start_trans = m_bools [1] ? m_doubles [4] : 0.0;
01055 double left_end_trans = m_bools [2] ? m_doubles [7] : 0.0;
01056 double right_start_trans = m_bools [3] ? m_doubles [10] : 0.0;
01057 double right_end_trans = m_bools [4] ? m_doubles [13] : 0.0;
01058
01059 std::vector <Two_Point> vec;
01060
01061 if (!m_bools [0])
01062 {
01063 m_doubles [2] = 0.0;
01064 }
01065 Road_Segment* segment = new Road_Segment (m_doubles [0],
01066 m_doubles [1],
01067 m_doubles [2],
01068 m_doubles [20],
01069 m_point_vectors [0],
01070 m_point_vectors [1],
01071 m_point_vectors [2],
01072 m_point_vectors [3],
01073 new Kerb (m_left_profile,
01074 m_doubles [3],
01075 left_start_trans,
01076 m_doubles [5],
01077 m_doubles [6],
01078 left_end_trans,
01079 m_doubles [8]),
01080 new Kerb (m_right_profile,
01081 m_doubles [9],
01082 right_start_trans,
01083 m_doubles [11],
01084 m_doubles [12],
01085 right_end_trans,
01086 m_doubles [14]),
01087 m_doubles [15],
01088 m_doubles [16],
01089
01090 vec,
01091 m_doubles [17],
01092 m_doubles [18],
01093 m_segments [m_strings [0]],
01094 m_braking_markers);
01095 mp_road->add_segment (segment);
01096 for (std::vector <Road_Segment::Model_Info>::iterator
01097 it = m_model_info.begin ();
01098 it != m_model_info.end ();
01099 it++)
01100 {
01101 segment->add_model_info (*it);
01102 }
01103 }
01104 else if (m_tag == "timing-line")
01105 {
01106 mp_road->timing_line (m_doubles [0]);
01107 }
01108 else if (m_tag == "track")
01109 {
01110 mp_road->build (m_circuit, m_length);
01111 }
01112 }
01113
01114 void Vamos_Track::
01115 Strip_Track_Reader::on_data (std::string data_string)
01116 {
01117 std::string data = remove_leading_space (data_string);
01118 if (data.size () == 0)
01119 {
01120 return;
01121 }
01122 std::istringstream is (data.c_str ());
01123
01124 char delim;
01125
01126 if (m_path == "/track/sky/sides")
01127 {
01128 m_strings [0] = data;
01129 }
01130 else if (m_path == "/track/sky/top")
01131 {
01132 m_strings [1] = data;
01133 }
01134 else if (m_path == "/track/sky/bottom")
01135 {
01136 m_strings [2] = data;
01137 }
01138 else if (m_path == "/track/material/friction")
01139 {
01140 is >> m_doubles [0];
01141 }
01142 else if (m_path == "/track/material/restitution")
01143 {
01144 is >> m_doubles [1];
01145 }
01146 else if (m_path == "/track/material/rolling")
01147 {
01148 is >> m_doubles [2];
01149 }
01150 else if (m_path == "/track/material/drag")
01151 {
01152 is >> m_doubles [3];
01153 }
01154 else if (m_path == "/track/material/bump-amplitude")
01155 {
01156 is >> m_doubles [4];
01157 }
01158 else if (m_path == "/track/material/bump-wavelength")
01159 {
01160 is >> m_doubles [5];
01161 }
01162 else if (m_path == "/track/material/texture/width")
01163 {
01164 is >> m_doubles [6];
01165 }
01166 else if (m_path == "/track/material/texture/length")
01167 {
01168 is >> m_doubles [7];
01169 }
01170 else if (m_path == "/track/material/texture/file")
01171 {
01172 m_strings.push_back (data);
01173 }
01174 else if (m_path == "/track/segment")
01175 {
01176 is >> delim >> m_strings [0]
01177 >> m_strings [1]
01178 >> m_strings [2]
01179 >> m_strings [3]
01180 >> m_strings [4]
01181 >> m_strings [5]
01182 >> m_strings [6];
01183 }
01184 else if (m_path == "/track/road/resolution")
01185 {
01186 is >> m_doubles [0];
01187 }
01188 else if (m_path == "/track/road/length")
01189 {
01190 is >> m_doubles [1];
01191 }
01192 else if (m_path == "/track/road/radius")
01193 {
01194 m_bools [0] = true;
01195 is >> m_doubles [2];
01196 }
01197 else if (m_path == "/track/road/skew")
01198 {
01199 is >> m_doubles [20];
01200 }
01201 else if (m_path == "/track/road/left-width")
01202 {
01203 Two_Point point;
01204 is >> point;
01205 m_point_vectors [0].push_back (point);
01206 }
01207 else if (m_path == "/track/road/right-width")
01208 {
01209 Two_Point point;
01210 is >> point;
01211 m_point_vectors [1].push_back (point);
01212 }
01213 else if (m_path == "/track/road/left-road-width")
01214 {
01215 Two_Point point;
01216 is >> point;
01217 m_point_vectors [2].push_back (point);
01218 }
01219 else if (m_path == "/track/road/right-road-width")
01220 {
01221 Two_Point point;
01222 is >> point;
01223 m_point_vectors [3].push_back (point);
01224 }
01225
01226 else if (m_path == "/track/road/left-kerb/start/distance")
01227 {
01228 is >> m_doubles [3];
01229 }
01230 else if (m_path == "/track/road/left-kerb/start/transition/length")
01231 {
01232 is >> m_doubles [4];
01233 }
01234 else if (m_path == "/track/road/left-kerb/start/transition/width")
01235 {
01236 is >> m_doubles [5];
01237 }
01238 else if (m_path == "/track/road/left-kerb/end/distance")
01239 {
01240 is >> m_doubles [6];
01241 }
01242 else if (m_path == "/track/road/left-kerb/end/transition/length")
01243 {
01244 is >> m_doubles [7];
01245 }
01246 else if (m_path == "/track/road/left-kerb/end/transition/width")
01247 {
01248 is >> m_doubles [8];
01249 }
01250 else if (m_path == "/track/road/left-kerb/profile")
01251 {
01252 Two_Point point;
01253 m_left_profile.clear ();
01254 m_left_profile.push_back (point);
01255 while (is >> point)
01256 {
01257 m_left_profile.push_back (point);
01258 }
01259 }
01260
01261 else if (m_path == "/track/road/right-kerb/start/distance")
01262 {
01263 is >> m_doubles [9];
01264 }
01265 else if (m_path == "/track/road/right-kerb/start/transition/length")
01266 {
01267 is >> m_doubles [10];
01268 }
01269 else if (m_path == "/track/road/right-kerb/start/transition/width")
01270 {
01271 is >> m_doubles [11];
01272 }
01273 else if (m_path == "/track/road/right-kerb/end/distance")
01274 {
01275 is >> m_doubles [12];
01276 }
01277 else if (m_path == "/track/road/right-kerb/end/transition/length")
01278 {
01279 is >> m_doubles [13];
01280 }
01281 else if (m_path == "/track/road/right-kerb/end/transition/width")
01282 {
01283 is >> m_doubles [14];
01284 }
01285 else if (m_path == "/track/road/right-kerb/profile")
01286 {
01287 Two_Point point;
01288 m_right_profile.clear ();
01289 m_right_profile.push_back (point);
01290 while (is >> point)
01291 {
01292 m_right_profile.push_back (point);
01293 }
01294 }
01295
01296 else if (m_path == "/track/road/left-wall-height")
01297 {
01298 is >> m_doubles [15];
01299 }
01300 else if (m_path == "/track/road/right-wall-height")
01301 {
01302 is >> m_doubles [16];
01303 }
01304 else if (m_path == "/track/road/elevation")
01305 {
01306 char delim;
01307 double dist;
01308 double elev;
01309 is >> delim >> dist >> delim >> elev;
01310
01311 }
01312 else if (m_path == "/track/road/bank")
01313 {
01314 is >> m_doubles [17];
01315 }
01316 else if (m_path == "/track/road/bank-pivot")
01317 {
01318 is >> m_doubles [18];
01319 }
01320 else if (m_path == "/track/road/braking-marker/file")
01321 {
01322 m_strings [1] = data;
01323 }
01324 else if (m_path == "/track/road/braking-marker/distance")
01325 {
01326 is >> m_doubles [19];
01327 }
01328 else if (m_path == "/track/road/braking-marker/size")
01329 {
01330 is >> m_points [0];
01331 }
01332 else if (m_path == "/track/road/braking-marker/offset")
01333 {
01334 is >> m_points [1];
01335 }
01336 else if (m_path == "/track/road/braking-marker/side")
01337 {
01338 m_bools [5] = (data == "right");
01339 }
01340 else if (m_path == "/track/road/model/file")
01341 {
01342 std::string file;
01343 is >> file;
01344 m_current_model_info.file = m_data_dir + "tracks/" + file;
01345 }
01346 else if (m_path == "/track/road/model/scale")
01347 {
01348 is >> m_current_model_info.scale;
01349 }
01350 else if (m_path == "/track/road/model/translate")
01351 {
01352 is >> m_current_model_info.translation;
01353 }
01354 else if (m_path == "/track/road/model/rotate")
01355 {
01356 is >> m_current_model_info.rotation;
01357 }
01358 else if (m_path == "/track/track-length")
01359 {
01360 is >> m_length;
01361 }
01362 else
01363 {
01364 double arg;
01365 is >> arg;
01366 m_doubles.push_back (arg);
01367 }
01368 }