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++) {
713 GfFatal(
"AddSides: memory allocation error");
735 while (bseg->
side[side] != NULL) {
736 bseg = bseg->
side[side];
747 mSeg->
barrier[side] = curBarrier;
775 int segread, curindex;
776 tdble radius, radiusend = 0, dradius;
783 tdble xr, yr, newxr, newyr;
784 tdble xl, yl, newxl, newyl;
787 tdble x1, x2, y1, y2;
789 tdble zsl, zsr, zel, zer, zs, ze;
790 tdble bankings, bankinge, dz;
802 tdble tl, dtl, T1l, T2l;
803 tdble tr, dtr, T1r, T2r;
804 tdble curzel, curzer, curArc, curLength, curzsl, curzsr;
807 const int BUFSIZE = 256;
809 #define MAX_TMP_INTS 256 813 radius = arc =
length = alf = xr = yr = newxr = newyr = xl = yl = 0;
814 zel = zer = etgtl = etgtr = newxl = newyl = 0;
830 zsl = zsr = zel = zer = zs = ze = 0.0;
844 zsl = zsr = zel = zer = zs = ze = start->
vertex[
TR_SR].
z;
846 xl = xr - width * sin(alf);
847 yl = yr + width * cos(alf);
882 char* tmpmarks = strdup(marks);
883 char *s = strtok(tmpmarks,
";");
885 mi[ind] = (int)strtol(s, NULL, 0);
887 s = strtok(NULL,
";");
903 radius = radiusend = 0;
910 length = (radius + radiusend) / 2.0 * arc;
917 length = (radius + radiusend) / 2.0 * arc;
931 if (zs != -100000.0) {
934 zs = (zsl + zsr) / 2.0;
936 if (ze != -100000.0) {
938 }
else if (grade != -100000.0) {
941 ze = (zel + zer) / 2.0;
943 bankings = atan2(zsl - zsr, width);
944 bankinge = atan2(zel - zer, width);
947 dz = tan(bankings) * width / 2.0;
950 dz = tan(bankinge) * width / 2.0;
966 steps = (int)(
length / stepslg) + 1;
975 stgt = etgt = -100000.0;
978 if (stgt != -100000.0) {
979 stgtl = stgtr = stgt;
981 if (etgt != -100000.0) {
982 etgtl = etgtr = etgt;
986 stgtl = etgtl = (zel - zsl) /
length;
987 stgtr = etgtr = (zer - zsr) /
length;
996 dtl = 1.0 / (
tdble)steps;
1000 dtr = 1.0 / (
tdble)steps;
1005 curArc = arc / (
tdble)steps;
1007 dradius = (radiusend - radius) / (
tdble)steps;
1008 if (radiusend != radius) {
1011 dradius = (radiusend - radius) / (
tdble)(steps - 1);
1013 tdble tmpRadius = radius;
1014 for (curStep = 0; curStep < steps; curStep++) {
1015 tmpAngle += curLength / tmpRadius;
1016 tmpRadius += dradius;
1018 curLength *= arc / tmpAngle;
1023 while (curStep < steps) {
1035 curArc = curLength / radius;
1042 curSeg->
next = curSeg;
1043 curSeg->
prev = curSeg;
1047 curSeg->
prev = root;
1048 root->
next = curSeg;
1052 curSeg->
name = segName;
1053 curSeg->
id = curindex;
1060 int *mrks = (
int*)calloc(ind,
sizeof(
int));
1063 memcpy(mrks, mi, ind*
sizeof(
int));
1065 segExt->
marks = mrks;
1066 curSeg->
ext = segExt;
1075 curSeg->
length = curLength;
1077 newxr = xr + curLength * cos(alf);
1078 newyr = yr + curLength * sin(alf);
1079 newxl = xl + curLength * cos(alf);
1080 newyl = yl + curLength * sin(alf);
1121 curSeg->
radiusr = radius + wi2;
1122 curSeg->
radiusl = radius - wi2;
1123 curSeg->
arc = curArc;
1124 curSeg->
length = curLength;
1126 innerradius = radius - wi2;
1127 cenx = xl - innerradius * sin(alf);
1128 ceny = yl + innerradius * cos(alf);
1137 newxl = cenx + innerradius * sin(alf);
1138 newyl = ceny - innerradius * cos(alf);
1139 newxr = cenx + (innerradius + width) * sin(alf);
1140 newyr = ceny - (innerradius + width) * cos(alf);
1163 curSeg->
Kzl = tan(curSeg->
angle[
TR_YR]) * (innerradius + width);
1171 for (j = 0; j < 36; j++) {
1173 x1 = curSeg->
center.
x + (innerradius) * sin(alfl);
1174 y1 = curSeg->
center.
y - (innerradius) * cos(alfl);
1175 x2 = curSeg->
center.
x + (innerradius + width) * sin(alfl);
1176 y2 = curSeg->
center.
y - (innerradius + width) * cos(alfl);
1187 curSeg->
radiusr = radius - wi2;
1188 curSeg->
radiusl = radius + wi2;
1189 curSeg->
arc = curArc;
1190 curSeg->
length = curLength;
1192 innerradius = radius - wi2;
1193 cenx = xr + innerradius * sin(alf);
1194 ceny = yr - innerradius * cos(alf);
1203 newxl = cenx - (innerradius + width) * sin(alf);
1204 newyl = ceny + (innerradius + width) * cos(alf);
1205 newxr = cenx - innerradius * sin(alf);
1206 newyr = ceny + innerradius * cos(alf);
1237 for (j = 0; j < 36; j++) {
1239 x1 = curSeg->
center.
x - (innerradius + width) * sin(alfl);
1240 y1 = curSeg->
center.
y + (innerradius + width) * cos(alfl);
1241 x2 = curSeg->
center.
x - innerradius * sin(alfl);
1242 y2 = curSeg->
center.
y + innerradius * cos(alfl);
1252 totLength += curSeg->
length;
1290 const char *segName;
1295 const char *paramVal;
1296 const char *pitType;
1297 const int BUFSIZE = 256;
1299 char path2[BUFSIZE];
1322 if (pitEntrySeg->
id == segId) {
1325 pitEntrySeg = pitEntrySeg->
next;
1328 pitEntrySeg = pitEntrySeg->
prev;
1341 if (!strcmp(segName, pitExitSeg->
name)) {
1344 pitExitSeg = pitExitSeg->
prev;
1347 pitExitSeg = pitExitSeg->
next;
1359 if (!strcmp(segName, pitStart->
name)) {
1362 pitStart = pitStart->
next;
1365 pitStart = pitStart->
prev;
1377 if (!strcmp(segName, pitEnd->
name)) {
1380 pitEnd = pitEnd->
prev;
1383 pitEnd = pitEnd->
next;
1390 if (strcmp(paramVal,
"right") == 0) {
1396 if ((pitEntrySeg != NULL) && (pitExitSeg != NULL) && (pitStart != NULL) && (pitEnd != NULL)) {
1427 while (i < pits->nMaxPits) {
1433 switch (pits->
side) {
1435 curPitSeg = mSeg->
rside;
1436 if (curPitSeg->
rside) {
1437 offset = curPitSeg->
width;
1438 curPitSeg = curPitSeg->
rside;
1442 curPitSeg = mSeg->
lside;
1443 if (curPitSeg->
lside) {
1444 offset = curPitSeg->
width;
1445 curPitSeg = curPitSeg->
lside;
1449 if (toStart >= mSeg->length) {
1457 switch (pits->
side) {
1469 toStart += pits->
len;
1470 if (toStart >= mSeg->length) {
1471 toStart -= mSeg->length;
1477 for (mSeg = pitStart->
prev; mSeg != pitEnd->
next->
next; mSeg = mSeg->
next) {
1479 switch(pits->
side) {
1481 curSeg = mSeg->
rside;
1482 curSeg2 = curSeg->
rside;
1483 if ((mSeg != pitStart->
prev) && (mSeg != pitEnd->
next)) {
1488 curSeg = mSeg->
lside;
1489 curSeg2 = curSeg->
lside;
1490 if ((mSeg != pitStart->
prev) && (mSeg != pitEnd->
next)) {
1495 if ((mSeg != pitStart->
prev) && (mSeg != pitEnd->
next)) {
1500 }
else if (mSeg == pitStart->
prev) {
1505 }
else if (mSeg == pitEnd->
next) {
1523 GfFatal(
"ReadTrack3: Memory allocation error");
1525 if (*camList == NULL) {
1527 curCam->
next = curCam;
1530 (*camList)->
next = curCam;
1542 if (curSeg->
id == segId) {
1545 curSeg = curSeg->
next;
1548 trkPos.
seg = curSeg;
1562 if (curSeg->
id == segId) {
1565 curSeg = curSeg->
next;
1575 curSeg->
cam = curCam;
1576 curSeg = curSeg->
next;
1577 }
while (curSeg->
id != segId);
1599 if (curSeg->
lside) {
1605 if (curSeg->
rside) {
1611 curSeg = curSeg->
next;
1615 if (*camList != NULL) {
1618 curCam = curCam->
next;
1622 }
while (curCam != *camList);
static const char * KeyBorderWidth[2]
int nMaxPits
number max of pits
tdble kRoughness
Roughtness in m of the surface (wave height)
#define TR_PITBUILDING
Pit building wall (barrier only)
#define TR_SR
Start-Right corner.
#define TRK_ATT_RADIUSEND
tTrackSeg * pitEnd
Pit lane segment.
static const char * barrierMaterial[2]
static tdble borderWidth[2]
static void GfFatal(const char *fmt,...)
static void AddSides(tTrackSeg *curSeg, void *TrackHandle, tTrack *theTrack, int curStep, int steps)
tTrackOwnPit * driversPits
List of pits by driver.
int type
Geometrical type:
t3Dd center
Center of the curve.
static void CreateSegRing3(void *TrackHandle, tTrack *theTrack, tTrackSeg *start, tTrackSeg *end, int ext)
#define TR_ER
End_Right corner.
tdble toRight
Distance (+ to left, - to right) relative to the right side of segment.
static int barrierStyle[2]
#define TR_SPEEDLIMIT
Segment where the speed is limited.
#define TR_LSIDE
Left side segment (outer segment)
int GfParmListSeekNext(void *handle, const char *path)
Go the the next subsection element in the parameter set handle.
static tdble barrierWidth[2]
#define TR_ZS
Rotation angles of the track in rad anti-clockwise: Index in:
tdble width
Width of the segment (if constant width)
struct trackSurface * next
Next surface in list.
Location on the track in local coordinates.
#define TR_PIT_ON_TRACK_SIDE
The pits are on the track side.
static const char * borderMaterial[2]
unsigned int raceInfo
Type of segment regarding the race: Mask value in:
#define TRK_VAL_PIT_TYPE_SIDE
void TrackLocal2Global(tTrkLocPos *p, tdble *X, tdble *Y)
#define TR_NORMAL
Normal segment.
#define TR_SL
Start-Left corner.
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.
#define TRK_ATT_PROFSTEPSLEN
#define TR_CS
Center start angle.
static const char * KeyBarrierStyle[2]
static const char * KeyBarrierSurface[2]
static const char * KeyBorderSurface[2]
tdble lgfromstart
Length of beginning of segment from starting line.
tdble endWidth
Width of the end of the segment.
#define TR_YL
Y Left angle.
tdble length
Length in meters of the middle of the track.
tdble startWidth
Width of the beginning of the segment.
int nPitSeg
actual number of pits
tdble kRebound
Coefficient of energy restitution.
const char * GfParmGetStr(void *parmHandle, const char *path, const char *key, const char *deflt)
Get a string parameter from the parameter set handle.
#define TRK_ATT_PROFTGTEL
tTrackSeg * pitEntry
Pit lane segment.
#define TR_PITENTRY
Segment where the pit lane cross the main track.
#define TR_FENCE
Fence (no width) (barrier only)
static const char * KeyBarrierWidth[2]
static const char * KeySideWidth[2]
static tTrackSurface * barrierSurface[2]
static const char * KeySideBankType[2]
char * GfParmListGetCurEltName(void *handle, const char *path)
Get current subsection name of the parameter set handle during subsection iteration.
tdble toMiddle
Distance (+ to left, - to right) relative to the middle of segment.
#define TRK_VAL_PIT_TYPE_NONE
static tTrackSurface * borderSurface[2]
tdble length
main track length
tdble speedLimit
Speed limit between pitStart and pitEnd.
int type
Type of description:
static const char * KeySideEndWidth[2]
tTrkLocPos pos
Center of the pit position.
#define TR_RBORDER
Right border segment (inner segment)
int GfParmListSeekFirst(void *handle, const char *path)
Go the the first subsection element in the parameter set handle.
const char * material
Type of material used.
#define TRK_ATT_PROFTGTSL
#define TR_LPOS_MAIN
Relative to the main segment, mostly used for racing on the main track.
static const char * sideMaterial[2]
tTrackBarrier * barrier[2]
Segment barriers.
tTrackSurface * surface
Barrier surface.
const char * name
Segment name.
static const char * KeyBorderStyle[2]
#define TRK_ATT_PROFTGTER
#define TR_LAST
Segment before start line.
tdble toLeft
Distance (- to left, + to right) relative to left side of segment.
#define TR_LFT
Left curve.
#define TR_PITEXIT
Segment where the pit lane cross the main track.
#define TRK_ATT_PROFSTEPS
Scalar length(const Quaternion &q)
#define TR_RSIDE
Right side segment (outer segment)
tdble radiusr
Radius in meters of the right side of the track (>0)
static void normSeg(tTrackSeg *curSeg)
float tdble
Floating point type used in TORCS.
static tdble borderHeight[2]
tdble TrackHeightL(tTrkLocPos *p)
tdble radiusl
Radius in meters of the left side of the track (>0)
int nseg
Number of segments.
#define TR_CURB
Curb (border only)
#define TR_YR
Y Right angle.
static void * TrackHandle
struct trackSeg * side[2]
The Gaming Framework API.
void ReadTrack3(tTrack *theTrack, void *TrackHandle, tRoadCam **camList, int ext)
#define TRK_SECT_SURFACES
#define TR_PITEND
Car pit End.
#define TRK_ATT_PROFTGTSR
#define TRK_ATT_PIT_WIDTH
tdble arc
Arc in rad of the curve (>0)
#define TR_ZE
Z End angle.
#define TR_LBORDER
Left border segment (inner segment)
tTrackSeg * pitExit
Pit lane segment.
tdble height
Barrier height.
#define TR_XS
X Start angle.
tdble radius
Radius in meters of the middle of the track (>0)
static int sideBankType[2]
t3Dd vertex[4]
Coordinates of the 4 corners of the segment.
static tTrackSurface * sideSurface[2]
static const char * ValStyle[4]
tdble kRollRes
Rolling resistance.
tdble TrackSpline(tdble p0, tdble p1, tdble t0, tdble t1, tdble t)
static int borderStyle[2]
#define TRK_ATT_PIT_ENTRY
tdble height
Max height for curbs.
tTrackSeg * seg
Track segment.
tdble GfParmGetNum(void *handle, const char *path, const char *key, const char *unit, tdble deflt)
Get a numerical parameter from the parameter set handle.
tdble width
Width of each pit stop.
#define TR_EL
End-Left corner.
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.
Track segment (tTrackSeg) The segments can be straights (type TR_STR): (the track goes from the right...
#define TR_START
Segment after start line.
#define TR_RGT
Right curve.
tdble len
Lenght of each pit stop.
#define TR_XE
X End angle.
tdble toStart
Distance to start of segment (or arc if turn)
struct trackSeg * prev
Previous segment.
tTrackSurface * surface
Segment surface.
tdble kDammage
Dammages in case of collision.
tTrackSeg * pitStart
Pit lane segment.
struct trackSeg * next
Next segment.
static tdble GlobalStepLen
#define TR_MAIN
Main track segment (ie road part)
static tdble barrierHeight[2]
tTrackSurface * surfaces
Segment surface list.
static void InitSides(void *TrackHandle, tTrack *theTrack)
static tdble sideStartWidth[2]
static const char * KeyBorderHeight[2]
int style
Border and barrier segments style:
static tTrackSurface * AddTrackSurface(void *TrackHandle, tTrack *theTrack, const char *material)
Track Structure and Track Loader Module Definition.
static const char * KeySideSurface[2]
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.
static const char * KeyBarrierHeight[2]
#define TR_PLAN
Flat (border only)
tTrackSeg * seg
Main track.
tTrackPitInfo pits
Pits information.
#define TRK_ATT_PIT_START
tdble kFriction
Coefficient of friction.
tdble kRoughWaveLen
Wave length in m of the surface.
static tdble sideEndWidth[2]
#define TR_PITSTART
Car pit Star.
static const char * KeySideStartWidth[2]
tdble width
Barrier width.
#define TR_WALL
Wall (barrier only)