38 #define TSTX(x) do { \ 39 if (xmin > (x)) xmin = (x); \ 40 if (xmax < (x)) xmax = (x); \ 43 #define TSTY(y) do { \ 44 if (ymin > (y)) ymin = (y); \ 45 if (ymax < (y)) ymax = (y); \ 48 #define TSTZ(z) do { \ 49 if (zmin > (z)) zmin = (z); \ 50 if (zmax < (z)) zmax = (z); \ 91 const int bankingtype,
92 const tdble startwidth,
101 const int bankingtype,
102 const tdble startwidth,
111 const int bankingtype,
112 const tdble startwidth,
113 const tdble endwidth,
115 const tdble borderheight,
116 const int borderstyle
132 const int BUFSIZE = 256;
139 if (strcmp(curSurf->
material, material) == 0) {
142 curSurf = curSurf->
next;
148 GfFatal(
"AddTrackSurface: Memory allocation failed\n");
176 const int BUFSIZE = 256;
180 for (side = 0; side < 2; side++) {
243 const int BUFSIZE = 256;
254 for (side = 0; side < 2; side++) {
260 snprintf(path2, BUFSIZE,
"%s/%s", path,
SectSide[side]);
271 snprintf(path2, BUFSIZE,
"%s/%s", path,
SectBorder[side]);
288 snprintf(path2, BUFSIZE,
"%s/%s", path,
SectBarrier[side]);
309 Kew = (ew - sw) / (
tdble)steps;
310 ew = sw + (
tdble)(curStep+1) * Kew;
311 sw = sw + (
tdble)(curStep) * Kew;
320 if ((sw > 0.0f) || (ew > 0.0f)) {
328 GfFatal(
"AddSides: memory allocation error");
350 while (bseg->
side[side] != NULL) {
351 bseg = bseg->
side[side];
362 mSeg->
barrier[side] = curBarrier;
393 int segread, curindex;
394 tdble radius, radiusend = 0, dradius;
401 tdble xr, yr, newxr, newyr;
402 tdble xl, yl, newxl, newyl;
405 tdble x1, x2, y1, y2;
407 tdble zsl, zsr, zel, zer, zs, ze;
408 tdble bankings, bankinge, dz;
414 const char *segtype = (
char*)NULL;
415 const char *material;
422 tdble tl, dtl, T1l, T2l;
423 tdble tr, dtr, T1r, T2r;
424 tdble curzel, curzer, curArc, curLength, curzsl, curzsr;
427 void *segNameHash = NULL;
428 const int BUFSIZE = 256;
431 #define MAX_TMP_INTS 256 435 radius = arc =
length = alf = xr = yr = newxr = newyr = xl = yl = 0;
436 zel = zer = etgtl = etgtr = newxl = newyl = 0;
448 zsl = zsr = zel = zer = zs = ze = 0.0;
484 char* tmpmarks = strdup(marks);
485 char *s = strtok(tmpmarks,
";");
487 mi[ind] = (int)strtol(s, NULL, 0);
489 s = strtok(NULL,
";");
507 radius = radiusend = 0;
514 length = (radius + radiusend) / 2.0 * arc;
521 length = (radius + radiusend) / 2.0 * arc;
526 printf(
">>>>>>>>> DUPLICATED SEGMENT NAME \"%s\" PLEASE CHANGE IT !!!!\n", segName);
541 if (zs != -100000.0) {
544 zs = (zsl + zsr) / 2.0;
546 if (ze != -100000.0) {
548 }
else if (grade != -100000.0) {
551 ze = (zel + zer) / 2.0;
553 bankings = atan2(zsl - zsr, width);
554 bankinge = atan2(zel - zer, width);
557 dz = tan(bankings) * width / 2.0;
560 dz = tan(bankinge) * width / 2.0;
576 steps = (int)(
length / stepslg) + 1;
585 stgt = etgt = -100000.0;
588 if (stgt != -100000.0) {
589 stgtl = stgtr = stgt;
591 if (etgt != -100000.0) {
592 etgtl = etgtr = etgt;
596 stgtl = etgtl = (zel - zsl) /
length;
597 stgtr = etgtr = (zer - zsr) /
length;
606 dtl = 1.0 / (
tdble)steps;
610 dtr = 1.0 / (
tdble)steps;
615 curArc = arc / (
tdble)steps;
617 dradius = (radiusend - radius) / (
tdble)steps;
618 if (radiusend != radius) {
621 dradius = (radiusend - radius) / (
tdble)(steps - 1);
623 tdble tmpRadius = radius;
624 for (curStep = 0; curStep < steps; curStep++) {
625 tmpAngle += curLength / tmpRadius;
626 tmpRadius += dradius;
628 curLength *= arc / tmpAngle;
633 while (curStep < steps) {
645 curArc = curLength / radius;
652 curSeg->
next = curSeg;
653 curSeg->
prev = curSeg;
662 curSeg->
name = segName;
663 curSeg->
id = curindex;
672 int *mrks = (
int*)calloc(ind,
sizeof(
int));
675 memcpy(mrks, mi, ind*
sizeof(
int));
677 segExt->
marks = mrks;
678 curSeg->
ext = segExt;
687 curSeg->
length = curLength;
689 newxr = xr + curLength * cos(alf);
690 newyr = yr + curLength * sin(alf);
691 newxl = xl + curLength * cos(alf);
692 newyl = yl + curLength * sin(alf);
733 curSeg->
radiusr = radius + wi2;
734 curSeg->
radiusl = radius - wi2;
735 curSeg->
arc = curArc;
736 curSeg->
length = curLength;
738 innerradius = radius - wi2;
739 cenx = xl - innerradius * sin(alf);
740 ceny = yl + innerradius * cos(alf);
749 newxl = cenx + innerradius * sin(alf);
750 newyl = ceny - innerradius * cos(alf);
751 newxr = cenx + (innerradius + width) * sin(alf);
752 newyr = ceny - (innerradius + width) * cos(alf);
775 curSeg->
Kzl = tan(curSeg->
angle[
TR_YR]) * (innerradius + width);
783 for (j = 0; j < 36; j++) {
785 x1 = curSeg->
center.
x + (innerradius) * cos(alfl);
786 y1 = curSeg->
center.
y + (innerradius) * sin(alfl);
787 x2 = curSeg->
center.
x + (innerradius + width) * cos(alfl);
788 y2 = curSeg->
center.
y + (innerradius + width) * sin(alfl);
799 curSeg->
radiusr = radius - wi2;
800 curSeg->
radiusl = radius + wi2;
801 curSeg->
arc = curArc;
802 curSeg->
length = curLength;
804 innerradius = radius - wi2;
805 cenx = xr + innerradius * sin(alf);
806 ceny = yr - innerradius * cos(alf);
815 newxl = cenx - (innerradius + width) * sin(alf);
816 newyl = ceny + (innerradius + width) * cos(alf);
817 newxr = cenx - innerradius * sin(alf);
818 newyr = ceny + innerradius * cos(alf);
846 al = curSeg->
arc / 36.0;
849 for (j = 0; j < 36; j++) {
851 x1 = curSeg->
center.
x + (innerradius + width) * cos(alfl);
852 y1 = curSeg->
center.
y + (innerradius + width) * sin(alfl);
853 x2 = curSeg->
center.
x + innerradius * cos(alfl);
854 y2 = curSeg->
center.
y + innerradius * sin(alfl);
864 totLength += curSeg->
length;
914 const char *paramVal;
915 const int BUFSIZE = 256;
939 if (pitEntrySeg->
id == segId) {
942 pitEntrySeg = pitEntrySeg->
next;
945 pitEntrySeg = pitEntrySeg->
prev;
959 if (!strcmp(segName, pitExitSeg->
name)) {
963 pitExitSeg = pitExitSeg->
prev;
976 if (!strcmp(segName, pitStart->
name)) {
979 pitStart = pitStart->
next;
982 pitStart = pitStart->
prev;
996 if (!strcmp(segName, pitEnd->
name)) {
1000 pitEnd = pitEnd->
prev;
1007 if (strcmp(paramVal,
"right") == 0) {
1013 if ((pitEntrySeg != NULL) && (pitExitSeg != NULL) && (pitStart != NULL) && (pitEnd != NULL)) {
1040 mSeg = pitStart->
prev;
1044 while (i < pits->nMaxPits) {
1050 if (toStart >= mSeg->length) {
1051 toStart -= mSeg->length;
1055 switch (pits->
side) {
1057 curPitSeg = mSeg->
rside;
1058 if (curPitSeg->
rside) {
1059 offset = curPitSeg->
width;
1060 curPitSeg = curPitSeg->
rside;
1064 curPitSeg = mSeg->
lside;
1065 if (curPitSeg->
lside) {
1066 offset = curPitSeg->
width;
1067 curPitSeg = curPitSeg->
lside;
1075 switch (pits->
side) {
1087 toStart += pits->
len;
1088 if (toStart >= mSeg->length) {
1089 toStart -= mSeg->length;
1095 for (mSeg = pitStart->
prev; mSeg != pitEnd->
next->
next; mSeg = mSeg->
next) {
1097 switch(pits->
side) {
1099 curSeg = mSeg->
rside;
1100 curSeg2 = curSeg->
rside;
1101 if ((mSeg != pitStart->
prev) && (mSeg != pitEnd->
next)) {
1106 curSeg = mSeg->
lside;
1107 curSeg2 = curSeg->
lside;
1108 if ((mSeg != pitStart->
prev) && (mSeg != pitEnd->
next)) {
1113 if ((mSeg != pitStart->
prev) && (mSeg != pitEnd->
next)) {
1118 }
else if (mSeg == pitStart->
prev) {
1123 }
else if (mSeg == pitEnd->
next) {
1139 GfFatal(
"ReadTrack3: Memory allocation error");
1141 if (*camList == NULL) {
1143 curCam->
next = curCam;
1146 (*camList)->
next = curCam;
1158 if (curSeg->
id == segId) {
1161 curSeg = curSeg->
next;
1164 trkPos.
seg = curSeg;
1178 if (curSeg->
id == segId) {
1181 curSeg = curSeg->
next;
1191 curSeg->
cam = curCam;
1192 curSeg = curSeg->
next;
1193 }
while (curSeg->
id != segId);
1215 if (curSeg->
lside) {
1221 if (curSeg->
rside) {
1227 curSeg = curSeg->
next;
1231 if (*camList != NULL) {
1234 curCam = curCam->
next;
1238 }
while (curCam != *camList);
1256 al = curBorder->
arc / 36.0 *
sign;
1259 for (j = 0; j < 36; j++) {
1261 x = curBorder->
center.
x + radius * cos(alfl);
1262 y = curBorder->
center.
y + radius * sin(alfl);
1284 curBorder->
Kyl = (endwidth - startwidth) / curBorder->
arc;
1306 const int bankingtype,
1307 const tdble startwidth,
1308 const tdble endwidth,
1309 const tdble maxwidth
1314 if (turntype ==
TR_LFT) {
1330 curBorder->
arc = curSeg->
arc;
1348 curBorder->
arc = curSeg->
arc;
1380 const int bankingtype,
1381 const tdble startwidth,
1382 const tdble endwidth
1412 curBorder->
Kyl = (endwidth - startwidth) / curBorder->
length;
1442 const int righttype,
1443 const int bankingtype,
1444 const tdble startwidth,
1445 const tdble endwidth,
1447 const tdble borderheight,
1448 const int borderstyle
1453 curSeg->
lside = curBorder;
1456 curBorder->
type2 = lefttype;
1458 curSeg->
rside = curBorder;
1461 curBorder->
type2 = righttype;
1466 curBorder->
width =
MIN(startwidth, endwidth);
1467 tdble maxWidth =
MAX(startwidth, endwidth);
1471 curBorder->
height = borderheight;
1472 curBorder->
style = borderstyle;
1481 switch(curSeg->
type) {
int nMaxPits
number max of pits
#define GF_HASH_TYPE_STR
String key based hash table.
static int sideBankType[2]
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 void GfFatal(const char *fmt,...)
tTrackOwnPit * driversPits
List of pits by driver.
int type
Geometrical type:
t3Dd center
Center of the curve.
#define TR_ER
End_Right corner.
tdble toRight
Distance (+ to left, - to right) relative to the right side of segment.
#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.
#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.
static const char * SectSide[2]
#define TR_PIT_ON_TRACK_SIDE
The pits are on the track side.
static tdble barrierHeight[2]
unsigned int raceInfo
Type of segment regarding the race: Mask value in:
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
static tTrackSurface * getTrackSurface(void *trackHandle, tTrack *theTrack, const char *material)
Gets surface properties based on the material.
#define TR_CS
Center start angle.
static tdble borderWidth[2]
void GfHashRelease(void *hash, tfHashFree hashFree)
Release a hash table.
static void normSeg(tTrackSeg *curSeg)
Segment coordinate normalization, track is moved to the origin of the coordinate system.
#define TRK_SECT_LBARRIER
static const char * SectBorder[2]
static tTrackSurface * sideSurface[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.
const void * GfHashGetStr(void *hash, const char *key)
Get the user data associated with a string key.
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)
#define TRK_SECT_RBARRIER
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.
static void addSides(tTrackSeg *curSeg, void *trackHandle, tTrack *theTrack, int curStep, int steps)
Adds the specified side/border/barrier segments to given main track segement.
static const char * barrierMaterial[2]
tdble length
main track length
tdble speedLimit
Speed limit between pitStart and pitEnd.
int type
Type of description:
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.
tTrackBarrier * barrier[2]
Segment barriers.
tTrackSurface * surface
Barrier surface.
const char * name
Segment name.
#define TRK_ATT_PROFTGTER
#define TR_LAST
Segment before start line.
void * GfHashCreate(int type)
Create a new hash table.
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)
float tdble
Floating point type used in TORCS.
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.
static tTrackSurface * borderSurface[2]
#define TRK_SECT_SURFACES
#define TR_PITEND
Car pit End.
#define TRK_ATT_DOVFACTOR
#define TRK_ATT_PROFTGTSR
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 tdble borderHeight[2]
t3Dd vertex[4]
Coordinates of the 4 corners of the segment.
tdble kRollRes
Rolling resistance.
static const char * sideMaterial[2]
static tdble sideEndWidth[2]
tdble TrackSpline(tdble p0, tdble p1, tdble t0, tdble t1, tdble t)
static tdble sideStartWidth[2]
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.
static const char * SectBarrier[2]
Track segment (tTrackSeg) The segments can be straights (type TR_STR): (the track goes from the right...
static tTrackSurface * barrierSurface[2]
#define TR_START
Segment after start line.
static void initSideForStraight(tTrackSeg *const curBorder, const tTrackSeg *const curSeg, const int side, const int bankingtype, const tdble startwidth, const tdble endwidth)
Set up side and border track segments for straight segments.
int GfHashAddStr(void *hash, const char *key, const void *data)
Add an element with a string key to a hash table.
#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)
static void updateMinMaxForTurn(const tTrackSeg *const curBorder, const tdble radius, const tdble sign, const tdble z)
Update global min/max values for turns (discretized approximation).
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 const char * ValStyle[]
void ReadTrack4(tTrack *theTrack, void *TrackHandle, tRoadCam **camList, int ext)
#define TR_MAIN
Main track segment (ie road part)
static void readDefaultSideParameters(void *trackHandle, tTrack *theTrack)
Reads default side/border track segment parameters.
tTrackSurface * surfaces
Segment surface list.
static tdble GlobalStepLen
static void initSideForTurn(const int turntype, tTrackSeg *const curBorder, const tTrackSeg *const curSeg, const int side, const int bankingtype, const tdble startwidth, const tdble endwidth, const tdble maxwidth)
Set up side and border track segments for turns.
static const char * borderMaterial[2]
static tdble barrierWidth[2]
static void initAnglesAndGradients(tTrackSeg *const curBorder, const tdble startwidth, const tdble endwidth)
Set up border segment angles and gradients.
static int borderStyle[2]
static void CreateSegRing(void *TrackHandle, tTrack *theTrack, int ext)
int style
Border and barrier segments style:
Track Structure and Track Loader Module Definition.
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 int barrierStyle[2]
#define TR_PLAN
Flat (border only)
tTrackSeg * seg
Main track.
tTrackPitInfo pits
Pits information.
tdble kFriction
Coefficient of friction.
tdble kRoughWaveLen
Wave length in m of the surface.
#define TR_PITSTART
Car pit Star.
static tTrackSeg * commonSideInit(tTrackSeg *const curSeg, const int side, const int lefttype, const int righttype, const int bankingtype, const tdble startwidth, const tdble endwidth, tTrackSurface *surface, const tdble borderheight, const int borderstyle)
Common side/border allocation and initialization for straights and turns.
tdble width
Barrier width.
#define TR_WALL
Wall (barrier only)