TORCS  1.3.10
The Open Racing Car Simulator
Loading...
Searching...
No Matches
rttrack.cpp
Go to the documentation of this file.
1/***************************************************************************
2 rttrack.cpp -- Track utilities functions
3 -------------------
4 created : Sat Aug 14 23:03:22 CEST 1999
5 copyright : (C) 1999-2026 by Eric EspiƩ, Bernhard Wymann
6 email : berniw@bluewin.ch
7
8***************************************************************************/
9
10/***************************************************************************
11 * *
12 * This program is free software; you can redistribute it and/or modify *
13 * it under the terms of the GNU General Public License as published by *
14 * the Free Software Foundation; either version 2 of the License, or *
15 * (at your option) any later version. *
16 * *
17 ***************************************************************************/
18
23
28
33
34
35#include <portability.h>
36#include <stdlib.h>
37#include <math.h>
38#ifdef WIN32
39#include <windows.h>
40#endif
41#include <tgf.h>
42#include <car.h>
43#include <track.h>
44
45#include <robottools.h>
46
60{
61 return fabs(seg->startWidth + toStart * seg->Kyl);
62}
63
64
80void
82{
83 tdble CosA, SinA, r, a;
84 tdble tr, toRight;
85 tTrackSeg *seg = p->seg;
86
87 // Compute the equivalent toRight for TR_TOMIDDLE and TR_TOLEFT. This way
88 // we can run for all cases the same calculations further below.
89 if (flag == TR_TOMIDDLE || flag == TR_TOLEFT) {
90 tdble width = RtTrackGetWidth(seg, p->toStart);
91
92 if (flag == TR_TOMIDDLE) {
93 toRight = (width / 2.0) + p->toMiddle;
94 } else { // TR_TOLEFT
95 toRight = width - p->toLeft;
96 }
97 } else {
98 toRight = p->toRight;
99 }
100
101 switch(seg->type) {
102 case TR_STR:
103 CosA = cos(seg->angle[TR_ZS]);
104 SinA = sin(seg->angle[TR_ZS]);
105
106 if (seg->type2 == TR_MAIN || seg->type2 == TR_LSIDE || seg->type2 == TR_LBORDER) {
107 tr = toRight;
108 } else if (seg->type2 == TR_RSIDE || seg->type2 == TR_RBORDER) {
109 tr = toRight - seg->Kyl * p->toStart;
110 } else {
111 tr = 0;
112 }
113
114 *X = seg->vertex[TR_SR].x + p->toStart * CosA - tr * SinA;
115 *Y = seg->vertex[TR_SR].y + p->toStart * SinA + tr * CosA;
116 break;
117
118 case TR_LFT:
119 case TR_RGT:
120 {
121 tdble sign = (seg->type == TR_LFT) ? 1.0f : -1.0f;
122 a = seg->angle[TR_ZS] + sign * p->toStart;
123
124 if (seg->type2 == TR_MAIN || seg->type2 == TR_LSIDE || seg->type2 == TR_LBORDER) {
125 r = seg->radiusr - sign * toRight;
126 } else if (seg->type2 == TR_RSIDE || seg->type2 == TR_RBORDER) {
127 r = seg->radiusl + sign * (seg->startWidth + seg->Kyl * p->toStart - toRight);
128 } else {
129 r = 0;
130 }
131
132 *X = seg->center.x + sign * r * sin(a);
133 *Y = seg->center.y - sign * r * cos(a);
134 break;
135 }
136 }
137}
138
139/* Shared implementation of the global-to-local conversions. */
140template <typename T>
141static void
142rtTrackGlobal2Local(tTrackSeg *segment, T X, T Y, tTrkLocPos *p, int type)
143{
144 int segnotfound = 1;
145 T x, y;
146 tTrackSeg *seg = segment;
147 T theta, a2;
148 int depl = 0;
149 tdble curWidth;
150
151 p->type = type;
152
153 while (segnotfound) {
154
155 switch(seg->type) {
156 case TR_STR:
157 /* rotation */
158 T sine, cosine;
159 T ts;
160
161 sine = sin(seg->angle[TR_ZS]);
162 cosine = cos(seg->angle[TR_ZS]);
163 x = X - seg->vertex[TR_SR].x;
164 y = Y - seg->vertex[TR_SR].y;
165 ts = x * cosine + y * sine;
166 p->seg = seg;
167 p->toStart = ts;
168 p->toRight = y * cosine - x * sine;
169 if ((ts < 0) && (depl < 1)) {
170 /* get back */
171 seg = seg->prev;
172 depl = -1;
173 } else if ((ts > seg->length) && (depl > -1)) {
174 seg = seg->next;
175 depl = 1;
176 } else {
177 segnotfound = 0;
178 }
179 break;
180
181 case TR_LFT:
182 case TR_RGT:
183 {
184 tdble sign = (seg->type == TR_LFT) ? 1.0f : -1.0f;
185
186 x = X - seg->center.x;
187 y = Y - seg->center.y;
188 a2 = seg->arc / 2.0;
189
190 theta = sign * (atan2(y, x) - seg->angle[TR_CS]) - a2;
191
192 while (theta > PI) {
193 theta -= (T)(2.0 * PI);
194 }
195 while (theta < -PI) {
196 theta += (T)(2.0 * PI);
197 }
198 p->seg = seg;
199 p->toStart = theta + a2;
200 p->toRight = sign * (seg->radiusr - sqrt(x * x + y * y));
201
202 if ((theta < -a2) && (depl < 1)) {
203 seg = seg->prev;
204 depl = -1;
205 }
206 else if ((theta > a2) && (depl > -1)) {
207 seg = seg->next;
208 depl = 1;
209 } else {
210 segnotfound = 0;
211 }
212
213 break;
214 }
215 }
216 }
217
218 /* The track is of constant width */
219 /* This is subject to change */
220 p->toMiddle = p->toRight - seg->width / 2.0;
221 p->toLeft = seg->width - p->toRight;
222
223 // Local position relative to the outermost barriers, mostly used for collision detection with barrier
224 if (type == TR_LPOS_TRACK) {
225 int side;
226 for (side = TR_SIDE_RGT; side <= TR_SIDE_LFT; side++) {
227 tdble* toSide = (side == TR_SIDE_RGT) ? (&p->toRight) : (&p->toLeft);
228 tTrackSeg *sseg = seg;
229 while ((sseg = sseg->side[side]) != NULL) {
230 *toSide += RtTrackGetWidth(sseg, p->toStart);
231 }
232 }
233 }
234
235 // Relative to the segment which the point is located, including border and sides, mostly used for contact physics
236 if (type == TR_LPOS_SEGMENT) {
237 tTrackSeg *sseg = seg;
238 int trSide;
239
240 // Determine which side to traverse to based on the position
241 if ((p->toRight < 0.0f) && (seg->side[TR_SIDE_RGT] != NULL)) {
242 trSide = TR_SIDE_RGT;
243 } else if ((p->toLeft < 0.0f) && (seg->side[TR_SIDE_LFT] != NULL)) {
244 trSide = TR_SIDE_LFT;
245 } else {
246 // Local position is already within the given segment
247 return;
248 }
249
250 // Set variables based on the side
251 tdble *toSide = (trSide == TR_SIDE_RGT) ? &p->toRight : &p->toLeft;
252 tdble *toOppositeSide = (trSide == TR_SIDE_RGT) ? &p->toLeft : &p->toRight;
253 tdble sign = (trSide == TR_SIDE_RGT) ? 1.0f : -1.0f;
254 tdble prevWidth = seg->width;
255
256 while ((*toSide < 0.0f) && (sseg->side[trSide] != NULL)) {
257 sseg = sseg->side[trSide];
258 p->seg = sseg;
259 curWidth = RtTrackGetWidth(sseg, p->toStart);
260 *toOppositeSide -= prevWidth;
261 *toSide += curWidth;
262 p->toMiddle += sign*(prevWidth + curWidth)/2.0f;
263 prevWidth = curWidth;
264 }
265 }
266}
267
268
275void
276RtTrackGlobal2LocalD(tTrackSeg *segment, double X, double Y, tTrkLocPos *p, int type)
277{
278 rtTrackGlobal2Local(segment, X, Y, p, type);
279}
280
281
297void
299{
300 rtTrackGlobal2Local(segment, X, Y, p, type);
301}
302
303
311static tTrackSeg *
313{
314 tdble tr = p->toRight;
315 tTrackSeg *seg = p->seg;
316
317 if ((tr < 0) && (seg->rside != NULL)) {
318 seg = seg->rside;
319 tr += seg->width;
320
321 if ((tr < 0) && (seg->rside != NULL)) {
322 seg = seg->rside;
323 tr += RtTrackGetWidth(seg, p->toStart);
324 }
325 } else if ((tr > seg->width) && (seg->lside != NULL)) {
326 tr -= seg->width;
327 seg = seg->lside;
328 if ((tr > seg->width) && (seg->lside != NULL)) {
329 tr -= RtTrackGetWidth(seg, p->toStart);
330 seg = seg->lside;
331 }
332 }
333
334 *toRight = tr;
335 return seg;
336}
337
338
364tdble
366{
367 tdble lg;
368 tdble tr;
369 tTrackSeg *seg = resolveTrackSeg(p, &tr);
370
371 switch (seg->type) {
372 case TR_STR:
373 lg = p->toStart;
374 break;
375 default:
376 lg = p->toStart * seg->radius;
377 break;
378 }
379
380 // Initial height on right side
381 tdble height_right_side = seg->vertex[TR_SR].z + p->toStart * seg->Kzl;
382 // Additional height because of banking angle
383 tdble banking_height = tr * tan(seg->angle[TR_XS] + p->toStart * seg->Kzw);
384 // Base height
385 tdble base_height = height_right_side + banking_height;
386
387 if (seg->style == TR_CURB) {
388 // The final height = starting height + height difference due
389 // to track angle + height difference due to curb (this seems
390 // to be the way it is implemented in the graphics too: the
391 // curb does not adding an angle to the main track, but a
392 // height in global coordinates).
393
394 tdble alpha = tr;
395 if (seg->type2 == TR_RBORDER) {
396 alpha = seg->width - tr;
397 }
398
399 tdble curb_roughness = seg->surface->kRoughness * sin(seg->surface->kRoughWaveLen * lg);
400 return base_height + alpha * (seg->height + curb_roughness) / seg->width;
401 }
402
403 return base_height +
404 seg->surface->kRoughness * sin(seg->surface->kRoughWaveLen * tr) * sin(seg->surface->kRoughWaveLen * lg);
405}
406
407
420{
421 if (current->side[tr_side] != NULL) {
422 return current->side[tr_side];
423 }
424
425 // Because of the above guard the neighbour has now to be on the inside. Switching direction because we
426 // are searching from the inside; we need to traverse the opposite side to find the matching segment.
427 int tr_other_side = (tr_side == TR_SIDE_LFT) ? TR_SIDE_RGT : TR_SIDE_LFT;
428 tTrackSeg *neighbour = main;
429 tTrackSeg *otherSurface = main;
430 while (neighbour->side[tr_other_side] != NULL) {
431 otherSurface = neighbour;
432 if (neighbour->side[tr_other_side] == current) {
433 break;
434 }
435 neighbour = neighbour->side[tr_other_side];
436 }
437
438 return otherSurface;
439}
440
441
449tTrackSeg *
451{
452 tdble toRight;
453 return resolveTrackSeg(p, &toRight);
454}
455
464tdble
466{
468
470 return RtTrackHeightL(&p);
471}
472
494void
496{
497 tdble lg;
498
499 switch (seg->type) {
500 case TR_STR:
501 if (side == TR_RGT) {
502 norm->x = seg->rgtSideNormal.x;
503 norm->y = seg->rgtSideNormal.y;
504 } else {
505 norm->x = -seg->rgtSideNormal.x;
506 norm->y = -seg->rgtSideNormal.y;
507 }
508 break;
509 case TR_RGT:
510 case TR_LFT:
511 // For curved segments: same side as curve direction = outward, opposite side = inward
512 if (side == seg->type) {
513 // outward: pos - center
514 norm->x = X - seg->center.x;
515 norm->y = Y - seg->center.y;
516 } else {
517 // inward: center - pos
518 norm->x = seg->center.x - X;
519 norm->y = seg->center.y - Y;
520 }
521
522 lg = 1.0 / sqrt(norm->x * norm->x + norm->y * norm->y);
523 norm->x *= lg;
524 norm->y *= lg;
525 break;
526 }
527}
528
537
538tdble
540{
541 switch (p->seg->type) {
542 case TR_STR:
543 return p->seg->angle[TR_ZS];
544 break;
545 case TR_RGT:
546 return p->seg->angle[TR_ZS] - p->toStart;
547 break;
548 case TR_LFT:
549 return p->seg->angle[TR_ZS] + p->toStart;
550 break;
551 }
552 return 0;
553}
554
555
566void
568{
569 tTrkLocPos p1;
570 t3Dd px1, px2, py1, py2;
571 t3Dd v1, v2;
572 tdble lg;
573
574 // Get to vectors, and calculate normal from the cross product.
575 p1.seg = p->seg;
576
577 // Points for vector along the track with points px1, px2
578 p1.toStart = 0;
579 p1.toRight = p->toRight;
580 RtTrackLocal2Global(&p1, &px1.x, &px1.y, TR_TORIGHT);
581 px1.z = RtTrackHeightL(&p1);
582
583 if (p1.seg->type == TR_STR) {
584 p1.toStart = p1.seg->length;
585 } else {
586 p1.toStart = p1.seg->arc;
587 }
588
589 RtTrackLocal2Global(&p1, &px2.x, &px2.y, TR_TORIGHT);
590 px2.z = RtTrackHeightL(&p1);
591
592 // Points for vector to the side of the track
593 // Determine if we take the vector on the start or end of the segment, for cases
594 // where start width or end width is 0. Does usually not matter, except on special
595 // cases like test tracks like ole-dirt
596 tdble width;
597 if (p1.seg->endWidth > p1.seg->startWidth) {
598 p1.toStart = p->toStart;
599 width = p1.seg->endWidth;
600 } else {
601 p1.toStart = 0;
602 width = p1.seg->startWidth;
603 }
604
605 p1.toRight = 0;
606 RtTrackLocal2Global(&p1, &py1.x, &py1.y, TR_TORIGHT);
607 py1.z = RtTrackHeightL(&p1);
608
609 p1.toRight = width;
610 RtTrackLocal2Global(&p1, &py2.x, &py2.y, TR_TORIGHT);
611 py2.z = RtTrackHeightL(&p1);
612
613 // Vector along the track with points px1, px2
614 v1.x = px2.x - px1.x;
615 v1.y = px2.y - px1.y;
616 v1.z = px2.z - px1.z;
617
618 // Vector to the side of the track py1, py2
619 v2.x = py2.x - py1.x;
620 v2.y = py2.y - py1.y;
621 v2.z = py2.z - py1.z;
622
623 norm->x = v1.y * v2.z - v2.y * v1.z;
624 norm->y = v2.x * v1.z - v1.x * v2.z;
625 norm->z = v1.x * v2.y - v2.x * v1.y;
626 lg = sqrt(norm->x * norm->x + norm->y * norm->y + norm->z * norm->z);
627
628 if (lg == 0.0) {
629 lg = 1.0;
630 } else {
631 lg = 1.0 / lg;
632 }
633
634 norm->x *= lg;
635 norm->y *= lg;
636 norm->z *= lg;
637}
638
639
645tdble
647{
648 return RtGetDistFromStart2(&(car->_trkPos));
649}
650
651
658tdble
660{
661 tTrackSeg *seg;
662 tdble lg;
663
664 seg = p->seg;
665 lg = seg->lgfromstart;
666
667 switch (seg->type) {
668 case TR_STR:
669 lg += p->toStart;
670 break;
671 default:
672 lg += p->toStart * seg->radius;
673 break;
674 }
675
676 return lg;
677}
678
679
691int
692RtDistToPit(struct CarElt *car, tTrack *track, tdble *dL, tdble *dW)
693{
694 tTrkLocPos *pitpos;
695 tTrkLocPos *carpos;
696 tdble pitts;
697 tdble carts;
698
699 if (car->_pit == NULL) return 1;
700
701 pitpos = &(car->_pit->pos);
702 carpos = &(car->_trkPos);
703
704 if (carpos->seg->radius) {
705 carts = carpos->toStart * carpos->seg->radius;
706 } else {
707 carts = carpos->toStart;
708 }
709
710 if (pitpos->seg->radius) {
711 pitts = pitpos->toStart * pitpos->seg->radius;
712 } else {
713 pitts = pitpos->toStart;
714 }
715
716 *dL = pitpos->seg->lgfromstart - carpos->seg->lgfromstart + pitts - carts;
717 if (*dL < 0.0f) {
718 *dL += track->length;
719 } else if (*dL > track->length) {
720 *dL -= track->length;
721 }
722
723 *dW = pitpos->toRight - carpos->toRight;
724
725 return 0;
726}
727
728
729static void RtReadCarPitSetupEntry(tCarPitSetupValue* v, const char* path, const char* key, void *hdle, bool minmaxonly)
730{
731 if (!minmaxonly) {
732 v->value = GfParmGetNum(hdle, path, key, (char*)NULL, 0.0f);
733 }
734 GfParmGetNumBoundaries(hdle, path, key, &v->min, &v->max);
735}
736
737
748void RtInitCarPitSetup(void *hdle, tCarPitSetup* s, bool minmaxonly)
749{
752 const int BUFSIZE = 256;
753 char path[BUFSIZE];
754
755 // Steer
757
758 int i;
759 for (i=0; i < 4; i++) {
760 // Wheel
761 RtReadCarPitSetupEntry(&s->wheelcamber[i], WheelSect[i], PRM_CAMBER, hdle, minmaxonly);
762 RtReadCarPitSetupEntry(&s->wheeltoe[i], WheelSect[i], PRM_TOE, hdle, minmaxonly);
763 RtReadCarPitSetupEntry(&s->wheelrideheight[i], WheelSect[i], PRM_RIDEHEIGHT, hdle, minmaxonly);
764 RtReadCarPitSetupEntry(&s->wheelcaster[i], WheelSect[i], PRM_CASTER, hdle, minmaxonly);
765
766 // Suspension
767 RtReadCarPitSetupEntry(&s->suspspring[i], SuspSect[i], PRM_SPR, hdle, minmaxonly);
768 RtReadCarPitSetupEntry(&s->susppackers[i], SuspSect[i], PRM_PACKERS, hdle, minmaxonly);
769 RtReadCarPitSetupEntry(&s->suspslowbump[i], SuspSect[i], PRM_SLOWBUMP, hdle, minmaxonly);
770 RtReadCarPitSetupEntry(&s->suspslowrebound[i], SuspSect[i], PRM_SLOWREBOUND, hdle, minmaxonly);
771 RtReadCarPitSetupEntry(&s->suspfastbump[i], SuspSect[i], PRM_FASTBUMP, hdle, minmaxonly);
772 RtReadCarPitSetupEntry(&s->suspfastrebound[i], SuspSect[i], PRM_FASTREBOUND, hdle, minmaxonly);
775 }
776
777 // Brake
780
781 // Anti roll bar
782 static const char *ArbSect[2] = {SECT_FRNTARB, SECT_REARARB};
783 for (i=0; i < 2; i++) {
784 RtReadCarPitSetupEntry(&s->arbspring[i], ArbSect[i], PRM_SPR, hdle, minmaxonly);
785 }
786
787 // Third element
788 static const char *AxleSect[2] = {SECT_FRNTAXLE, SECT_REARAXLE};
789 for (i=0; i < 2; i++) {
790 RtReadCarPitSetupEntry(&s->thirdspring[i], AxleSect[i], PRM_SPR, hdle, minmaxonly);
791 RtReadCarPitSetupEntry(&s->thirdbump[i], AxleSect[i], PRM_SLOWBUMP, hdle, minmaxonly);
792 RtReadCarPitSetupEntry(&s->thirdrebound[i], AxleSect[i], PRM_SLOWREBOUND, hdle, minmaxonly);
793 RtReadCarPitSetupEntry(&s->thirdX0[i], AxleSect[i], PRM_SUSPCOURSE, hdle, minmaxonly);
794 }
795
796 // Gears
797 for (i=0; i < 8; i++) {
798 snprintf(path, BUFSIZE, "%s/%s/%d", SECT_GEARBOX, ARR_GEARS, i+1);
799 RtReadCarPitSetupEntry(&s->gearsratio[i], path, PRM_RATIO, hdle, minmaxonly);
800 }
801
802 // Wings
803 static const char *WingSect[2] = {SECT_FRNTWING, SECT_REARWING};
804 for (i=0; i < 2; i++) {
805 RtReadCarPitSetupEntry(&s->wingangle[i], WingSect[i], PRM_WINGANGLE, hdle, minmaxonly);
806 }
807
808 // Differentials
809 static const char *DiffSect[3] = {SECT_FRNTDIFFERENTIAL, SECT_REARDIFFERENTIAL, SECT_CENTRALDIFFERENTIAL};
810 for (i=0; i < 3; i++) {
811 RtReadCarPitSetupEntry(&s->diffratio[i], DiffSect[i], PRM_RATIO, hdle, minmaxonly);
812 RtReadCarPitSetupEntry(&s->diffmintqbias[i], DiffSect[i], PRM_MIN_TQ_BIAS, hdle, minmaxonly);
813 RtReadCarPitSetupEntry(&s->diffmaxtqbias[i], DiffSect[i], PRM_MAX_TQ_BIAS, hdle, minmaxonly);
814 RtReadCarPitSetupEntry(&s->diffslipbias[i], DiffSect[i], PRM_MAX_SLIP_BIAS, hdle, minmaxonly);
815 RtReadCarPitSetupEntry(&s->difflockinginputtq[i], DiffSect[i], PRM_LOCKING_TQ, hdle, minmaxonly);
816 RtReadCarPitSetupEntry(&s->difflockinginputbraketq[i], DiffSect[i], PRM_LOCKINGBRAKE_TQ, hdle, minmaxonly);
817
818 const char* type = GfParmGetStr(hdle, DiffSect[i], PRM_TYPE, VAL_DIFF_NONE);
819 if (strcmp(type, VAL_DIFF_LIMITED_SLIP) == 0) {
821 } else if (strcmp(type, VAL_DIFF_VISCOUS_COUPLER) == 0) {
823 } else if (strcmp(type, VAL_DIFF_SPOOL) == 0) {
825 } else if (strcmp(type, VAL_DIFF_FREE) == 0) {
827 } else {
829 }
830 }
831}
832
833
835static const char* CarPitSetupFilenames[6] = { "practice", "qualifying", "race", "backup1", "backup2", "backup3" };
836
837
850 int robidx,
851 const char* carname,
852 const char* trackname,
853 char* filename,
854 const int len
855)
856{
857 snprintf(filename, len, "%s_%s_%d_%s" , carname, trackname, robidx, CarPitSetupFilenames[type]);
858}
859
860
868static void RtParmSetNum(void* hdlesetup, const char* path, const char* key, const char* unit, tCarPitSetupValue* v)
869{
870 // If min == max there is nothing to adjust, so we do not need to write the value.
871 if (fabs(v->min - v->max) >= 0.0001f) {
872 GfParmSetNumEx(hdlesetup, path, key, unit, GfParmSI2Unit(unit, v->value), GfParmSI2Unit(unit, v->min), GfParmSI2Unit(unit, v->max));
873 }
874}
875
876
889 void *hdlecar, // handle to car definition file, for min/max merge
890 tCarPitSetup* s, // the setup data to save
891 const char* filepath, // full path including filename and extension
892 const char* carname
893)
894{
895 const int BUFSIZE = 256;
896 char path[BUFSIZE];
897 void* hdlesetup = GfParmReadFile(filepath, GFPARM_RMODE_STD | GFPARM_RMODE_CREAT);
898
899 // Steer
900 RtParmSetNum(hdlesetup, SECT_STEER, PRM_STEERLOCK, "deg", &s->steerLock);
901
904
905 int i;
906 for (i=0; i < 4; i++) {
907 // Wheel
908 RtParmSetNum(hdlesetup, WheelSect[i], PRM_CAMBER, "deg", &s->wheelcamber[i]);
909 RtParmSetNum(hdlesetup, WheelSect[i], PRM_TOE, "deg", &s->wheeltoe[i]);
910 RtParmSetNum(hdlesetup, WheelSect[i], PRM_RIDEHEIGHT, "mm", &s->wheelrideheight[i]);
911 RtParmSetNum(hdlesetup, WheelSect[i], PRM_CASTER, "deg", &s->wheelcaster[i]);
912
913 // Suspension
914 RtParmSetNum(hdlesetup, SuspSect[i], PRM_SPR, "lbs/in", &s->suspspring[i]);
915 RtParmSetNum(hdlesetup, SuspSect[i], PRM_PACKERS, "mm", &s->susppackers[i]);
916 RtParmSetNum(hdlesetup, SuspSect[i], PRM_SLOWBUMP, "lbs/in/s", &s->suspslowbump[i]);
917 RtParmSetNum(hdlesetup, SuspSect[i], PRM_SLOWREBOUND, "lbs/in/s", &s->suspslowrebound[i]);
918 RtParmSetNum(hdlesetup, SuspSect[i], PRM_FASTBUMP, "lbs/in/s", &s->suspfastbump[i]);
919 RtParmSetNum(hdlesetup, SuspSect[i], PRM_FASTREBOUND, "lbs/in/s", &s->suspfastrebound[i]);
920 RtParmSetNum(hdlesetup, SuspSect[i], PRM_BUMPTHRESHOLD, "cm/s", &s->suspbumpthreshold[i]);
921 RtParmSetNum(hdlesetup, SuspSect[i], PRM_REBOUNDTHRESHOLD, "cm/s", &s->suspreboundthreshold[i]);
922 }
923
924 // Brake
926 RtParmSetNum(hdlesetup, SECT_BRKSYST, PRM_BRKPRESS, "kPa", &s->brakePressure);
927
928 // Anti roll bar
929 static const char *ArbSect[2] = {SECT_FRNTARB, SECT_REARARB};
930 for (i=0; i < 2; i++) {
931 RtParmSetNum(hdlesetup, ArbSect[i], PRM_SPR, "lbs/in", &s->arbspring[i]);
932 }
933
934 // Third element
935 static const char *AxleSect[2] = {SECT_FRNTAXLE, SECT_REARAXLE};
936 for (i=0; i < 2; i++) {
937 RtParmSetNum(hdlesetup, AxleSect[i], PRM_SPR, "lbs/in", &s->thirdspring[i]);
938 RtParmSetNum(hdlesetup, AxleSect[i], PRM_SLOWBUMP, "lbs/in/s", &s->thirdbump[i]);
939 RtParmSetNum(hdlesetup, AxleSect[i], PRM_SLOWREBOUND, "lbs/in/s", &s->thirdrebound[i]);
940 RtParmSetNum(hdlesetup, AxleSect[i], PRM_SUSPCOURSE, "mm", &s->thirdX0[i]);
941 }
942
943 // Gears
944 for (i=0; i < 8; i++) {
945 snprintf(path, BUFSIZE, "%s/%s/%d", SECT_GEARBOX, ARR_GEARS, i+1);
946 RtParmSetNum(hdlesetup, path, PRM_RATIO, NULL, &s->gearsratio[i]);
947 }
948
949 // Wings
950 static const char *WingSect[2] = {SECT_FRNTWING, SECT_REARWING};
951 for (i=0; i < 2; i++) {
952 RtParmSetNum(hdlesetup, WingSect[i], PRM_WINGANGLE, "deg", &s->wingangle[i]);
953 }
954
955 // Differentials
956 static const char *DiffSect[3] = {SECT_FRNTDIFFERENTIAL, SECT_REARDIFFERENTIAL, SECT_CENTRALDIFFERENTIAL};
958 for (i=0; i < 3; i++) {
959 RtParmSetNum(hdlesetup, DiffSect[i], PRM_RATIO, NULL, &s->diffratio[i]);
960 RtParmSetNum(hdlesetup, DiffSect[i], PRM_MIN_TQ_BIAS, NULL, &s->diffmintqbias[i]);
961 RtParmSetNum(hdlesetup, DiffSect[i], PRM_MAX_TQ_BIAS, NULL, &s->diffmaxtqbias[i]);
962 RtParmSetNum(hdlesetup, DiffSect[i], PRM_MAX_SLIP_BIAS, NULL, &s->diffslipbias[i]);
963 RtParmSetNum(hdlesetup, DiffSect[i], PRM_LOCKING_TQ, "N.m", &s->difflockinginputtq[i]);
964 RtParmSetNum(hdlesetup, DiffSect[i], PRM_LOCKINGBRAKE_TQ, "N.m", &s->difflockinginputbraketq[i]);
965
966 if (s->diffType[i] != tCarPitSetup::NONE) {
967 GfParmSetStr(hdlesetup, DiffSect[i], PRM_TYPE, DiffType[s->diffType[i]]);
968 }
969 }
970
971 hdlesetup = GfParmMergeHandles(hdlecar, hdlesetup, GFPARM_MMODE_DST | GFPARM_MMODE_RELDST);
972 GfParmWriteFile(filepath, hdlesetup, carname);
973 GfParmReleaseHandle(hdlesetup);
974}
975
976
992 void *hdlecar,
993 tCarPitSetup* s,
995 const char* modulename,
996 int robidx,
997 const char* trackname,
998 const char* carname
999)
1000{
1001 const int filelen = 256;
1002 char filename[filelen];
1003 RtGetCarPitSetupFilename(type, robidx, carname, trackname, filename, filelen);
1004
1005 const int pathlen = 1024;
1006 char path[pathlen];
1007
1008 snprintf(path, pathlen, "%sdrivers/%s/setups", GetLocalDir(), modulename);
1009 if (GfCreateDir(path) == GF_DIR_CREATED) {
1010 snprintf(path, pathlen, "%sdrivers/%s/setups/%s.xml", GetLocalDir(), modulename, filename);
1011 RtSaveCarPitSetupFile(hdlecar, s, path, carname);
1012 } else {
1013 GfError("RtSaveCarPitSetup, could not create %s\n", path);
1014 }
1015}
1016
1017
1029 rtCarPitSetupType type,
1030 const char* modulename,
1031 int robidx,
1032 const char* trackname,
1033 const char* carname
1034)
1035{
1036 const int filelen = 256;
1037 char filename[filelen];
1038 RtGetCarPitSetupFilename(type, robidx, carname, trackname, filename, filelen);
1039
1040 const int pathlen = 1024;
1041 char path[pathlen];
1042
1043 snprintf(path, pathlen, "%sdrivers/%s/setups/%s.xml", GetLocalDir(), modulename, filename);
1044 FILE* file = fopen(path, "r"); // TODO: maybe "stat" would be enough here
1045 if (file) {
1046 fclose(file);
1047 return true;
1048 }
1049
1050 return false;
1051}
1052
1053
1067bool RtLoadCarPitSetupFilename(void* hdlecar, const char* filepath, tCarPitSetup* s, bool minmaxonly)
1068{
1069 void* hdlesetup = GfParmReadFile(filepath, GFPARM_RMODE_STD);
1070 if (hdlesetup) {
1071 hdlesetup = GfParmMergeHandles(hdlecar, hdlesetup, GFPARM_MMODE_DST | GFPARM_MMODE_RELDST);
1072 RtInitCarPitSetup(hdlesetup, s, minmaxonly);
1073 GfParmReleaseHandle(hdlesetup);
1074 return true;
1075 } else {
1076 return false;
1077 }
1078}
1079
1080
1098 void* hdlecar,
1099 tCarPitSetup* s,
1100 rtCarPitSetupType type,
1101 const char* modulename,
1102 int robidx,
1103 const char* trackname,
1104 const char* carname,
1105 bool minmaxonly
1106)
1107{
1108 const int filelen = 256;
1109 char filename[filelen];
1110 RtGetCarPitSetupFilename(type, robidx, carname, trackname, filename, filelen);
1111
1112 const int pathlen = 1024;
1113 char path[pathlen];
1114
1115 snprintf(path, pathlen, "%sdrivers/%s/setups/%s.xml", GetLocalDir(), modulename, filename);
1116 return RtLoadCarPitSetupFilename(hdlecar, path, s, minmaxonly);
1117}
1118
1119
1127void* RtLoadOriginalCarSettings(const char* carname)
1128{
1129 const int BUFSIZE = 1024;
1130 char buf[BUFSIZE];
1131
1132 // Fetch car handle
1133 snprintf(buf, BUFSIZE, "%scars/%s/%s.xml", GetDataDir(), carname, carname);
1134 void* carhdle = GfParmReadFile(buf, GFPARM_RMODE_STD);
1135 if (carhdle == 0) {
1136 GfError("carhdle NULL in %s, line %d\n", __FILE__, __LINE__);
1137 return NULL;
1138 }
1139
1140 // Get category
1141 const char* category = GfParmGetStr(carhdle, SECT_CAR, PRM_CATEGORY, NULL);
1142 if (category == 0) {
1143 GfError("category string NULL in %s, line %d\n", __FILE__, __LINE__);
1144 GfParmReleaseHandle(carhdle);
1145 return NULL;
1146 }
1147
1148 // Fetch category handle
1149 snprintf(buf, BUFSIZE, "%scategories/%s.xml", GetDataDir(), category);
1150 void* cathdle = GfParmReadFile(buf, GFPARM_RMODE_STD);
1151 if (cathdle == 0) {
1152 GfError("cathdle NULL in %s, line %d\n", __FILE__, __LINE__);
1153 GfParmReleaseHandle(carhdle);
1154 return NULL;
1155 }
1156
1157 // Compose final result, MergeHandles releases source handles with given parameters
1160
1161 return carhdle;
1162}
1163
1164
1172bool RtInitCarPitSetupFromDefault(tCarPitSetup* s, const char* carname)
1173{
1174 void* carhandle = RtLoadOriginalCarSettings(carname);
1175 if (carhandle == 0) {
1176 GfError("carhandle NULL in %s, line %d\n", __FILE__, __LINE__);
1177 return false;
1178 }
1179
1180 RtInitCarPitSetup(carhandle, s, false);
1181 GfParmReleaseHandle(carhandle);
1182 return true;
1183}
1184
1185
1199 rtCarPitSetupType type,
1200 const char* modulename,
1201 int robidx,
1202 const char* trackname,
1203 const char* carname
1204)
1205{
1206 const int filelen = 256;
1207 char filename[filelen];
1208 RtGetCarPitSetupFilename(type, robidx, carname, trackname, filename, filelen);
1209
1210 const int pathlen = 1024;
1211 char path[pathlen];
1212
1213 snprintf(path, pathlen, "%sdrivers/%s/setups/%s.xml", GetLocalDir(), modulename, filename);
1214 return GfParmReadFile(path, GFPARM_RMODE_STD);
1215}
@ Y
Definition Basic.h:58
@ X
Definition Basic.h:58
static Point p[4]
Definition Convex.cpp:54
static Vector y[4]
Definition Convex.cpp:56
static const double PI
const T sign(const T &x)
static const char * WingSect[2]
Definition aero.cpp:108
static const char * AxleSect[2]
Definition axle.cpp:21
#define SECT_REARWING
Definition car.h:490
#define SECT_CENTRALDIFFERENTIAL
Definition car.h:500
#define PRM_STEERLOCK
Definition car.h:572
#define PRM_SLOWBUMP
Definition car.h:561
#define PRM_LOCKINGBRAKE_TQ
Definition car.h:625
#define PRM_PACKERS
Definition car.h:560
#define SECT_FRNTRGTSUSP
Definition car.h:484
#define SECT_REARLFTWHEEL
Definition car.h:494
#define VAL_DIFF_SPOOL
Definition car.h:630
#define SECT_STEER
Definition car.h:501
#define VAL_DIFF_FREE
Definition car.h:631
#define PRM_BRKREP
Definition car.h:577
#define SECT_REARRGTSUSP
Definition car.h:495
#define PRM_REBOUNDTHRESHOLD
Definition car.h:566
#define PRM_FASTBUMP
Definition car.h:563
#define PRM_SLOWREBOUND
Definition car.h:562
#define SECT_FRNTWING
Definition car.h:479
#define SECT_REARAXLE
Definition car.h:491
#define PRM_SPR
Definition car.h:557
#define VAL_DIFF_NONE
Definition car.h:629
#define PRM_LOCKING_TQ
Definition car.h:624
#define SECT_FRNTLFTSUSP
Definition car.h:485
#define PRM_MIN_TQ_BIAS
Definition car.h:621
#define SECT_CAR
Definition car.h:477
#define PRM_BUMPTHRESHOLD
Definition car.h:565
#define SECT_FRNTAXLE
Definition car.h:480
struct CarElt tCarElt
Car structure (tCarElt).
#define SECT_REARRGTWHEEL
Definition car.h:493
#define PRM_TYPE
Definition car.h:531
#define PRM_RIDEHEIGHT
Definition car.h:539
#define SECT_BRKSYST
Definition car.h:502
#define PRM_CASTER
Definition car.h:542
#define SECT_FRNTDIFFERENTIAL
Definition car.h:488
#define SECT_REARLFTSUSP
Definition car.h:496
#define VAL_DIFF_VISCOUS_COUPLER
Definition car.h:633
#define SECT_FRNTARB
Definition car.h:481
#define SECT_GEARBOX
Definition car.h:507
#define PRM_TOE
Definition car.h:540
#define SECT_FRNTRGTWHEEL
Definition car.h:482
#define PRM_MAX_TQ_BIAS
Definition car.h:622
#define PRM_FASTREBOUND
Definition car.h:564
#define PRM_MAX_SLIP_BIAS
Definition car.h:623
#define PRM_CAMBER
Definition car.h:541
#define ARR_GEARS
Definition car.h:607
#define PRM_WINGANGLE
Definition car.h:587
#define PRM_BRKPRESS
Definition car.h:578
#define SECT_REARARB
Definition car.h:492
#define VAL_DIFF_LIMITED_SLIP
Definition car.h:632
#define PRM_SUSPCOURSE
Definition car.h:558
#define PRM_CATEGORY
Definition car.h:515
#define SECT_FRNTLFTWHEEL
Definition car.h:483
#define PRM_RATIO
Definition car.h:604
#define SECT_REARDIFFERENTIAL
Definition car.h:499
float tdble
Floating point type used in TORCS.
Definition tgf.h:47
int GfParmSetNumEx(void *handle, const char *path, const char *key, const char *unit, tdble val, tdble min, tdble max)
Set a numerical parameter and its bounds, creating it if necessary.
Definition params.cpp:2783
const char * GfParmGetStr(void *parmHandle, const char *path, const char *key, const char *deflt)
Get a string parameter from the parameter set handle.
Definition params.cpp:2453
int GfParmSetStr(void *handle, const char *path, const char *key, const char *val)
Set a string parameter in the parameter set handle.
Definition params.cpp:2623
tdble GfParmGetNum(void *handle, const char *path, const char *key, const char *unit, tdble deflt)
Get a numerical parameter from the parameter set handle.
Definition params.cpp:2534
tdble GfParmSI2Unit(const char *unit, tdble val)
Convert a value from SI to given unit.
Definition params.cpp:2133
int GfParmGetNumBoundaries(void *handle, const char *path, const char *key, tdble *min, tdble *max)
Get the min and max of a numerical parameter from the parameter set handle.
Definition params.cpp:3268
void GfParmReleaseHandle(void *parmHandle)
Release given parameter set handle parmHandle.
Definition params.cpp:1963
int GfParmWriteFile(const char *file, void *parmHandle, const char *name)
Write parameter set into file.
Definition params.cpp:1732
void * GfParmMergeHandles(void *ref, void *tgt, int mode)
Merge two parameter sets into a new private set.
Definition params.cpp:3129
void * GfParmReadFile(const char *file, int mode)
Read parameter set from file and return handle to parameter set.
Definition params.cpp:1173
void RtGetCarPitSetupFilename(rtCarPitSetupType type, int robidx, const char *carname, const char *trackname, char *filename, const int len)
Compose filename from given strings.
Definition rttrack.cpp:848
bool RtCarPitSetupExists(rtCarPitSetupType type, const char *modulename, int robidx, const char *trackname, const char *carname)
Checks if a specific car setup is available.
Definition rttrack.cpp:1028
bool RtInitCarPitSetupFromDefault(tCarPitSetup *s, const char *carname)
Initialize the given tCarPitSetup with the original TORCS setup, that means the car setup merged with...
Definition rttrack.cpp:1172
void * RtLoadOriginalCarSettings(const char *carname)
Gets a handle to a parameter file containing the original TORCS car setup, that means the car setup m...
Definition rttrack.cpp:1127
void RtSaveCarPitSetup(void *hdlecar, tCarPitSetup *s, rtCarPitSetupType type, const char *modulename, int robidx, const char *trackname, const char *carname)
Save a custom setup in the robot's local setups directory.
Definition rttrack.cpp:991
bool RtLoadCarPitSetup(void *hdlecar, tCarPitSetup *s, rtCarPitSetupType type, const char *modulename, int robidx, const char *trackname, const char *carname, bool minmaxonly)
Load a custom setup from the robot's local setups directory.
Definition rttrack.cpp:1097
void * RtParmReadSetup(rtCarPitSetupType type, const char *modulename, int robidx, const char *trackname, const char *carname)
Load a custom car setup file for a given robot, car, track and session (race, practice,...
Definition rttrack.cpp:1198
bool RtLoadCarPitSetupFilename(void *hdlecar, const char *filepath, tCarPitSetup *s, bool minmaxonly)
Load a custom setup and merge its entries with hdlecar's restrictions.
Definition rttrack.cpp:1067
void RtSaveCarPitSetupFile(void *hdlecar, tCarPitSetup *s, const char *filepath, const char *carname)
Save adjustable setup entries to a file, merging them with hdlecar's restrictions.
Definition rttrack.cpp:888
void RtInitCarPitSetup(void *hdle, tCarPitSetup *s, bool minmaxonly)
Initialize tCarPitSetup from data in parameter set given in handle hdle.
Definition rttrack.cpp:748
struct trackSeg tTrackSeg
Track segment (tTrackSeg) The segments can be straights (type TR_STR): (the track goes from the right...
tTrackSeg * RtTrackGetSeg(tTrkLocPos *p)
Get the effective segment of the given position starting from a segment of type TR_MAIN,...
Definition rttrack.cpp:450
void RtTrackGlobal2LocalD(tTrackSeg *segment, double X, double Y, tTrkLocPos *p, int type)
Convert global coordinates to a local track position using double intermediates.
Definition rttrack.cpp:276
void RtTrackGlobal2Local(tTrackSeg *segment, tdble X, tdble Y, tTrkLocPos *p, int type)
Convert global coordinates to a local track position.
Definition rttrack.cpp:298
tdble RtTrackHeightL(tTrkLocPos *p)
Returns the absolute height in meters of the road at the Local position p.
Definition rttrack.cpp:365
tdble RtGetDistFromStart(tCarElt *car)
Get distance along the track from the start/finish line.
Definition rttrack.cpp:646
tdble RtTrackSideTgAngleL(tTrkLocPos *p)
Used to get the tangent angle for a track position The angle is given in radian.
Definition rttrack.cpp:539
int RtDistToPit(struct CarElt *car, tTrack *track, tdble *dL, tdble *dW)
Get the distance to the pit stop.
Definition rttrack.cpp:692
tdble RtTrackGetWidth(tTrackSeg *seg, tdble toStart)
Get the track width at the specified point.
Definition rttrack.cpp:59
tdble RtGetDistFromStart2(tTrkLocPos *p)
Get distance along the track from the start/finish line.
Definition rttrack.cpp:659
tdble RtTrackHeightG(tTrackSeg *seg, tdble X, tdble Y)
Returns the absolute height in meters of the road at the Global position (segment,...
Definition rttrack.cpp:465
void RtTrackSurfaceNormalL(tTrkLocPos *p, t3Dd *norm)
Used to get the normal vector of the road (pointing upward).
Definition rttrack.cpp:567
tTrackSeg * RtTrackGetSideNeighbourSeg(tTrackSeg *main, tTrackSeg *current, int tr_side)
Get the neighbour segment of the given current segment.
Definition rttrack.cpp:419
void RtTrackLocal2Global(tTrkLocPos *p, tdble *X, tdble *Y, int flag)
Calculate global coordinates from a local position relative to the given track segment (segment,...
Definition rttrack.cpp:81
void RtTrackSideNormalG(tTrackSeg *seg, tdble X, tdble Y, int side, t3Dd *norm)
Compute the horizontal inward border normal using the supplied segment.
Definition rttrack.cpp:495
int main(int argc, char *argv[])
Definition main.cpp:124
static tRmTrackSelect ts
Robots Tools
rtCarPitSetupType
Definition robottools.h:191
static const char * CarPitSetupFilenames[6]
Array with names for rtCarPitSetupType enumeration.
Definition rttrack.cpp:835
static tTrackSeg * resolveTrackSeg(const tTrkLocPos *p, tdble *toRight)
Resolve the effective segment and rebase the lateral coordinate to it.
Definition rttrack.cpp:312
static void RtParmSetNum(void *hdlesetup, const char *path, const char *key, const char *unit, tCarPitSetupValue *v)
Robottool internal: Set parameter if min != max, save as well min and max values.
Definition rttrack.cpp:868
static void RtReadCarPitSetupEntry(tCarPitSetupValue *v, const char *path, const char *key, void *hdle, bool minmaxonly)
Definition rttrack.cpp:729
static void rtTrackGlobal2Local(tTrackSeg *segment, T X, T Y, tTrkLocPos *p, int type)
Definition rttrack.cpp:142
Car structure (tCarElt).
Definition car.h:458
3D point.
Definition tgf.h:114
tdble y
y coordinate
Definition tgf.h:116
tdble z
z coordinate
Definition tgf.h:117
tdble x
x coordinate
Definition tgf.h:115
tCarPitSetupValue thirdbump[2]
Definition car.h:414
tCarPitSetupValue wheelcaster[4]
Definition car.h:393
tCarPitSetupValue diffmintqbias[3]
Definition car.h:426
tCarPitSetupValue brakePressure
Definition car.h:396
tCarPitSetupValue wheelcamber[4]
Definition car.h:390
tCarPitSetupValue suspfastbump[4]
Definition car.h:404
tCarPitSetupValue suspspring[4]
Definition car.h:400
tCarPitSetupValue brakeRepartition
Definition car.h:397
tCarPitSetupValue suspbumpthreshold[4]
Definition car.h:406
tCarPitSetupValue gearsratio[MAX_GEARS - 2]
Definition car.h:419
tCarPitSetupValue wheeltoe[4]
Definition car.h:391
tCarPitSetupValue suspslowbump[4]
Definition car.h:402
tCarPitSetupValue diffratio[3]
Definition car.h:425
tCarPitSetupValue thirdX0[2]
Definition car.h:416
TDiffType diffType[3]
Definition car.h:432
tCarPitSetupValue diffslipbias[3]
Definition car.h:428
tCarPitSetupValue difflockinginputbraketq[3]
Definition car.h:430
tCarPitSetupValue wingangle[2]
Definition car.h:422
tCarPitSetupValue suspfastrebound[4]
Definition car.h:405
tCarPitSetupValue suspslowrebound[4]
Definition car.h:403
tCarPitSetupValue arbspring[2]
Definition car.h:410
tCarPitSetupValue wheelrideheight[4]
Definition car.h:392
tCarPitSetupValue suspreboundthreshold[4]
Definition car.h:407
tCarPitSetupValue susppackers[4]
Definition car.h:401
tCarPitSetupValue thirdrebound[2]
Definition car.h:415
@ LIMITED_SLIP
Definition car.h:431
@ VISCOUS_COUPLER
Definition car.h:431
tCarPitSetupValue diffmaxtqbias[3]
Definition car.h:427
tCarPitSetupValue steerLock
Definition car.h:387
tCarPitSetupValue difflockinginputtq[3]
Definition car.h:429
tCarPitSetupValue thirdspring[2]
Definition car.h:413
tdble value
Definition car.h:377
Track structure.
Definition track.h:533
Location on the track in local coordinates.
Definition track.h:434
tdble toRight
Distance (+ to left, - to right) relative to the right side of segment.
Definition track.h:447
tTrackSeg * seg
Track segment.
Definition track.h:435
tdble toStart
Distance to start of segment (or arc if turn)
Definition track.h:446
int type
Geometrical type:
Definition track.h:297
tTrackSurface * surface
Segment surface.
Definition track.h:409
tdble height
Max height for curbs.
Definition track.h:380
t3Dd vertex[4]
Coordinates of the 4 corners of the segment.
Definition track.h:342
tdble radiusr
Radius in meters of the right side of the track (>0)
Definition track.h:338
tdble radius
Radius in meters of the middle of the track (>0)
Definition track.h:337
tdble arc
Arc in rad of the curve (>0)
Definition track.h:340
tdble angle[7]
Definition track.h:354
tdble lgfromstart
Length of beginning of segment from starting line.
Definition track.h:336
t3Dd center
Center of the curve.
Definition track.h:341
tdble Kyl
Definition track.h:376
tdble length
Length in meters of the middle of the track.
Definition track.h:332
tdble radiusl
Radius in meters of the left side of the track (>0)
Definition track.h:339
tdble Kzw
Definition track.h:374
struct trackSeg * rside
Definition track.h:421
struct trackSeg * next
Next segment.
Definition track.h:412
tdble startWidth
Width of the beginning of the segment.
Definition track.h:334
struct trackSeg * prev
Previous segment.
Definition track.h:413
int style
Border and barrier segments style:
Definition track.h:319
struct trackSeg * side[2]
Definition track.h:422
t3Dd rgtSideNormal
Definition track.h:377
tdble width
Width of the segment (if constant width)
Definition track.h:333
tdble Kzl
Definition track.h:373
int type2
Position type:
Definition track.h:306
struct trackSeg * lside
Definition track.h:421
tdble endWidth
Width of the end of the segment.
Definition track.h:335
tdble kRoughWaveLen
Wave length in m of the surface.
Definition track.h:268
tdble kRoughness
Roughtness in m of the surface (wave height)
Definition track.h:267
int GfCreateDir(char *path)
Create directory for given path recursively, so all missing parent directories are created as well.
Definition tgf.cpp:308
char * GetDataDir(void)
Definition tgf.cpp:256
char * GetLocalDir(void)
Definition tgf.cpp:230
#define GFPARM_RMODE_CREAT
Allow an empty in-memory set on file-open failure; does not write a file.
Definition tgf.h:266
#define GFPARM_RMODE_STD
Return a new handle sharing cached data for this filename, if available.
Definition tgf.h:264
#define GFPARM_MMODE_RELSRC
release ref after the merge
Definition tgf.h:314
#define GFPARM_MMODE_RELDST
release tgt after the merge
Definition tgf.h:315
#define GFPARM_MMODE_SRC
Include ref attributes; merge common attributes using ref restrictions and tgt values.
Definition tgf.h:312
#define GFPARM_MMODE_DST
Include tgt attributes; merge common attributes using ref restrictions and tgt values.
Definition tgf.h:313
#define GF_DIR_CREATED
Definition tgf.h:622
#define GfError
Definition tgf.h:350
#define TR_SIDE_RGT
Definition track.h:419
#define TR_XS
X Start angle.
Definition track.h:368
#define TR_RSIDE
Right side segment (outer segment)
Definition track.h:315
#define TR_CS
Center start angle.
Definition track.h:370
#define TR_MAIN
Main track segment (ie road part)
Definition track.h:313
#define TR_LFT
Left curve.
Definition track.h:303
#define TR_LPOS_SEGMENT
Relative to the segment which the point is located, including border and sides, mostly used for conta...
Definition track.h:443
#define TR_TOMIDDLE
Definition track.h:429
#define TR_RBORDER
Right border segment (inner segment)
Definition track.h:317
#define TR_LBORDER
Left border segment (inner segment)
Definition track.h:316
#define TR_TORIGHT
Definition track.h:428
#define TR_TOLEFT
Definition track.h:430
#define TR_SIDE_LFT
Definition track.h:418
#define TR_STR
Straight.
Definition track.h:304
#define TR_LPOS_TRACK
Local position relative to the outermost barriers, mostly used for collision detection with barrier.
Definition track.h:444
#define TR_LSIDE
Left side segment (outer segment)
Definition track.h:314
#define TR_CURB
Curb (border only)
Definition track.h:327
#define TR_RGT
Right curve.
Definition track.h:302
#define TR_ZS
Rotation angles of the track in rad anti-clockwise: Index in:
Definition track.h:364
#define TR_SR
Start-Right corner.
Definition track.h:350
int track(tModInfo *modInfo)
Definition trackitf.cpp:85
static const char * SuspSect[4]
Definition wheel.cpp:23
static const char * WheelSect[4]
Definition wheel.cpp:22