[go: up one dir, main page]

Menu

[f338fb]: / track / Road_Segment.h  Maximize  Restore  History

Download this file

432 lines (350 with data), 16.7 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
// Copyright (C) 2001--2003 Sam Varner
//
// This file is part of Vamos Automotive Simulator.
//
// Vamos 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 3 of the License, or
// (at your option) any later version.
//
// Vamos 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 Vamos. If not, see <http://www.gnu.org/licenses/>.
#ifndef _ROAD_SEGMENT_H_
#define _ROAD_SEGMENT_H_
#include "../geometry/Conversions.h"
#include "../geometry/Linear_Interpolator.h"
#include "../geometry/Rectangle.h"
#include "../geometry/Spline.h"
#include "../geometry/Three_Vector.h"
#include "../geometry/Two_Vector.h"
#include <string>
#include <vector>
#include <complex>
namespace Vamos_Track
{
typedef std::vector <Vamos_Geometry::Two_Vector> TPoints;
//===========================================================================
/// @class Kerb
/// Rumble strips on the sides of the track.
class Kerb
{
public:
/// The constructor defines the geometry of the kerb.
///
/// The kerb shape is defined by the profile. Transition zones may be
/// defined to make the kerb taper to the ground. Transition zones do not
/// add to the length of the kerb. A zero-length transition zone leaves the
/// kerb open on the end. This is useful for connecting kerbs across
/// segment boundaries. The roughness of the kerb is defined by the
/// material assigned to it in the track object.
///
/// @param profile the shape of the kerb defined by a vector of Two_Vectors
/// where x is the distance from the edge of the track and y is the height.
/// @param start the distance from the start of the road segment to the
/// start of the kerb.
/// @param start_transition_length the distance from the start of the kerb
/// to the end of the transition.
/// @ param start_transition_width the width of the kerb where it meets the
/// ground.
/// @param end the distance from the start of the road segment to the end of
/// the kerb.
/// @param end_transition_length the distance from the start of transition
/// to the end of the kerb
/// @ param end_transition_width the width of the kerb where it meets the
/// ground.
Kerb (const TPoints& profile,
double start,
double start_transition_length,
double start_transition_width,
double end,
double end_transition_length,
double end_transition_width,
bool full_length);
/// Change the length of the kerb, perhaps because the length of its road
/// segment has changed.
/// @param length the new length.
void set_length (double length);
double transition_start () const { return m_start; }
double transition_end () const { return m_end; }
double start () const { return m_start + m_start_transition_length; }
double end () const { return m_end - m_end_transition_length; }
double start_transition_width () const { return m_start_transition_width; }
double end_transition_width () const { return m_end_transition_width; }
double width () const;
/// @return true if 'dist' along the segment is between the start and end of
/// the kerb.
bool on_kerb (double dist) const;
/// @param along distance along the segment.
/// @param from_inside distance from the inside edge of the kerb.
/// @return the height of the kerb above the ground at the given point.
double elevation (double along, double from_inside);
/// @param along distance along the segment.
/// @param from_inside distance from the inside edge of the kerb.
/// @return the angle of the normal vector relative to the ground.
double angle (double along, double from_inside);
/// @return a profile point.
const Vamos_Geometry::Two_Vector& point (size_t substrip) const;
/// @return the number of flat surfaces on the kerb.
size_t substrips () const { return m_points.size () - 1; }
private:
TPoints m_points;
Vamos_Geometry::Linear_Interpolator m_profile;
double m_start;
double m_start_transition_length;
double m_start_transition_width;
double m_end;
double m_end_transition_length;
double m_end_transition_width;
bool m_full_length;
};
//===========================================================================
/// @class Banking
/// Track banking parameters
class Banking
{
public:
Banking ();
~Banking ();
void set (double end_angle, double pivot_from_center);
double angle (double along) const;
double height (double along, double from_center) const;
void set_start (double start_angle, double length);
double start_angle () const { return m_start_angle; }
double end_angle () const { return m_end_angle; }
private:
Vamos_Geometry::Spline m_bank_angle;
double m_start_angle;
double m_end_angle;
double m_pivot_from_center;
};
//=============================================================================
/// @class Pit_Lane_Transition
/// Parameters for places where the pit lane merges with the track.
class Pit_Lane_Transition
{
public:
Pit_Lane_Transition ();
void set_merge (Vamos_Geometry::Direction direction,
Vamos_Geometry::Direction side,
double split_or_join,
double merge,
double angle);
void set_width (double pit_width,
double left_shoulder,
double right_shoulder);
Vamos_Geometry::Direction direction () const { return m_direction; }
Vamos_Geometry::Direction side () const { return m_side; }
double merge () const { return active () ? m_merge : 0.0; }
double split_or_join () const { return active () ? m_split_or_join : 0.0; }
double width (Vamos_Geometry::Direction side, double distance, bool narrow) const;
double shoulder_width () const { return m_pit_shoulder_width; }
void scale (double factor);
double angle () const { return m_angle; }
double skew (double length) const { return length / cos (m_angle); }
// Scale length to account for the skew.
bool active () const { return m_merge_is_set && m_width_is_set; }
private:
Vamos_Geometry::Direction m_direction;
Vamos_Geometry::Direction m_side;
double m_split_or_join;
double m_merge;
double m_angle;
double m_pit_width;
double m_pit_shoulder_width;
bool m_merge_is_set;
bool m_width_is_set;
};
//===========================================================================
/// @class Road_Segment
/// A straight or curved section of road
class Road_Segment
{
friend class Segment_Iterator;
public:
/// @param length the length of the segment at the centereline.
/// @param radius the radius of the curve at the centerline of the segment.
/// Set to 0 for a straight segment.
/// @param left_width the distance from the centerline to the left barrier.
/// @param right_width the distance from the centerline to the right
/// barrier.
/// @param left_road_width the width of road surface to the left of the
/// centerline.
/// @param right_road_width the width of road surface to the right of the
/// centerline.
Road_Segment (double length,
double radius,
double left_width,
double right_width,
double left_road_width,
double right_road_width);
virtual ~Road_Segment ();
/// @return the length of the segment at the centerline.
double length () const { return m_length; }
/// Change the length of he segment.
void set_length (double new_length);
/// @return the radius of the segment at the centerline or zero if the
/// segment is straight.
double radius () const { return m_radius; }
/// Set the radius of the curve. Preserve the length if the segment is
/// currently straight, otherwise preserve the arc.
void set_radius (double new_radius);
/// @return true if the segment is straight.
bool is_straight () const { return m_radius == 0.0; }
/// @return the arc in radians that the segment subtends.
double arc () const;
/// Set the arc of the curve. Preserve the radius if the segment is
/// currently curve, otherwise preserve the length.
void set_arc (double new_arc);
Vamos_Geometry::Three_Vector center_of_curve () const;
double left_width (double distance, bool narrow = false) const;
double right_width (double distance, bool narrow = false) const;
double width (double distance) const
{ return left_width (distance) + right_width (distance); }
double left_road_width_no_pit (double distance) const;
double right_road_width_no_pit (double distance) const;
double left_road_width (double distance, bool narrow = false) const;
double right_road_width (double distance, bool narrow = false) const;
double left_wall_height () const { return m_left_wall_height; }
double right_wall_height () const { return m_right_wall_height; }
double left_racing_line_width (double distance) const;
double right_racing_line_width (double distance) const;
void set_left_width (double distance, double width);
void set_right_width (double distance, double width);
void set_left_road_width (double distance, double width);
void set_right_road_width (double distance, double width);
void set_racing_line_adjustment (double across, double distance);
void set_racing_line_margin (double margin);
void set_wall_heights (double left_height, double right_height);
void set_start_skew (double skew) { m_start_skew = skew; }
void set_end_skew (double skew) { m_end_skew = skew; }
double start_skew () const { return m_start_skew; }
double end_skew () const { return m_end_skew; }
double elevation (double along, double from_center) const;
void build_elevation (Vamos_Geometry::Spline* elevation,
double start_distance);
// A convenience function for getting the elevation at a point in
// world coordinates. Use 'coordinates()' if you need the x and y
// track coodinates as well.
double world_elevation (const Vamos_Geometry::Three_Vector& world_position) const;
const Banking& banking () const { return m_banking; }
// Return the normal vector at the given location.
Vamos_Geometry::Three_Vector normal (double along,
double from_center,
const Vamos_Geometry::Three_Vector& bump,
bool include_kerb = true) const;
// Return the normal vector ignoring bumpiness.
Vamos_Geometry::Three_Vector normal (double along,
double from_center,
bool include_kerb = true) const;
Vamos_Geometry::Three_Vector
barrier_normal (double along,
double from_center,
const Vamos_Geometry::Three_Vector& bump) const;
Vamos_Geometry::Three_Vector barrier_normal (double along, double from_center) const;
Vamos_Geometry::Three_Vector end_coords () const;
Vamos_Geometry::Three_Vector start_coords () const
{ return m_start_coords; }
void set_start_coords (const Vamos_Geometry::Three_Vector& x)
{ m_start_coords = x; }
double angle (double along) const
{ return m_start_angle + arc () * along / m_length; }
void set_kerb (Kerb* kerb, Vamos_Geometry::Direction side);
void scale (double factor);
void set_pit_lane (Vamos_Geometry::Direction direction,
Vamos_Geometry::Direction side,
double split_or_join,
double merge,
double angle);
void set_pit_width (double width,
double left_shoulder,
double right_shoulder);
double pit_width () const;
bool on_pit_merge (double distance, double from_center) const;
virtual void set_start (const Vamos_Geometry::Three_Vector& start_coords,
double start_distance,
double start_angle,
double start_bank,
const std::vector <double>& texture_offsets);
/// @return the direction at the start of the segment in radians.
double start_angle () const { return m_start_angle; }
void set_start_angle (double radians) { m_start_angle = radians; }
/// @return the direction at the end of the segment in radians.
double end_angle () const;
double pit_angle () const { return angle (m_pit.split_or_join ()); }
double start_distance () const { return m_start_distance; }
double end_distance () const { return m_start_distance + m_length; }
void last_segment (bool last) { m_last_segment = last; }
// Do the world-to-track coordinate transformation.
double coordinates (const Vamos_Geometry::Three_Vector& world_pos,
Vamos_Geometry::Three_Vector& track_pos) const;
// Do the track-to-world coordinate transformation.
Vamos_Geometry::Three_Vector position (double along,
double from_center) const;
const Pit_Lane_Transition& pit () const;
void narrow (Vamos_Geometry::Direction side, double delta_width);
// Subtract delta_width from this segment's width.
void set_racing_line_curvature_factor (double factor)
{ m_racing_line_curvature_factor = factor; }
double racing_line_curvature_factor () const
{ return m_racing_line_curvature_factor; }
protected:
double kerb_width (Vamos_Geometry::Direction side, double along) const;
void set_banking (double end_angle, double pivot)
{ m_banking.set (end_angle, pivot); }
void set_elevation_points (const TPoints& elevation)
{ m_elevation_points = elevation; }
void set_widths (const TPoints& right, const TPoints& right_road,
const TPoints& left_road, const TPoints& left);
double pit_road_connection () const;
bool is_last_segment () const { return m_last_segment; }
private:
// The length of the centerline of the segment.
double m_length;
// The radius of curvature; 0.0 for a straight segment.
double m_radius;
// The distance from the center line to the walls.
Vamos_Geometry::Linear_Interpolator m_left_width;
Vamos_Geometry::Linear_Interpolator m_right_width;
// The distance from the center line to the edges of the track.
Vamos_Geometry::Linear_Interpolator m_left_road_width;
Vamos_Geometry::Linear_Interpolator m_right_road_width;
double m_racing_line_adjustment;
double m_racing_line_adjustment_distance;
// The heights of the walls.
double m_left_wall_height;
double m_right_wall_height;
double m_start_skew;
double m_end_skew;
TPoints m_elevation_points;
Vamos_Geometry::Spline* mp_elevation_curve;
Banking m_banking;
Kerb* mp_left_kerb;
Kerb* mp_right_kerb;
Pit_Lane_Transition m_pit;
// The distance along the track where this segment starts.
double m_start_distance;
double m_start_angle;
Vamos_Geometry::Three_Vector m_start_coords;
// True if this is the last segment of a circuit.
bool m_last_segment;
double m_racing_line_curvature_factor;
Road_Segment (const Road_Segment& segment);
void scale_widths (double factor);
// Find the angle from the beginning of a curve.
double get_curve_angle (const Vamos_Geometry::Three_Vector& position,
double across) const;
// How far is the position off the end (+ve) or beginning (-ve) of
// the segment? Return 0 if the position is on the segment.
double off_track_distance (const Vamos_Geometry::Three_Vector&
track_position) const;
double extra_road_width (Vamos_Geometry::Direction side,
double distance,
bool narrow) const;
};
}
#endif // not _ROAD_SEGMENT_H_