25#include <robottools.h>
27#include <portability.h>
33 if (xmin > (x)) xmin = (x); \
34 if (xmax < (x)) xmax = (x);
37 if (ymin > (y)) ymin = (y); \
38 if (ymax < (y)) ymax = (y);
41 if (zmin > (z)) zmin = (z); \
42 if (zmax < (z)) zmax = (z);
92 const int BUFSIZE = 256;
99 if (strcmp(curSurf->
material, material) == 0) {
102 curSurf = curSurf->
next;
108 GfFatal(
"AddTrackSurface: Memory allocation failed\n");
132 for (side = 0; side < 2; side++) {
185 tdble x1, x2, y1, y2;
192 const int BUFSIZE = 256;
199 for (side = 0; side < 2; side++) {
242 Kew = (ew - sw) / (
tdble)steps;
243 ew = sw + (
tdble)(curStep+1) * Kew;
244 sw = sw + (
tdble)(curStep) * Kew;
250 curSeg->
lside = curBorder;
255 curSeg->
rside = curBorder;
264 curBorder->
width = bw;
276 switch(curSeg->
type) {
322 curBorder->
arc = curSeg->
arc;
345 for (j = 0; j < 36; j++) {
359 curBorder->
arc = curSeg->
arc;
382 for (j = 0; j < 36; j++) {
403 curBorder->
arc = curSeg->
arc;
426 for (j = 0; j < 36; j++) {
440 curBorder->
arc = curSeg->
arc;
463 for (j = 0; j < 36; j++) {
481 if ((sw != 0.0) || (ew != 0)) {
484 curSeg->
lside = curSide;
489 curSeg->
rside = curSide;
498 curSide->
width = minWidth =
MIN(sw, ew);
499 maxWidth =
MAX(sw, ew);
509 switch(curSeg->
type) {
536 curSide->
Kyl = (ew - sw) / curSide->
length;
555 curSide->
arc = curSeg->
arc;
572 curSide->
Kyl = (ew - sw) / curSide->
arc;
578 for (j = 0; j < 36; j++) {
592 curSide->
arc = curSeg->
arc;
609 curSide->
Kyl = (ew - sw) / curSide->
arc;
615 for (j = 0; j < 36; j++) {
636 curSide->
arc = curSeg->
arc;
653 curSide->
Kyl = (ew - sw) / curSide->
arc;
659 for (j = 0; j < 36; j++) {
673 curSide->
arc = curSeg->
arc;
690 curSide->
Kyl = (ew - sw) / curSide->
arc;
696 for (j = 0; j < 36; j++) {
716 GfFatal(
"AddSides: memory allocation error");
738 while (bseg->
side[side] != NULL) {
739 bseg = bseg->
side[side];
750 mSeg->
barrier[side] = curBarrier;
778 int segread, curindex;
779 tdble radius, radiusend = 0, dradius;
786 tdble xr, yr, newxr, newyr;
787 tdble xl, yl, newxl, newyl;
790 tdble x1, x2, y1, y2;
792 tdble zsl, zsr, zel, zer, zs, ze;
793 tdble bankings, bankinge, dz;
805 tdble tl, dtl, T1l, T2l;
806 tdble tr, dtr, T1r, T2r;
807 tdble curzel, curzer, curArc, curLength, curzsl, curzsr;
810 const int BUFSIZE = 256;
812#define MAX_TMP_INTS 256
816 radius = arc =
length = alf = xr = yr = newxr = newyr = xl = yl = 0;
817 zel = zer = etgtl = etgtr = newxl = newyl = 0;
833 zsl = zsr = zel = zer = zs = ze = 0.0;
847 zsl = zsr = zel = zer = zs = ze = start->
vertex[
TR_SR].
z;
849 xl = xr - width * sin(alf);
850 yl = yr + width * cos(alf);
885 char* tmpmarks = strdup(marks);
886 char *s = strtok(tmpmarks,
";");
888 mi[ind] = (int)strtol(s, NULL, 0);
890 s = strtok(NULL,
";");
906 radius = radiusend = 0;
913 length = (radius + radiusend) / 2.0 * arc;
920 length = (radius + radiusend) / 2.0 * arc;
934 if (zs != -100000.0) {
937 zs = (zsl + zsr) / 2.0;
939 if (ze != -100000.0) {
941 }
else if (grade != -100000.0) {
944 ze = (zel + zer) / 2.0;
946 bankings = atan2(zsl - zsr, width);
947 bankinge = atan2(zel - zer, width);
950 dz = tan(bankings) * width / 2.0;
953 dz = tan(bankinge) * width / 2.0;
969 steps = (int)(
length / stepslg) + 1;
978 stgt = etgt = -100000.0;
981 if (stgt != -100000.0) {
982 stgtl = stgtr = stgt;
984 if (etgt != -100000.0) {
985 etgtl = etgtr = etgt;
989 stgtl = etgtl = (zel - zsl) /
length;
990 stgtr = etgtr = (zer - zsr) /
length;
999 dtl = 1.0 / (
tdble)steps;
1003 dtr = 1.0 / (
tdble)steps;
1008 curArc = arc / (
tdble)steps;
1010 dradius = (radiusend - radius) / (
tdble)steps;
1011 if (radiusend != radius) {
1014 dradius = (radiusend - radius) / (
tdble)(steps - 1);
1016 tdble tmpRadius = radius;
1017 for (curStep = 0; curStep < steps; curStep++) {
1018 tmpAngle += curLength / tmpRadius;
1019 tmpRadius += dradius;
1021 curLength *= arc / tmpAngle;
1026 while (curStep < steps) {
1038 curArc = curLength / radius;
1045 curSeg->
next = curSeg;
1046 curSeg->
prev = curSeg;
1050 curSeg->
prev = root;
1051 root->
next = curSeg;
1055 curSeg->
name = segName;
1056 curSeg->
id = curindex;
1063 int *mrks = (
int*)calloc(ind,
sizeof(
int));
1066 memcpy(mrks, mi, ind*
sizeof(
int));
1068 segExt->
marks = mrks;
1069 curSeg->
ext = segExt;
1078 curSeg->
length = curLength;
1080 newxr = xr + curLength * cos(alf);
1081 newyr = yr + curLength * sin(alf);
1082 newxl = xl + curLength * cos(alf);
1083 newyl = yl + curLength * sin(alf);
1124 curSeg->
radiusr = radius + wi2;
1125 curSeg->
radiusl = radius - wi2;
1126 curSeg->
arc = curArc;
1127 curSeg->
length = curLength;
1129 innerradius = radius - wi2;
1130 cenx = xl - innerradius * sin(alf);
1131 ceny = yl + innerradius * cos(alf);
1140 newxl = cenx + innerradius * sin(alf);
1141 newyl = ceny - innerradius * cos(alf);
1142 newxr = cenx + (innerradius + width) * sin(alf);
1143 newyr = ceny - (innerradius + width) * cos(alf);
1166 curSeg->
Kzl = tan(curSeg->
angle[
TR_YR]) * (innerradius + width);
1174 for (j = 0; j < 36; j++) {
1176 x1 = curSeg->
center.
x + (innerradius) * sin(alfl);
1177 y1 = curSeg->
center.
y - (innerradius) * cos(alfl);
1178 x2 = curSeg->
center.
x + (innerradius + width) * sin(alfl);
1179 y2 = curSeg->
center.
y - (innerradius + width) * cos(alfl);
1190 curSeg->
radiusr = radius - wi2;
1191 curSeg->
radiusl = radius + wi2;
1192 curSeg->
arc = curArc;
1193 curSeg->
length = curLength;
1195 innerradius = radius - wi2;
1196 cenx = xr + innerradius * sin(alf);
1197 ceny = yr - innerradius * cos(alf);
1206 newxl = cenx - (innerradius + width) * sin(alf);
1207 newyl = ceny + (innerradius + width) * cos(alf);
1208 newxr = cenx - innerradius * sin(alf);
1209 newyr = ceny + innerradius * cos(alf);
1240 for (j = 0; j < 36; j++) {
1242 x1 = curSeg->
center.
x - (innerradius + width) * sin(alfl);
1243 y1 = curSeg->
center.
y + (innerradius + width) * cos(alfl);
1244 x2 = curSeg->
center.
x - innerradius * sin(alfl);
1245 y2 = curSeg->
center.
y + innerradius * cos(alfl);
1255 totLength += curSeg->
length;
1293 const char *segName;
1298 const char *paramVal;
1299 const char *pitType;
1300 const int BUFSIZE = 256;
1302 char path2[BUFSIZE];
1324 for(i = 0; i <
theTrack->nseg; i++) {
1325 if (pitEntrySeg->
id == segId) {
1328 pitEntrySeg = pitEntrySeg->
next;
1331 pitEntrySeg = pitEntrySeg->
prev;
1342 for(i = 0; i <
theTrack->nseg; i++) {
1344 if (!strcmp(segName, pitExitSeg->
name)) {
1347 pitExitSeg = pitExitSeg->
prev;
1350 pitExitSeg = pitExitSeg->
next;
1361 for(i = 0; i <
theTrack->nseg; i++) {
1362 if (!strcmp(segName, pitStart->
name)) {
1365 pitStart = pitStart->
next;
1368 pitStart = pitStart->
prev;
1379 for(i = 0; i <
theTrack->nseg; i++) {
1380 if (!strcmp(segName, pitEnd->
name)) {
1383 pitEnd = pitEnd->
prev;
1386 pitEnd = pitEnd->
next;
1393 if (strcmp(paramVal,
"right") == 0) {
1399 if ((pitEntrySeg != NULL) && (pitExitSeg != NULL) && (pitStart != NULL) && (pitEnd != NULL)) {
1430 while (i < pits->nMaxPits) {
1436 switch (pits->
side) {
1438 curPitSeg = mSeg->
rside;
1439 if (curPitSeg->
rside) {
1440 offset = curPitSeg->
width;
1441 curPitSeg = curPitSeg->
rside;
1445 curPitSeg = mSeg->
lside;
1446 if (curPitSeg->
lside) {
1447 offset = curPitSeg->
width;
1448 curPitSeg = curPitSeg->
lside;
1452 if (toStart >= mSeg->length) {
1453 toStart -= mSeg->length;
1460 switch (pits->
side) {
1472 toStart += pits->
len;
1473 if (toStart >= mSeg->length) {
1474 toStart -= mSeg->length;
1480 for (mSeg = pitStart->
prev; mSeg != pitEnd->
next->
next; mSeg = mSeg->
next) {
1482 switch(pits->
side) {
1484 curSeg = mSeg->
rside;
1485 curSeg2 = curSeg->
rside;
1486 if ((mSeg != pitStart->
prev) && (mSeg != pitEnd->
next)) {
1491 curSeg = mSeg->
lside;
1492 curSeg2 = curSeg->
lside;
1493 if ((mSeg != pitStart->
prev) && (mSeg != pitEnd->
next)) {
1498 if ((mSeg != pitStart->
prev) && (mSeg != pitEnd->
next)) {
1503 }
else if (mSeg == pitStart->
prev) {
1508 }
else if (mSeg == pitEnd->
next) {
1526 GfFatal(
"ReadTrack3: Memory allocation error");
1528 if (*camList == NULL) {
1530 curCam->
next = curCam;
1533 (*camList)->
next = curCam;
1545 if (curSeg->
id == segId) {
1548 curSeg = curSeg->
next;
1551 trkPos.
seg = curSeg;
1565 if (curSeg->
id == segId) {
1568 curSeg = curSeg->
next;
1578 curSeg->
cam = curCam;
1579 curSeg = curSeg->
next;
1580 }
while (curSeg->
id != segId);
1602 if (curSeg->
lside) {
1608 if (curSeg->
rside) {
1614 curSeg = curSeg->
next;
1618 if (*camList != NULL) {
1621 curCam = curCam->
next;
1625 }
while (curCam != *camList);
Scalar length(const Quaternion &q)
float tdble
Floating point type used in TORCS.
const char * GfParmGetStr(void *parmHandle, const char *path, const char *key, const char *deflt)
Get a string parameter from the parameter set handle.
tdble GfParmGetNum(void *handle, const char *path, const char *key, const char *unit, tdble deflt)
Get a numerical parameter from the parameter set handle.
char * GfParmListGetCurEltName(void *handle, const char *path)
Get current subsection name of the parameter set handle during subsection iteration.
int GfParmListSeekNext(void *handle, const char *path)
Advance to the next immediate subsection.
int GfParmListSeekFirst(void *handle, const char *path)
Select the first immediate subsection of a section.
int GfParmSetCurNum(void *handle, const char *path, const char *key, const char *unit, tdble val)
Set a numerical parameter in the parameter set handle based on subsection iteration.
tdble GfParmGetCurNum(void *handle, const char *path, const char *key, const char *unit, tdble deflt)
Get a numerical parameter from the parameter set handle based on subsection iteration.
const char * GfParmGetCurStr(void *handle, const char *path, const char *key, const char *deflt)
Get a string parameter from the parameter set handle based on subsection iteration.
struct trackSeg tTrackSeg
Track segment (tTrackSeg) The segments can be straights (type TR_STR): (the track goes from the right...
tTrkLocPos pos
Center of the pit position.
tTrackSeg * pitStart
Pit lane segment.
tTrackSeg * pitEntry
Pit lane segment.
int nPitSeg
actual number of pits
tTrackOwnPit * driversPits
List of pits by driver.
tTrackSeg * pitExit
Pit lane segment.
tdble len
Lenght of each pit stop.
tTrackSeg * pitEnd
Pit lane segment.
tdble speedLimit
Speed limit between pitStart and pitEnd.
int nMaxPits
number max of pits
tdble width
Width of each pit stop.
Location on the track in local coordinates.
tdble toMiddle
Distance (+ to left, - to right) relative to the middle of segment.
tdble toLeft
Distance (- to left, + to right) relative to left side of segment.
tdble toRight
Distance (+ to left, - to right) relative to the right side of segment.
tTrackSeg * seg
Track segment.
int type
Type of description:
tdble toStart
Distance to start of segment (or arc if turn)
tdble width
Barrier width.
tdble height
Barrier height.
tTrackSurface * surface
Barrier surface.
int type
Geometrical type:
tTrackSurface * surface
Segment surface.
tdble height
Max height for curbs.
t3Dd vertex[4]
Coordinates of the 4 corners of the segment.
tdble radiusr
Radius in meters of the right side of the track (>0)
unsigned int raceInfo
Type of segment regarding the race: Mask value in:
tdble radius
Radius in meters of the middle of the track (>0)
tdble arc
Arc in rad of the curve (>0)
tdble lgfromstart
Length of beginning of segment from starting line.
t3Dd center
Center of the curve.
const char * name
Segment name.
tdble length
Length in meters of the middle of the track.
tdble radiusl
Radius in meters of the left side of the track (>0)
tTrackBarrier * barrier[2]
Segment barriers.
struct trackSeg * next
Next segment.
tdble startWidth
Width of the beginning of the segment.
struct trackSeg * prev
Previous segment.
int style
Border and barrier segments style:
struct trackSeg * side[2]
tdble width
Width of the segment (if constant width)
tdble endWidth
Width of the end of the segment.
tdble kRebound
Coefficient of energy restitution.
tdble kDammage
Dammages in case of collision.
tdble kFriction
Coefficient of friction.
tdble kRollRes
Rolling resistance.
const char * material
Type of material used.
struct trackSurface * next
Next surface in list.
tdble kRoughWaveLen
Wave length in m of the surface.
tdble kRoughness
Roughtness in m of the surface (wave height)
static void GfFatal(const char *fmt,...)
static const char * KeySideSurface[2]
static void AddSides(tTrackSeg *curSeg, void *TrackHandle, tTrack *theTrack, int curStep, int steps)
static void InitSides(void *TrackHandle, tTrack *theTrack)
static int barrierStyle[2]
static tdble borderHeight[2]
static const char * KeySideWidth[2]
static const char * KeyBarrierSurface[2]
static tTrackSurface * borderSurface[2]
static const char * KeyBarrierStyle[2]
static const char * barrierMaterial[2]
static tdble borderWidth[2]
static tdble barrierWidth[2]
static tTrackSurface * barrierSurface[2]
void ReadTrack3(tTrack *theTrack, void *TrackHandle, tRoadCam **camList, int ext)
static const char * sideMaterial[2]
static const char * KeySideStartWidth[2]
static const char * ValStyle[4]
static const char * KeyBarrierWidth[2]
static tTrackSurface * AddTrackSurface(void *TrackHandle, tTrack *theTrack, const char *material)
static tdble sideStartWidth[2]
static const char * KeyBarrierHeight[2]
static tdble sideEndWidth[2]
static const char * KeyBorderWidth[2]
static const char * KeyBorderStyle[2]
static void CreateSegRing3(void *TrackHandle, tTrack *theTrack, tTrackSeg *start, tTrackSeg *end, int ext)
static const char * KeySideEndWidth[2]
static int sideBankType[2]
static tdble barrierHeight[2]
static tTrackSurface * sideSurface[2]
static const char * KeyBorderSurface[2]
static tdble GlobalStepLen
static const char * borderMaterial[2]
static int borderStyle[2]
static void normSeg(tTrackSeg *curSeg)
static const char * KeyBorderHeight[2]
static const char * KeySideBankType[2]
static void * TrackHandle
#define TRK_ATT_PIT_ENTRY
#define TRK_VAL_PIT_TYPE_NONE
#define TR_XS
X Start angle.
#define TRK_ATT_PROFTGTEL
#define TR_START
Segment after start line.
struct TrackOwnPit tTrackOwnPit
Driver's pit.
#define TR_RSIDE
Right side segment (outer segment)
#define TRK_ATT_PROFTGTER
#define TRK_ATT_PROFSTEPS
#define TR_CS
Center start angle.
#define TR_LAST
Segment before start line.
#define TRK_ATT_PROFTGTSL
#define TR_PITEND
Car pit End.
#define TR_PITSTART
Car pit Star.
#define TR_YR
Y Right angle.
#define TR_MAIN
Main track segment (ie road part)
struct trackSurface tTrackSurface
Surface.
#define TR_FENCE
Fence (no width) (barrier only)
#define TRK_ATT_RADIUSEND
#define TR_SPEEDLIMIT
Segment where the speed is limited.
#define TR_LFT
Left curve.
#define TRK_ATT_PIT_WIDTH
#define TRK_SECT_SURFACES
#define TR_XE
X End angle.
#define TR_EL
End-Left corner.
#define TRK_ATT_PROFSTEPSLEN
#define TR_ZE
Z End angle.
struct RoadCam tRoadCam
road camera
#define TR_RBORDER
Right border segment (inner segment)
#define TR_NORMAL
Normal segment.
#define TR_YL
Y Left angle.
#define TR_PITEXIT
Segment where the pit lane cross the main track.
#define TR_LBORDER
Left border segment (inner segment)
struct SegExt tSegExt
Extended track segment.
#define TR_LPOS_MAIN
Relative to the main segment, mostly used for racing on the main track.
#define TRK_ATT_PROFTGTSR
#define TR_PIT_ON_TRACK_SIDE
The pits are on the track side.
struct trackBarrier tTrackBarrier
Barrier.
#define TR_PITENTRY
Segment where the pit lane cross the main track.
#define TRK_VAL_PIT_TYPE_SIDE
#define TRK_ATT_PIT_START
#define TR_ER
End_Right corner.
#define TR_PLAN
Flat (border only)
#define TR_LSIDE
Left side segment (outer segment)
#define TR_CURB
Curb (border only)
#define TR_SL
Start-Left corner.
#define TR_RGT
Right curve.
#define TR_PITBUILDING
Pit building wall (barrier only)
#define TR_ZS
Rotation angles of the track in rad anti-clockwise: Index in:
#define TR_WALL
Wall (barrier only)
#define TR_SR
Start-Right corner.
tdble TrackSpline(tdble p0, tdble p1, tdble t0, tdble t1, tdble t)
void TrackLocal2Global(tTrkLocPos *p, tdble *X, tdble *Y)
tdble TrackHeightL(tTrkLocPos *p)