/***************************************************************************
file : track.cpp
created : Sun Dec 24 12:14:18 CET 2000
copyright : (C) 2000 by Eric Espie
email : eric.espie@torcs.org
version : $Id: track.cpp,v 1.22 2006/10/29 15:55:33 berniw Exp $
***************************************************************************/
/***************************************************************************
* *
* This program 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 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
/** @file
@author Eric Espie
@version $Id: track.cpp,v 1.22 2006/10/29 15:55:33 berniw Exp $
*/
#include
#include
#include
#include
#ifndef WIN32
#include
#endif
#include
#include
#include
#include
#include "ac3d.h"
#include "util.h"
#include "trackgen.h"
typedef struct texElt
{
char *name;
char *namebump;
unsigned int texid;
struct texElt *next;
} tTexElt;
typedef struct dispElt
{
int start;
int nb;
int surfType;
char *name;
int id;
tTexElt *texture;
struct dispElt *next;
} tDispElt;
typedef struct group
{
int nb;
tDispElt *dispList;
} tGroup;
static tGroup *Groups;
static int ActiveGroups;
static int GroupNb;
#define LMAX TrackStep
static float *trackvertices;
static float *tracktexcoord;
static unsigned int *trackindices;
static tdble TrackStep;
static void
initPits(tTrackPitInfo *pits)
{
tTrackSeg *curMainSeg;
tTrackSeg *curPitSeg = NULL;
tdble toStart = 0;
tdble offset = 0;
tTrkLocPos curPos;
int changeSeg;
int i;
switch (pits->type) {
case TR_PIT_ON_TRACK_SIDE:
pits->driversPits = (tTrackOwnPit*)calloc(pits->nMaxPits, sizeof(tTrackOwnPit));
pits->driversPitsNb = pits->nMaxPits;
curPos.type = TR_LPOS_MAIN;
curMainSeg = pits->pitStart->prev;
changeSeg = 1;
toStart = 0;
i = 0;
while (i < pits->nMaxPits) {
if (changeSeg) {
changeSeg = 0;
offset = 0;
curMainSeg = curMainSeg->next;
switch (pits->side) {
case TR_RGT:
curPitSeg = curMainSeg->rside;
if (curPitSeg->rside) {
offset = curPitSeg->width;
curPitSeg = curPitSeg->rside;
}
break;
case TR_LFT:
curPitSeg = curMainSeg->lside;
if (curPitSeg->lside) {
offset = curPitSeg->width;
curPitSeg = curPitSeg->lside;
}
break;
}
curPos.seg = curMainSeg;
if (toStart >= curMainSeg->length) {
toStart -= curMainSeg->length;
changeSeg = 1;
continue;
}
}
/* Not the real position but the start and border one instead of center */
curPos.toStart = toStart;
switch (pits->side) {
case TR_RGT:
curPos.toRight = -offset - RtTrackGetWidth(curPitSeg, toStart);
curPos.toLeft = curMainSeg->width - curPos.toRight;
curPos.toMiddle = curMainSeg->width / 2.0 - curPos.toRight;
break;
case TR_LFT:
curPos.toLeft = -offset - RtTrackGetWidth(curPitSeg, toStart);
curPos.toRight = curMainSeg->width - curPos.toLeft;
curPos.toMiddle = curMainSeg->width / 2.0 - curPos.toLeft;
break;
}
memcpy(&(pits->driversPits[i].pos), &curPos, sizeof(curPos));
toStart += pits->len;
if (toStart >= curMainSeg->length) {
toStart -= curMainSeg->length;
changeSeg = 1;
}
i++;
}
break;
case TR_PIT_ON_SEPARATE_PATH:
break;
case TR_PIT_NONE:
break;
}
}
int
InitScene(tTrack *Track, void *TrackHandle, int bump)
{
int i, j;
tTrackSeg *seg;
tTrackSeg *mseg;
int nbvert;
tdble width, wi2;
tdble anz, ts = 0;
tdble radiusr, radiusl;
tdble step;
tTrkLocPos trkpos;
tdble x, y, z;
tdble x2, y2, z2;
tdble x3, y3, z3;
int startNeeded;
tDispElt *aDispElt = NULL;
unsigned int prevTexId;
unsigned int curTexId = 0;
int curTexType = 0;
int curTexLink = 0;
tdble curTexOffset = 0;
tdble curTexSeg;
tdble curTexSize = 0;
tdble curHeight;
tTexElt *texList = (tTexElt*)NULL;
tTexElt *curTexElt = NULL;
tTrackBarrier *curBarrier;
tdble texLen;
tdble texStep;
tdble texMaxT = 0;
tTrackPitInfo *pits;
static int GenTexId = 1;
tdble runninglentgh;
tdble tmWidth = Track->graphic.turnMarksInfo.width;
tdble tmHeight = Track->graphic.turnMarksInfo.height;
tdble tmVSpace = Track->graphic.turnMarksInfo.vSpace;
tdble tmHSpace = Track->graphic.turnMarksInfo.hSpace;
char buf[256];
int hasBorder;
tDispElt *theCurDispElt = NULL;
char sname[256];
#define LG_STEP_MAX 50.0
printf("++++++++++++ Track ++++++++++++\n");
printf("name = %s\n", Track->name);
printf("author = %s\n", Track->author);
printf("filename = %s\n", Track->filename);
printf("nseg = %d\n", Track->nseg);
printf("version = %d\n", Track->version);
printf("length = %f\n", Track->length);
printf("width = %f\n", Track->width);
printf("pits = %d\n", Track->pits.nMaxPits);
printf("XSize = %f\n", Track->max.x);
printf("YSize = %f\n", Track->max.y);
printf("ZSize = %f\n", Track->max.z);
tdble delatx = Track->seg->next->vertex[TR_SL].x - Track->seg->vertex[TR_EL].x;
tdble delaty = Track->seg->next->vertex[TR_SL].y - Track->seg->vertex[TR_EL].y;
tdble delatz = Track->seg->next->vertex[TR_SL].z - Track->seg->vertex[TR_EL].z;
tdble delata = Track->seg->next->angle[TR_ZS] - Track->seg->angle[TR_ZE];
NORM_PI_PI(delata);
printf("Delta X = %f\n", delatx);
printf("Delta Y = %f\n", delaty);
printf("Delta Z = %f\n", delatz);
printf("Delta Ang = %f (%f)\n", delata, RAD2DEG(delata));
/* if ((fabs(delatx) > 1.0) || (fabs(delaty) > 1.0) || (fabs(delatz) > 1.0)) { */
/* exit(0); */
/* } */
Groups = (tGroup *)calloc(Track->nseg, sizeof(tGroup));
ActiveGroups = 0;
GroupNb = Track->nseg;
width = Track->width;
wi2 = width / 2.0;
trkpos.type = TR_LPOS_MAIN;
#define SETTEXTURE(texname, texnamebump, mipmap) do { \
int found = 0; \
curTexElt = texList; \
if (curTexElt == NULL) { \
curTexElt = (tTexElt*)calloc(1, sizeof(tTexElt)); \
curTexElt->next = curTexElt; \
texList = curTexElt; \
curTexElt->name = strdup(texname); \
curTexElt->namebump = strdup(texnamebump); \
curTexElt->texid = GenTexId++; \
} else { \
do { \
curTexElt = curTexElt->next; \
if (strcmp(texname, curTexElt->name) == 0) { \
found = 1; \
break; \
} \
} while (curTexElt != texList); \
if (!found) { \
curTexElt = (tTexElt*)calloc(1, sizeof(tTexElt)); \
curTexElt->next = texList->next; \
texList->next = curTexElt; \
texList = curTexElt; \
curTexElt->name = strdup(texname); \
curTexElt->namebump = strdup(texnamebump); \
curTexElt->texid = GenTexId++; \
} \
} \
curTexId = curTexElt->texid; \
} while (0)
#define NBELTLIST 1
#define NEWDISPLIST(texchange, _name, _id) do { \
if (!bump || (*(curTexElt->namebump) != 0)) { \
if (theCurDispElt != NULL) { \
startNeeded = texchange; \
if (theCurDispElt->start != nbvert) { \
theCurDispElt->nb = nbvert - theCurDispElt->start; \
theCurDispElt = aDispElt = (tDispElt*)malloc(sizeof(tDispElt)); \
aDispElt->start = nbvert; \
aDispElt->nb = 0; \
aDispElt->name = strdup(_name); \
aDispElt->id = _id; \
aDispElt->texture = curTexElt; \
aDispElt->surfType = 0; \
if (Groups[_id].nb == 0) { \
ActiveGroups++; \
aDispElt->next = aDispElt; \
Groups[_id].dispList = aDispElt; \
} else { \
aDispElt->next = Groups[_id].dispList->next; \
Groups[_id].dispList->next = aDispElt; \
Groups[_id].dispList = aDispElt; \
} \
Groups[_id].nb++; \
} else { \
aDispElt->texture = curTexElt; \
aDispElt->surfType = 0; \
} \
} else { \
theCurDispElt = aDispElt = (tDispElt*)malloc(sizeof(tDispElt)); \
aDispElt->start = nbvert; \
aDispElt->nb = 0; \
aDispElt->name = strdup(_name); \
aDispElt->id = _id; \
aDispElt->texture = curTexElt; \
aDispElt->surfType = 0; \
aDispElt->next = aDispElt; \
Groups[_id].dispList = aDispElt; \
Groups[_id].nb++; \
ActiveGroups++; \
} \
/* fprintf(stderr, "%s %d (%s)\n", _name, _id, curTexElt->name); */ \
} \
} while (0)
#define CHECKDISPLIST(mat, name, id, off) do { \
char *texname; \
char *texnamebump; \
int mipmap; \
static char path_[256]; \
if (Track->version < 4) { \
sprintf(path_, "%s/%s/%s", TRK_SECT_SURFACES, TRK_LST_SURF, mat); \
} else { \
sprintf(path_, "%s/%s", TRK_SECT_SURFACES, mat); \
} \
texnamebump = GfParmGetStr(TrackHandle, path_, TRK_ATT_BUMPNAME, ""); \
texname = GfParmGetStr(TrackHandle, path_, TRK_ATT_TEXTURE, "tr-asphalt.rgb"); \
mipmap = (int)GfParmGetNum(TrackHandle, path_, TRK_ATT_TEXMIPMAP, (char*)NULL, 0); \
SETTEXTURE(texname, texnamebump, mipmap); \
if ((curTexId != prevTexId) || (startNeeded)) { \
char *textype; \
if (bump) { \
curTexType = 1; \
curTexLink = 1; \
curTexOffset = -off; \
curTexSize = GfParmGetNum(TrackHandle, path_, TRK_ATT_BUMPSIZE, (char*)NULL, 20.0); \
} else { \
textype = GfParmGetStr(TrackHandle, path_, TRK_ATT_TEXTYPE, "continuous"); \
if (strcmp(textype, "continuous") == 0) \
curTexType = 1; \
else \
curTexType = 0; \
textype = GfParmGetStr(TrackHandle, path_, TRK_ATT_TEXLINK, TRK_VAL_YES); \
if (strcmp(textype, TRK_VAL_YES) == 0) \
curTexLink = 1; \
else \
curTexLink = 0; \
textype = GfParmGetStr(TrackHandle, path_, TRK_ATT_TEXSTARTBOUNDARY, TRK_VAL_NO); \
if (strcmp(textype, TRK_VAL_YES) == 0) \
curTexOffset = -off; \
else \
curTexOffset = 0; \
curTexSize = GfParmGetNum(TrackHandle, path_, TRK_ATT_TEXSIZE, (char*)NULL, 20.0); \
} \
prevTexId = curTexId; \
NEWDISPLIST(1, name, id); \
} \
} while (0)
#define CHECKDISPLIST2(texture, mipmap, name, id) do { \
char texname[256]; \
sprintf(texname, "%s.rgb", texture); \
SETTEXTURE(texname, "", mipmap); \
if (curTexId != prevTexId) { \
prevTexId = curTexId; \
NEWDISPLIST(1, name, id); \
} \
} while (0)
#define CHECKDISPLIST3(texture, mipmap, name, id) do { \
SETTEXTURE(texture, "", mipmap); \
if (curTexId != prevTexId) { \
prevTexId = curTexId; \
NEWDISPLIST(1, name, id); \
} \
} while (0)
#define CLOSEDISPLIST() do { \
theCurDispElt->nb = nbvert - theCurDispElt->start; \
} while (0)
#define SETPOINT(t1, t2, x, y, z) do { \
if (*(curTexElt->name) != 0) { \
tracktexcoord[2*nbvert] = t1; \
tracktexcoord[2*nbvert+1] = t2; \
trackvertices[3*nbvert] = x; \
trackvertices[3*nbvert+1] = y; \
trackvertices[3*nbvert+2] = z; \
trackindices[nbvert] = nbvert; \
++nbvert; \
} \
} while (0)
#define SETPOINT2(t1, t2, x, y, z) do { \
if (*(curTexElt->name) != 0) { \
tracktexcoord[2*nbvert] = t1; \
tracktexcoord[2*nbvert+1] = t2; \
trackvertices[3*nbvert] = x; \
trackvertices[3*nbvert+1] = y; \
trackvertices[3*nbvert+2] = z; \
trackindices[nbvert] = nbvert; \
++nbvert; \
printf("x=%f y=%f z=%f u=%f v=%f\n", \
(tdble)(x), (tdble)(y), (tdble)(z), \
(tdble)(t1), (tdble)(t2)); \
} \
} while (0)
/* Count the number of vertice to allocate */
nbvert = 0;
for (i = 0, seg = Track->seg->next; i < Track->nseg; i++, seg = seg->next) {
nbvert++;
switch (seg->type) {
case TR_STR:
nbvert += (int)(seg->length / LMAX);
break;
case TR_LFT:
nbvert += (int)(seg->arc * (seg->radiusr) / LMAX);
break;
case TR_RGT:
nbvert += (int)(seg->arc * (seg->radiusl) / LMAX);
break;
}
}
nbvert++;
nbvert *= 30;
nbvert+=58; /* start bridge */
nbvert+=12 + 10 * Track->pits.driversPitsNb;
// TODO: Investigate if this is a feasible solution, nbvert was perviously += 1000.
nbvert+=10000; /* safety margin */
printf("=== Indices Array Size = %d\n", nbvert);
printf("=== Vertex Array Size = %d\n", nbvert * 3);
printf("=== Tex Coord Array Size = %d\n", nbvert * 2);
trackindices = (unsigned int*)malloc(sizeof(unsigned int) * nbvert);
trackvertices = (float*)malloc(sizeof(GLfloat)*(nbvert * 3));
tracktexcoord = (float*)malloc(sizeof(GLfloat)*(nbvert * 2));
nbvert = 0;
/* Main track */
prevTexId = 0;
texLen = 0;
startNeeded = 1;
runninglentgh = 0;
for (i = 0, seg = Track->seg->next; i < Track->nseg; i++, seg = seg->next) {
CHECKDISPLIST(seg->surface->material, "tkMn", i, seg->lgfromstart);
if (!curTexLink) {
curTexSeg = 0;
} else {
curTexSeg = seg->lgfromstart;
}
curTexSeg += curTexOffset;
texLen = curTexSeg / curTexSize;
if (startNeeded || (runninglentgh > LG_STEP_MAX)) {
NEWDISPLIST(0, "tkMn", i);
runninglentgh = 0;
ts = 0;
texMaxT = (curTexType == 1 ? width / curTexSize : 1.0 + floor(width / curTexSize));
SETPOINT(texLen, texMaxT, seg->vertex[TR_SL].x, seg->vertex[TR_SL].y, seg->vertex[TR_SL].z);
SETPOINT(texLen, 0.0, seg->vertex[TR_SR].x, seg->vertex[TR_SR].y, seg->vertex[TR_SR].z);
}
switch (seg->type) {
case TR_STR:
ts = LMAX;
texStep = LMAX / curTexSize;
trkpos.seg = seg;
while (ts < seg->length) {
texLen += texStep;
trkpos.toStart = ts;
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, texMaxT, x, y, RtTrackHeightL(&trkpos));
trkpos.toRight = 0;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.0, x, y, RtTrackHeightL(&trkpos));
ts += LMAX;
}
ts = seg->length;
break;
case TR_LFT:
step = LMAX / (seg->radiusr);
texStep = step * seg->radius / curTexSize;
anz = seg->angle[TR_ZS] + step;
ts = step;
radiusr = seg->radiusr;
radiusl = seg->radiusl;
trkpos.seg = seg;
while (anz < seg->angle[TR_ZE]) {
texLen += texStep;
trkpos.toStart = ts;
/* left */
trkpos.toRight = width;
SETPOINT(texLen, texMaxT, seg->center.x + radiusl * sin(anz), seg->center.y - radiusl * cos(anz), RtTrackHeightL(&trkpos));
/* right */
trkpos.toRight = 0;
SETPOINT(texLen, 0.0, seg->center.x + radiusr * sin(anz), seg->center.y - radiusr * cos(anz), RtTrackHeightL(&trkpos));
ts += step;
anz += step;
}
ts = seg->arc;
break;
case TR_RGT:
step = LMAX / (seg->radiusl);
texStep = step * seg->radius / curTexSize;
anz = seg->angle[TR_ZS] - step;
ts = step;
radiusr = seg->radiusr;
radiusl = seg->radiusl;
trkpos.seg = seg;
while (anz > seg->angle[TR_ZE]) {
texLen += texStep;
trkpos.toStart = ts;
/* left */
trkpos.toRight = width;
SETPOINT(texLen, texMaxT, seg->center.x - radiusl * sin(anz), seg->center.y + radiusl * cos(anz), RtTrackHeightL(&trkpos));
/* right */
trkpos.toRight = 0;
SETPOINT(texLen, 0, seg->center.x - radiusr * sin(anz), seg->center.y + radiusr * cos(anz), RtTrackHeightL(&trkpos));
ts += step;
anz -= step;
}
ts = seg->arc;
break;
}
texLen = (curTexSeg + seg->length) / curTexSize;
SETPOINT(texLen, texMaxT, seg->vertex[TR_EL].x, seg->vertex[TR_EL].y, seg->vertex[TR_EL].z);
SETPOINT(texLen, 0, seg->vertex[TR_ER].x, seg->vertex[TR_ER].y, seg->vertex[TR_ER].z);
startNeeded = 0;
runninglentgh += seg->length;
}
/* Right Border */
for (j = 0; j < 3; j++) {
prevTexId = 0;
texLen = 0;
startNeeded = 1;
runninglentgh = 0;
sprintf(sname, "t%dRB", j);
for (i = 0, mseg = Track->seg->next; i < Track->nseg; i++, mseg = mseg->next) {
if ((mseg->rside != NULL) && (mseg->rside->type2 == TR_RBORDER)) {
seg = mseg->rside;
CHECKDISPLIST(seg->surface->material, sname, i, mseg->lgfromstart);
if (!curTexLink) {
curTexSeg = 0;
} else {
curTexSeg = mseg->lgfromstart;
}
curTexSeg += curTexOffset;
texLen = curTexSeg / curTexSize;
if (startNeeded || (runninglentgh > LG_STEP_MAX)) {
NEWDISPLIST(0, sname, i);
runninglentgh = 0;
ts = 0;
width = RtTrackGetWidth(seg, ts);
texMaxT = (curTexType == 1 ? width / curTexSize : 1.0 + floor(width / curTexSize));
switch (seg->style) {
case TR_PLAN:
if (j == 0) {
SETPOINT(texLen, 0, seg->vertex[TR_SL].x, seg->vertex[TR_SL].y, seg->vertex[TR_SL].z);
SETPOINT(texLen, texMaxT, seg->vertex[TR_SR].x, seg->vertex[TR_SR].y, seg->vertex[TR_SR].z);
}
break;
case TR_CURB:
switch (j) {
case 0:
if (!mseg->prev->rside || (mseg->prev->rside->type2 != TR_RBORDER) || (mseg->prev->rside->style != TR_CURB)) {
SETPOINT(texLen, 0, seg->vertex[TR_SL].x, seg->vertex[TR_SL].y, seg->vertex[TR_SL].z - 0.1);
SETPOINT(texLen, texMaxT, seg->vertex[TR_SR].x, seg->vertex[TR_SR].y, seg->vertex[TR_SR].z);
}
SETPOINT(texLen, 0, seg->vertex[TR_SL].x, seg->vertex[TR_SL].y, seg->vertex[TR_SL].z);
SETPOINT(texLen, texMaxT, seg->vertex[TR_SR].x, seg->vertex[TR_SR].y, seg->vertex[TR_SR].z + seg->height);
break;
case 1:
SETPOINT(texLen, texMaxT, seg->vertex[TR_SR].x, seg->vertex[TR_SR].y, seg->vertex[TR_SR].z + seg->height);
SETPOINT(texLen, texMaxT, seg->vertex[TR_SR].x, seg->vertex[TR_SR].y, seg->vertex[TR_SR].z);
break;
case 2:
break;
}
break;
case TR_WALL:
switch (j) {
case 0:
SETPOINT(texLen, 0, seg->vertex[TR_SL].x, seg->vertex[TR_SL].y, seg->vertex[TR_SL].z);
SETPOINT(texLen, .33, seg->vertex[TR_SL].x, seg->vertex[TR_SL].y, seg->vertex[TR_SL].z + seg->height);
break;
case 1:
SETPOINT(texLen, 0.33, seg->vertex[TR_SL].x, seg->vertex[TR_SL].y, seg->vertex[TR_SL].z + seg->height);
SETPOINT(texLen, 0.66, seg->vertex[TR_SR].x, seg->vertex[TR_SR].y, seg->vertex[TR_SR].z + seg->height);
break;
case 2:
if (!mseg->prev->rside || (mseg->prev->rside->type2 != TR_RBORDER) || (mseg->prev->rside->style != TR_WALL)) {
SETPOINT(texLen - seg->width/curTexSize, 0.66, seg->vertex[TR_SL].x, seg->vertex[TR_SL].y, seg->vertex[TR_SL].z + seg->height);
SETPOINT(texLen - seg->width/curTexSize, 1.00, seg->vertex[TR_SL].x, seg->vertex[TR_SL].y, seg->vertex[TR_SL].z);
}
SETPOINT(texLen, 0.66, seg->vertex[TR_SR].x, seg->vertex[TR_SR].y, seg->vertex[TR_SR].z + seg->height);
SETPOINT(texLen, 1.0, seg->vertex[TR_SR].x, seg->vertex[TR_SR].y, seg->vertex[TR_SR].z);
break;
}
break;
}
}
switch (seg->type) {
case TR_STR:
ts = LMAX;
texStep = LMAX / curTexSize;
texLen += texStep;
trkpos.seg = seg;
while (ts < seg->length) {
trkpos.toStart = ts;
width = RtTrackGetWidth(seg, ts);
texMaxT = (curTexType == 1 ? width / curTexSize : 1.0 + floor(width / curTexSize));
switch (seg->style) {
case TR_PLAN:
if (j == 0) {
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0, x, y, RtTrackHeightL(&trkpos));
trkpos.toRight = 0 ;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, texMaxT, x, y, RtTrackHeightL(&trkpos));
}
break;
case TR_CURB:
switch (j) {
case 0:
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0, x, y, RtTrackHeightL(&trkpos));
trkpos.toRight = 0 ;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, texMaxT, x, y, RtTrackHeightL(&trkpos) + seg->height);
break;
case 1:
trkpos.toRight = 0 ;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, texMaxT, x, y, RtTrackHeightL(&trkpos) + seg->height);
SETPOINT(texLen, texMaxT, x, y, RtTrackHeightL(&trkpos));
break;
case 2:
break;
}
break;
case TR_WALL:
switch (j) {
case 0:
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0, x, y, RtTrackHeightL(&trkpos));
SETPOINT(texLen, 0.33, x, y, RtTrackHeightL(&trkpos) + seg->height);
break;
case 1:
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.33, x, y, RtTrackHeightL(&trkpos) + seg->height);
trkpos.toRight = 0 ;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.66, x, y, RtTrackHeightL(&trkpos) + seg->height);
break;
case 2:
trkpos.toRight = 0 ;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.66, x, y, RtTrackHeightL(&trkpos) + seg->height);
SETPOINT(texLen, 1.0, x, y, RtTrackHeightL(&trkpos));
break;
}
break;
}
ts += LMAX;
texLen += texStep;
}
ts = seg->length;
break;
case TR_LFT:
step = LMAX / (mseg->radiusr);
texStep = step * mseg->radius / curTexSize;
anz = seg->angle[TR_ZS] + step;
ts = step;
texLen += texStep;
radiusr = seg->radiusr;
radiusl = seg->radiusl;
trkpos.seg = seg;
while (anz < seg->angle[TR_ZE]) {
trkpos.toStart = ts;
width = RtTrackGetWidth(seg, ts);
texMaxT = (curTexType == 1 ? width / curTexSize : 1.0 + floor(width / curTexSize));
switch (seg->style) {
case TR_PLAN:
if (j == 0) {
/* left */
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0, x, y, RtTrackHeightL(&trkpos));
/* right */
trkpos.toRight = 0;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, texMaxT, x, y, RtTrackHeightL(&trkpos));
}
break;
case TR_CURB:
switch (j) {
case 0:
/* left */
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0, x, y, RtTrackHeightL(&trkpos));
/* right */
trkpos.toRight = 0;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, texMaxT, x, y, RtTrackHeightL(&trkpos) + seg->height);
break;
case 1:
trkpos.toRight = 0;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, texMaxT, x, y, RtTrackHeightL(&trkpos) + seg->height);
SETPOINT(texLen, texMaxT, x, y, RtTrackHeightL(&trkpos));
break;
case 2:
break;
}
break;
case TR_WALL:
switch (j) {
case 0:
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0, x, y, RtTrackHeightL(&trkpos));
SETPOINT(texLen, 0.33, x, y, RtTrackHeightL(&trkpos) + seg->height);
break;
case 1:
/* left */
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.33, x, y, RtTrackHeightL(&trkpos) + seg->height);
/* right */
trkpos.toRight = 0;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.66, x, y, RtTrackHeightL(&trkpos) + seg->height);
break;
case 2:
trkpos.toRight = 0;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.66, x, y, RtTrackHeightL(&trkpos) + seg->height);
SETPOINT(texLen, 1.0, x, y, RtTrackHeightL(&trkpos));
break;
}
break;
}
ts += step;
texLen += texStep;
anz += step;
}
ts = seg->arc;
break;
case TR_RGT:
step = LMAX / (mseg->radiusl);
texStep = step * mseg->radius / curTexSize;
anz = seg->angle[TR_ZS] - step;
ts = step;
texLen += texStep;
radiusr = seg->radiusr;
radiusl = seg->radiusl;
trkpos.seg = seg;
while (anz > seg->angle[TR_ZE]) {
trkpos.toStart = ts;
width = RtTrackGetWidth(seg, ts);
texMaxT = (curTexType == 1 ? width / curTexSize : 1.0 + floor(width / curTexSize));
switch (seg->style) {
case TR_PLAN:
if (j == 0) {
/* left */
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0, x, y, RtTrackHeightL(&trkpos));
/* right */
trkpos.toRight = 0;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, texMaxT, x, y, RtTrackHeightL(&trkpos));
}
break;
case TR_CURB:
switch (j) {
case 0:
/* left */
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0, x, y, RtTrackHeightL(&trkpos));
/* right */
trkpos.toRight = 0;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, texMaxT, x, y, RtTrackHeightL(&trkpos) + seg->height);
break;
case 1:
trkpos.toRight = 0;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, texMaxT, x, y, RtTrackHeightL(&trkpos) + seg->height);
SETPOINT(texLen, texMaxT, x, y, RtTrackHeightL(&trkpos));
break;
case 2:
break;
}
break;
case TR_WALL:
switch (j) {
case 0:
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0, x, y, RtTrackHeightL(&trkpos));
SETPOINT(texLen, 0.33, x, y, RtTrackHeightL(&trkpos) + seg->height);
break;
case 1:
/* left */
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.33, x, y, RtTrackHeightL(&trkpos) + seg->height);
/* right */
trkpos.toRight = 0;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.66, x, y, RtTrackHeightL(&trkpos) + seg->height);
break;
case 2:
trkpos.toRight = 0;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.66, x, y, RtTrackHeightL(&trkpos) + seg->height);
SETPOINT(texLen, 1.0, x, y, RtTrackHeightL(&trkpos));
break;
}
break;
}
ts += step;
texLen += texStep;
anz -= step;
}
ts = seg->arc;
break;
}
texLen = (curTexSeg + mseg->length) / curTexSize;
switch (seg->style) {
case TR_PLAN:
if (j == 0) {
width = RtTrackGetWidth(seg, ts);
texMaxT = (curTexType == 1 ? width / curTexSize : 1.0 + floor(width / curTexSize));
SETPOINT(texLen, 0, seg->vertex[TR_EL].x, seg->vertex[TR_EL].y, seg->vertex[TR_EL].z);
SETPOINT(texLen, texMaxT, seg->vertex[TR_ER].x, seg->vertex[TR_ER].y, seg->vertex[TR_ER].z);
}
break;
case TR_CURB:
switch (j) {
case 0:
width = RtTrackGetWidth(seg, ts);
texMaxT = (curTexType == 1 ? width / curTexSize : 1.0 + floor(width / curTexSize));
SETPOINT(texLen, 0, seg->vertex[TR_EL].x, seg->vertex[TR_EL].y, seg->vertex[TR_EL].z);
SETPOINT(texLen, texMaxT, seg->vertex[TR_ER].x, seg->vertex[TR_ER].y, seg->vertex[TR_ER].z + seg->height);
if (mseg->next->rside && ((mseg->next->rside->type2 != TR_RBORDER) || (mseg->next->rside->style != TR_CURB))) {
SETPOINT(texLen, 0, seg->vertex[TR_EL].x, seg->vertex[TR_EL].y, seg->vertex[TR_EL].z - 0.1);
SETPOINT(texLen, texMaxT, seg->vertex[TR_ER].x, seg->vertex[TR_ER].y, seg->vertex[TR_ER].z);
}
break;
case 1:
width = RtTrackGetWidth(seg, ts);
texMaxT = (curTexType == 1 ? width / curTexSize : 1.0 + floor(width / curTexSize));
SETPOINT(texLen, texMaxT, seg->vertex[TR_ER].x, seg->vertex[TR_ER].y, seg->vertex[TR_ER].z + seg->height);
SETPOINT(texLen, texMaxT, seg->vertex[TR_ER].x, seg->vertex[TR_ER].y, seg->vertex[TR_ER].z);
break;
case 2:
break;
}
break;
case TR_WALL:
switch (j) {
case 0:
SETPOINT(texLen, 0, seg->vertex[TR_EL].x, seg->vertex[TR_EL].y, seg->vertex[TR_EL].z);
SETPOINT(texLen, 0.33, seg->vertex[TR_EL].x, seg->vertex[TR_EL].y, seg->vertex[TR_EL].z + seg->height);
break;
case 1:
SETPOINT(texLen, 0.33, seg->vertex[TR_EL].x, seg->vertex[TR_EL].y, seg->vertex[TR_EL].z + seg->height);
SETPOINT(texLen, 0.66, seg->vertex[TR_ER].x, seg->vertex[TR_ER].y, seg->vertex[TR_ER].z + seg->height);
break;
case 2:
SETPOINT(texLen, 0.66, seg->vertex[TR_ER].x, seg->vertex[TR_ER].y, seg->vertex[TR_ER].z + seg->height);
SETPOINT(texLen, 1.0, seg->vertex[TR_ER].x, seg->vertex[TR_ER].y, seg->vertex[TR_ER].z);
if (mseg->next->rside && ((mseg->next->rside->type2 != TR_RBORDER) || (mseg->next->rside->style != TR_WALL))) {
SETPOINT(texLen + seg->width/curTexSize, 0.66, seg->vertex[TR_EL].x, seg->vertex[TR_EL].y, seg->vertex[TR_EL].z + seg->height);
SETPOINT(texLen + seg->width/curTexSize, 1.00, seg->vertex[TR_EL].x, seg->vertex[TR_EL].y, seg->vertex[TR_EL].z);
}
break;
}
break;
}
startNeeded = 0;
runninglentgh += seg->length;
} else {
startNeeded = 1;
}
}
}
/* Right Side */
prevTexId = 0;
texLen = 0;
startNeeded = 1;
runninglentgh = 0;
hasBorder = 0;
for (i = 0, mseg = Track->seg->next; i < Track->nseg; i++, mseg = mseg->next) {
if ((mseg->rside != NULL) &&
((mseg->rside->type2 == TR_RSIDE) || (mseg->rside->rside != NULL))) {
seg = mseg->rside;
if (seg->rside != NULL) {
seg = seg->rside;
if (hasBorder == 0) {
startNeeded = 1;
hasBorder = 1;
}
} else {
if (hasBorder) {
startNeeded = 1;
hasBorder = 0;
}
}
CHECKDISPLIST(seg->surface->material, "tkRS", i, mseg->lgfromstart);
if (!curTexLink) {
curTexSeg = 0;
} else {
curTexSeg = mseg->lgfromstart;
}
curTexSeg += curTexOffset;
texLen = curTexSeg / curTexSize;
if (startNeeded || (runninglentgh > LG_STEP_MAX)) {
NEWDISPLIST(0, "tkRS", i);
runninglentgh = 0;
ts = 0;
width = RtTrackGetWidth(seg, ts);
texMaxT = (curTexType == 1 ? width / curTexSize : 1.0 + floor(width / curTexSize));
SETPOINT(texLen, 0, seg->vertex[TR_SL].x, seg->vertex[TR_SL].y, seg->vertex[TR_SL].z);
SETPOINT(texLen, texMaxT, seg->vertex[TR_SR].x, seg->vertex[TR_SR].y, seg->vertex[TR_SR].z);
}
switch (seg->type) {
case TR_STR:
ts = LMAX;
texStep = LMAX / curTexSize;
texLen += texStep;
trkpos.seg = seg;
while (ts < seg->length) {
trkpos.toStart = ts;
width = RtTrackGetWidth(seg, ts);
texMaxT = (curTexType == 1 ? width / curTexSize : 1.0 + floor(width / curTexSize));
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0, x, y, RtTrackHeightL(&trkpos));
trkpos.toRight = 0 ;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, texMaxT, x, y, RtTrackHeightL(&trkpos));
ts += LMAX;
texLen += texStep;
}
ts = seg->length;
break;
case TR_LFT:
step = LMAX / (mseg->radiusr);
texStep = step * mseg->radius / curTexSize;
anz = seg->angle[TR_ZS] + step;
ts = step;
texLen += texStep;
radiusr = seg->radiusr;
radiusl = seg->radiusl;
trkpos.seg = seg;
while (anz < seg->angle[TR_ZE]) {
trkpos.toStart = ts;
width = RtTrackGetWidth(seg, ts);
texMaxT = (curTexType == 1 ? width / curTexSize : 1.0 + floor(width / curTexSize));
/* left */
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0, x, y, RtTrackHeightL(&trkpos));
/* right */
trkpos.toRight = 0;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, texMaxT, x, y, RtTrackHeightL(&trkpos));
ts += step;
texLen += texStep;
anz += step;
}
ts = seg->arc;
break;
case TR_RGT:
step = LMAX / (mseg->radiusl);
texStep = step * mseg->radius / curTexSize;
anz = seg->angle[TR_ZS] - step;
ts = step;
texLen += texStep;
radiusr = seg->radiusr;
radiusl = seg->radiusl;
trkpos.seg = seg;
while (anz > seg->angle[TR_ZE]) {
trkpos.toStart = ts;
width = RtTrackGetWidth(seg, ts);
texMaxT = (curTexType == 1 ? width / curTexSize : 1.0 + floor(width / curTexSize));
/* left */
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0, x, y, RtTrackHeightL(&trkpos));
/* right */
trkpos.toRight = 0;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, texMaxT, x, y, RtTrackHeightL(&trkpos));
ts += step;
texLen += texStep;
anz -= step;
}
ts = seg->arc;
break;
}
texLen = (curTexSeg + mseg->length) / curTexSize;
width = RtTrackGetWidth(seg, ts);
texMaxT = (curTexType == 1 ? width / curTexSize : 1.0 + floor(width / curTexSize));
SETPOINT(texLen, 0, seg->vertex[TR_EL].x, seg->vertex[TR_EL].y, seg->vertex[TR_EL].z);
SETPOINT(texLen, texMaxT, seg->vertex[TR_ER].x, seg->vertex[TR_ER].y, seg->vertex[TR_ER].z);
startNeeded = 0;
runninglentgh += seg->length;
} else {
startNeeded = 1;
}
}
/* Left Border */
for (j = 0; j < 3; j++) {
prevTexId = 0;
texLen = 0;
startNeeded = 1;
runninglentgh = 0;
sprintf(sname, "t%dLB", j);
for (i = 0, mseg = Track->seg->next; i < Track->nseg; i++, mseg = mseg->next) {
if ((mseg->lside != NULL) && (mseg->lside->type2 == TR_LBORDER)) {
seg = mseg->lside;
CHECKDISPLIST(seg->surface->material, sname, i, mseg->lgfromstart);
if (!curTexLink) {
curTexSeg = 0;
} else {
curTexSeg = mseg->lgfromstart;
}
curTexSeg += curTexOffset;
texLen = curTexSeg / curTexSize;
if (startNeeded || (runninglentgh > LG_STEP_MAX)) {
NEWDISPLIST(0, sname, i);
runninglentgh = 0;
ts = 0;
width = RtTrackGetWidth(seg, ts);
texMaxT = (curTexType == 1 ? width / curTexSize : 1.0 + floor(width / curTexSize));
switch (seg->style) {
case TR_PLAN:
if (j == 0) {
SETPOINT(texLen, texMaxT, seg->vertex[TR_SL].x, seg->vertex[TR_SL].y, seg->vertex[TR_SL].z);
SETPOINT(texLen, 0, seg->vertex[TR_SR].x, seg->vertex[TR_SR].y, seg->vertex[TR_SR].z);
}
break;
case TR_CURB:
switch (j) {
case 0:
SETPOINT(texLen, texMaxT, seg->vertex[TR_SL].x, seg->vertex[TR_SL].y, seg->vertex[TR_SL].z);
SETPOINT(texLen, texMaxT, seg->vertex[TR_SL].x, seg->vertex[TR_SL].y, seg->vertex[TR_SL].z + seg->height);
break;
case 1:
if (!mseg->prev->rside || (mseg->prev->rside->type2 != TR_RBORDER) || (mseg->prev->rside->style != TR_CURB)) {
SETPOINT(texLen, texMaxT, seg->vertex[TR_SL].x, seg->vertex[TR_SL].y, seg->vertex[TR_SL].z);
SETPOINT(texLen, 0, seg->vertex[TR_SR].x, seg->vertex[TR_SR].y, seg->vertex[TR_SR].z - 0.1);
}
SETPOINT(texLen, texMaxT, seg->vertex[TR_SL].x, seg->vertex[TR_SL].y, seg->vertex[TR_SL].z + seg->height);
SETPOINT(texLen, 0, seg->vertex[TR_SR].x, seg->vertex[TR_SR].y, seg->vertex[TR_SR].z);
break;
case 2:
break;
}
break;
case TR_WALL:
switch (j) {
case 0:
if (!mseg->prev->rside || (mseg->prev->rside->type2 != TR_RBORDER) || (mseg->prev->rside->style != TR_WALL)) {
SETPOINT(texLen - seg->width/curTexSize, 1.00, seg->vertex[TR_SR].x, seg->vertex[TR_SR].y, seg->vertex[TR_SR].z);
SETPOINT(texLen - seg->width/curTexSize, 0.66, seg->vertex[TR_SR].x, seg->vertex[TR_SR].y, seg->vertex[TR_SR].z + seg->height);
}
SETPOINT(texLen, 1.0, seg->vertex[TR_SL].x, seg->vertex[TR_SL].y, seg->vertex[TR_SL].z);
SETPOINT(texLen, 0.66, seg->vertex[TR_SL].x, seg->vertex[TR_SL].y, seg->vertex[TR_SL].z + seg->height);
break;
case 1:
SETPOINT(texLen, 0.66, seg->vertex[TR_SL].x, seg->vertex[TR_SL].y, seg->vertex[TR_SL].z + seg->height);
SETPOINT(texLen, 0.33, seg->vertex[TR_SR].x, seg->vertex[TR_SR].y, seg->vertex[TR_SR].z + seg->height);
break;
case 2:
SETPOINT(texLen, 0.33, seg->vertex[TR_SR].x, seg->vertex[TR_SR].y, seg->vertex[TR_SR].z + seg->height);
SETPOINT(texLen, 0.0, seg->vertex[TR_SR].x, seg->vertex[TR_SR].y, seg->vertex[TR_SR].z);
break;
}
break;
}
}
switch (seg->type) {
case TR_STR:
ts = LMAX;
texStep = LMAX / curTexSize;
texLen += texStep;
trkpos.seg = seg;
while (ts < seg->length) {
trkpos.toStart = ts;
width = RtTrackGetWidth(seg, ts);
texMaxT = (curTexType == 1 ? width / curTexSize : 1.0 + floor(width / curTexSize));
switch (seg->style) {
case TR_PLAN:
if (j == 0) {
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, texMaxT, x, y, RtTrackHeightL(&trkpos));
trkpos.toRight = 0;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0, x, y, RtTrackHeightL(&trkpos));
}
break;
case TR_CURB:
switch (j) {
case 0:
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, texMaxT, x, y, RtTrackHeightL(&trkpos));
SETPOINT(texLen, texMaxT, x, y, RtTrackHeightL(&trkpos) + seg->height);
break;
case 1:
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, texMaxT, x, y, RtTrackHeightL(&trkpos) + seg->height);
trkpos.toRight = 0;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0, x, y, RtTrackHeightL(&trkpos));
break;
case 2:
break;
}
break;
case TR_WALL:
switch (j) {
case 0:
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 1.0, x, y, RtTrackHeightL(&trkpos));
SETPOINT(texLen, 0.66, x, y, RtTrackHeightL(&trkpos) + seg->height);
break;
case 1:
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.66, x, y, RtTrackHeightL(&trkpos) + seg->height);
trkpos.toRight = 0;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.33, x, y, RtTrackHeightL(&trkpos) + seg->height);
break;
case 2:
trkpos.toRight = 0;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.33, x, y, RtTrackHeightL(&trkpos) + seg->height);
SETPOINT(texLen, 0.0, x, y, RtTrackHeightL(&trkpos));
break;
}
break;
}
ts += LMAX;
texLen += texStep;
}
ts = seg->length;
break;
case TR_LFT:
step = LMAX / (mseg->radiusr);
texStep = step * mseg->radius / curTexSize;
anz = seg->angle[TR_ZS] + step;
ts = step;
texLen += texStep;
radiusr = seg->radiusr;
radiusl = seg->radiusl;
trkpos.seg = seg;
while (anz < seg->angle[TR_ZE]) {
trkpos.toStart = ts;
width = RtTrackGetWidth(seg, ts);
texMaxT = (curTexType == 1 ? width / curTexSize : 1.0 + floor(width / curTexSize));
switch (seg->style) {
case TR_PLAN:
if (j == 0) {
/* left */
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, texMaxT, x, y, RtTrackHeightL(&trkpos));
/* right */
trkpos.toRight = 0;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0, x, y, RtTrackHeightL(&trkpos));
}
break;
case TR_CURB:
switch (j) {
case 0:
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, texMaxT, x, y, RtTrackHeightL(&trkpos));
SETPOINT(texLen, texMaxT, x, y, RtTrackHeightL(&trkpos) + seg->height);
break;
case 1:
/* left */
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, texMaxT, x, y, RtTrackHeightL(&trkpos) + seg->height);
/* right */
trkpos.toRight = 0;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0, x, y, RtTrackHeightL(&trkpos));
break;
case 2:
break;
}
break;
case TR_WALL:
switch (j) {
case 0:
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 1.0, x, y, RtTrackHeightL(&trkpos));
SETPOINT(texLen, 0.66, x, y, RtTrackHeightL(&trkpos) + seg->height);
break;
case 1:
/* left */
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.66, x, y, RtTrackHeightL(&trkpos) + seg->height);
/* right */
trkpos.toRight = 0;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.33, x, y, RtTrackHeightL(&trkpos) + seg->height);
break;
case 2:
trkpos.toRight = 0;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.33, x, y, RtTrackHeightL(&trkpos) + seg->height);
SETPOINT(texLen, 0.0, x, y, RtTrackHeightL(&trkpos));
break;
}
break;
}
ts += step;
texLen += texStep;
anz += step;
}
ts = seg->arc;
break;
case TR_RGT:
step = LMAX / (mseg->radiusl);
texStep = step * mseg->radius / curTexSize;
anz = seg->angle[TR_ZS] - step;
ts = step;
texLen += texStep;
radiusr = seg->radiusr;
radiusl = seg->radiusl;
trkpos.seg = seg;
while (anz > seg->angle[TR_ZE]) {
trkpos.toStart = ts;
width = RtTrackGetWidth(seg, ts);
texMaxT = (curTexType == 1 ? width / curTexSize : 1.0 + floor(width / curTexSize));
switch (seg->style) {
case TR_PLAN:
if (j == 0) {
/* left */
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, texMaxT, x, y, RtTrackHeightL(&trkpos));
/* right */
trkpos.toRight = 0;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0, x, y, RtTrackHeightL(&trkpos));
}
break;
case TR_CURB:
switch (j) {
case 0:
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, texMaxT, x, y, RtTrackHeightL(&trkpos));
SETPOINT(texLen, texMaxT, x, y, RtTrackHeightL(&trkpos) + seg->height);
break;
case 1:
/* left */
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, texMaxT, x, y, RtTrackHeightL(&trkpos) + seg->height);
/* right */
trkpos.toRight = 0;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0, x, y, RtTrackHeightL(&trkpos));
break;
case 2:
break;
}
break;
case TR_WALL:
switch (j) {
case 0:
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 1.0, x, y, RtTrackHeightL(&trkpos));
SETPOINT(texLen, 0.66, x, y, RtTrackHeightL(&trkpos) + seg->height);
break;
case 1:
/* left */
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.66, x, y, RtTrackHeightL(&trkpos) + seg->height);
/* right */
trkpos.toRight = 0;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.33, x, y, RtTrackHeightL(&trkpos) + seg->height);
break;
case 2:
trkpos.toRight = 0;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.33, x, y, RtTrackHeightL(&trkpos) + seg->height);
SETPOINT(texLen, 0.0, x, y, RtTrackHeightL(&trkpos));
break;
}
break;
}
ts += step;
texLen += texStep;
anz -= step;
}
ts = seg->arc;
break;
}
texLen = (curTexSeg + mseg->length) / curTexSize;
width = RtTrackGetWidth(seg, ts);
texMaxT = (curTexType == 1 ? width / curTexSize : 1.0 + floor(width / curTexSize));
switch (seg->style) {
case TR_PLAN:
if (j == 0) {
SETPOINT(texLen, texMaxT, seg->vertex[TR_EL].x, seg->vertex[TR_EL].y, seg->vertex[TR_EL].z);
SETPOINT(texLen, 0, seg->vertex[TR_ER].x, seg->vertex[TR_ER].y, seg->vertex[TR_ER].z);
}
break;
case TR_CURB:
switch (j) {
case 0:
SETPOINT(texLen, texMaxT, seg->vertex[TR_EL].x, seg->vertex[TR_EL].y, seg->vertex[TR_EL].z);
SETPOINT(texLen, texMaxT, seg->vertex[TR_EL].x, seg->vertex[TR_EL].y, seg->vertex[TR_EL].z + seg->height);
break;
case 1:
SETPOINT(texLen, texMaxT, seg->vertex[TR_EL].x, seg->vertex[TR_EL].y, seg->vertex[TR_EL].z + seg->height);
SETPOINT(texLen, 0, seg->vertex[TR_ER].x, seg->vertex[TR_ER].y, seg->vertex[TR_ER].z);
if (mseg->next->lside && ((mseg->next->lside->type2 != TR_LBORDER) || (mseg->next->lside->style != TR_CURB))) {
SETPOINT(texLen, texMaxT, seg->vertex[TR_EL].x, seg->vertex[TR_EL].y, seg->vertex[TR_EL].z);
SETPOINT(texLen, 0, seg->vertex[TR_ER].x, seg->vertex[TR_ER].y, seg->vertex[TR_ER].z - 0.1);
}
break;
case 2:
break;
}
break;
case TR_WALL:
switch (j) {
case 0:
SETPOINT(texLen, 1.0, seg->vertex[TR_EL].x, seg->vertex[TR_EL].y, seg->vertex[TR_EL].z);
SETPOINT(texLen, 0.66, seg->vertex[TR_EL].x, seg->vertex[TR_EL].y, seg->vertex[TR_EL].z + seg->height);
if (mseg->next->lside && ((mseg->next->lside->type2 != TR_LBORDER) || (mseg->next->lside->style != TR_WALL))) {
SETPOINT(texLen + seg->width/curTexSize, 1.00, seg->vertex[TR_ER].x, seg->vertex[TR_ER].y, seg->vertex[TR_ER].z);
SETPOINT(texLen + seg->width/curTexSize, 0.66, seg->vertex[TR_ER].x, seg->vertex[TR_ER].y, seg->vertex[TR_ER].z + seg->height);
}
break;
case 1:
SETPOINT(texLen, 0.66, seg->vertex[TR_EL].x, seg->vertex[TR_EL].y, seg->vertex[TR_EL].z + seg->height);
SETPOINT(texLen, 0.33, seg->vertex[TR_ER].x, seg->vertex[TR_ER].y, seg->vertex[TR_ER].z + seg->height);
break;
case 2:
SETPOINT(texLen, 0.33, seg->vertex[TR_ER].x, seg->vertex[TR_ER].y, seg->vertex[TR_ER].z + seg->height);
SETPOINT(texLen, 0.0, seg->vertex[TR_ER].x, seg->vertex[TR_ER].y, seg->vertex[TR_ER].z);
break;
}
break;
}
startNeeded = 0;
runninglentgh += seg->length;
} else {
startNeeded = 1;
}
}
}
/* Left Side */
prevTexId = 0;
texLen = 0;
startNeeded = 1;
runninglentgh = 0;
hasBorder = 0;
for (i = 0, mseg = Track->seg->next; i < Track->nseg; i++, mseg = mseg->next) {
if ((mseg->lside != NULL) &&
((mseg->lside->type2 == TR_LSIDE) || (mseg->lside->lside != NULL))) {
seg = mseg->lside;
if (seg->lside) {
seg = seg->lside;
if (hasBorder == 0) {
startNeeded = 1;
hasBorder = 1;
}
} else {
if (hasBorder) {
startNeeded = 1;
hasBorder = 0;
}
}
CHECKDISPLIST(seg->surface->material, "tkLS", i, mseg->lgfromstart);
if (!curTexLink) {
curTexSeg = 0;
} else {
curTexSeg = mseg->lgfromstart;
}
curTexSeg += curTexOffset;
texLen = curTexSeg / curTexSize;
if (startNeeded || (runninglentgh > LG_STEP_MAX)) {
NEWDISPLIST(0, "tkLS", i);
runninglentgh = 0;
ts = 0;
width = RtTrackGetWidth(seg, ts);
texMaxT = (curTexType == 1 ? width / curTexSize : 1.0 + floor(width / curTexSize));
SETPOINT(texLen, texMaxT, seg->vertex[TR_SL].x, seg->vertex[TR_SL].y, seg->vertex[TR_SL].z);
SETPOINT(texLen, 0, seg->vertex[TR_SR].x, seg->vertex[TR_SR].y, seg->vertex[TR_SR].z);
}
switch (seg->type) {
case TR_STR:
ts = LMAX;
texStep = LMAX / curTexSize;
texLen += texStep;
trkpos.seg = seg;
while (ts < seg->length) {
trkpos.toStart = ts;
width = RtTrackGetWidth(seg, ts);
texMaxT = (curTexType == 1 ? width / curTexSize : 1.0 + floor(width / curTexSize));
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, texMaxT, x, y, RtTrackHeightL(&trkpos));
trkpos.toRight = 0;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0, x, y, RtTrackHeightL(&trkpos));
ts += LMAX;
texLen += texStep;
}
ts = seg->length;
break;
case TR_LFT:
step = LMAX / (mseg->radiusr);
texStep = step * mseg->radius / curTexSize;
anz = seg->angle[TR_ZS] + step;
ts = step;
texLen += texStep;
radiusr = seg->radiusr;
radiusl = seg->radiusl;
trkpos.seg = seg;
while (anz < seg->angle[TR_ZE]) {
trkpos.toStart = ts;
width = RtTrackGetWidth(seg, ts);
texMaxT = (curTexType == 1 ? width / curTexSize : 1.0 + floor(width / curTexSize));
/* left */
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, texMaxT, x, y, RtTrackHeightL(&trkpos));
/* right */
trkpos.toRight = 0;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0, x, y, RtTrackHeightL(&trkpos));
ts += step;
texLen += texStep;
anz += step;
}
ts = seg->arc;
break;
case TR_RGT:
step = LMAX / (mseg->radiusl);
texStep = step * mseg->radius / curTexSize;
anz = seg->angle[TR_ZS] - step;
ts = step;
texLen += texStep;
radiusr = seg->radiusr;
radiusl = seg->radiusl;
trkpos.seg = seg;
while (anz > seg->angle[TR_ZE]) {
trkpos.toStart = ts;
width = RtTrackGetWidth(seg, ts);
texMaxT = (curTexType == 1 ? width / curTexSize : 1.0 + floor(width / curTexSize));
/* left */
trkpos.toRight = width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, texMaxT, x, y, RtTrackHeightL(&trkpos));
/* right */
trkpos.toRight = 0;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0, x, y, RtTrackHeightL(&trkpos));
ts += step;
texLen += texStep;
anz -= step;
}
ts = seg->arc;
break;
}
texLen = (curTexSeg + mseg->length) / curTexSize;
width = RtTrackGetWidth(seg, ts);
texMaxT = (curTexType == 1 ? width / curTexSize : 1.0 + floor(width / curTexSize));
SETPOINT(texLen, texMaxT, seg->vertex[TR_EL].x, seg->vertex[TR_EL].y, seg->vertex[TR_EL].z);
SETPOINT(texLen, 0, seg->vertex[TR_ER].x, seg->vertex[TR_ER].y, seg->vertex[TR_ER].z);
startNeeded = 0;
runninglentgh += seg->length;
} else {
startNeeded = 1;
}
}
/* Right barrier */
for (j = 0; j < 3; j++) {
prevTexId = 0;
texLen = 0;
startNeeded = 1;
runninglentgh = 0;
sprintf(sname, "B%dRt", j);
for (i = 0, mseg = Track->seg->next; i < Track->nseg; i++, mseg = mseg->next) {
if ((mseg->rside != NULL) && (mseg->rside->raceInfo & TR_PIT)) {
startNeeded = 1;
runninglentgh = 0;
NEWDISPLIST(0, sname, i);
} else {
curBarrier = mseg->barrier[0];
CHECKDISPLIST(curBarrier->surface->material, sname, i, 0);
if (!curTexLink) {
curTexSeg = 0;
} else {
curTexSeg = mseg->lgfromstart;
}
texLen = curTexSeg / curTexSize;
if (mseg->rside) {
seg = mseg->rside;
if (seg->rside) {
seg = seg->rside;
}
} else {
seg = mseg;
}
trkpos.seg = seg;
if (startNeeded || (runninglentgh > LG_STEP_MAX)) {
NEWDISPLIST(0, sname, i);
if (curTexType == 0) texLen = 0;
runninglentgh = 0;
switch (curBarrier->style) {
case TR_FENCE:
if (j == 0) {
SETPOINT(texLen, 0, seg->vertex[TR_SR].x, seg->vertex[TR_SR].y, seg->vertex[TR_SR].z);
SETPOINT(texLen, 1.0, seg->vertex[TR_SR].x, seg->vertex[TR_SR].y, seg->vertex[TR_SR].z + curBarrier->height);
}
break;
case TR_WALL:
switch (j) {
case 0:
SETPOINT(texLen, 0, seg->vertex[TR_SR].x, seg->vertex[TR_SR].y, seg->vertex[TR_SR].z);
SETPOINT(texLen, 0.33, seg->vertex[TR_SR].x, seg->vertex[TR_SR].y, seg->vertex[TR_SR].z + curBarrier->height);
break;
case 1:
trkpos.toStart = 0;
trkpos.toRight = -curBarrier->width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.33, seg->vertex[TR_SR].x, seg->vertex[TR_SR].y, seg->vertex[TR_SR].z + curBarrier->height);
SETPOINT(texLen, 0.66, x, y, seg->vertex[TR_SR].z + curBarrier->height);
break;
case 2:
trkpos.toStart = 0;
trkpos.toRight = -curBarrier->width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
if ((mseg->prev->barrier[0]->style != TR_WALL) || (mseg->prev->barrier[0]->height != curBarrier->height)) {
SETPOINT(texLen - curBarrier->width/curTexSize, 0.66, seg->vertex[TR_SR].x, seg->vertex[TR_SR].y, seg->vertex[TR_SR].z + curBarrier->height);
SETPOINT(texLen - curBarrier->width/curTexSize, 1.00, seg->vertex[TR_SR].x, seg->vertex[TR_SR].y, seg->vertex[TR_SR].z);
}
SETPOINT(texLen, 0.66, x, y, seg->vertex[TR_SR].z + curBarrier->height);
SETPOINT(texLen, 1.0, x, y, seg->vertex[TR_SR].z);
break;
}
break;
}
}
switch (seg->type) {
case TR_STR:
ts = LMAX;
texStep = LMAX / curTexSize;
texLen += texStep;
trkpos.seg = seg;
while (ts < seg->length) {
trkpos.toStart = ts;
trkpos.toRight = 0;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
curHeight = RtTrackHeightL(&trkpos);
switch (curBarrier->style) {
case TR_FENCE:
if (j == 0) {
SETPOINT(texLen, 0, x, y, curHeight);
SETPOINT(texLen, 1.0, x, y, curHeight + curBarrier->height);
}
break;
case TR_WALL:
switch (j) {
case 0:
SETPOINT(texLen, 0.0, x, y, curHeight);
SETPOINT(texLen, 0.33, x, y, curHeight + curBarrier->height);
break;
case 1:
SETPOINT(texLen, 0.33, x, y, curHeight + curBarrier->height);
trkpos.toRight = -curBarrier->width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.66, x, y, curHeight + curBarrier->height);
break;
case 2:
trkpos.toRight = -curBarrier->width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.66, x, y, curHeight + curBarrier->height);
SETPOINT(texLen, 1.0, x, y, curHeight);
break;
}
break;
}
ts += LMAX;
texLen += texStep;
}
ts = seg->length;
break;
case TR_LFT:
step = LMAX / (mseg->radiusr);
texStep = step * mseg->radius / curTexSize;
anz = seg->angle[TR_ZS] + step;
ts = step;
texLen += texStep;
radiusr = seg->radiusr;
trkpos.seg = seg;
while (anz < seg->angle[TR_ZE]) {
trkpos.toStart = ts;
trkpos.toRight = 0;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
curHeight = RtTrackHeightL(&trkpos);
switch (curBarrier->style) {
case TR_FENCE:
if (j == 0) {
SETPOINT(texLen, 0.0, x, y, curHeight);
SETPOINT(texLen, 1.0, x, y, curHeight + curBarrier->height);
}
break;
case TR_WALL:
switch (j) {
case 0:
SETPOINT(texLen, 0.0, x, y, curHeight);
SETPOINT(texLen, 0.33, x, y, curHeight + curBarrier->height);
break;
case 1:
SETPOINT(texLen, 0.33, x, y, curHeight + curBarrier->height);
trkpos.toRight = -curBarrier->width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.66, x, y, curHeight + curBarrier->height);
break;
case 2:
trkpos.toRight = -curBarrier->width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.66, x, y, curHeight + curBarrier->height);
SETPOINT(texLen, 1.0, x, y, curHeight);
break;
}
break;
}
ts += step;
texLen += texStep;
anz += step;
}
ts = seg->arc;
break;
case TR_RGT:
step = LMAX / (mseg->radiusl);
texStep = step * mseg->radius / curTexSize;
anz = seg->angle[TR_ZS] - step;
ts = step;
texLen += texStep;
radiusr = seg->radiusr;
trkpos.seg = seg;
while (anz > seg->angle[TR_ZE]) {
trkpos.toStart = ts;
trkpos.toRight = 0;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
curHeight = RtTrackHeightL(&trkpos);
switch (curBarrier->style) {
case TR_FENCE:
if (j == 0) {
SETPOINT(texLen, 0.0, x, y, curHeight);
SETPOINT(texLen, 1.0, x, y, curHeight + curBarrier->height);
}
break;
case TR_WALL:
switch (j) {
case 0:
SETPOINT(texLen, 0.0, x, y, curHeight);
SETPOINT(texLen, 0.33, x, y, curHeight + curBarrier->height);
break;
case 1:
SETPOINT(texLen, 0.33, x, y, curHeight + curBarrier->height);
trkpos.toRight = -curBarrier->width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.66, x, y, curHeight + curBarrier->height);
break;
case 2:
trkpos.toRight = -curBarrier->width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.66, x, y, curHeight + curBarrier->height);
SETPOINT(texLen, 1.0, x, y, curHeight);
break;
}
break;
}
ts += step;
texLen += texStep;
anz -= step;
}
ts = seg->arc;
break;
}
texLen = (curTexSeg + mseg->length) / curTexSize;
switch (curBarrier->style) {
case TR_FENCE:
if (j == 0) {
SETPOINT(texLen, 0.0, seg->vertex[TR_ER].x, seg->vertex[TR_ER].y, seg->vertex[TR_ER].z);
SETPOINT(texLen, 1.0, seg->vertex[TR_ER].x, seg->vertex[TR_ER].y, seg->vertex[TR_ER].z + curBarrier->height);
}
break;
case TR_WALL:
switch (j) {
case 0:
SETPOINT(texLen, 0.0, seg->vertex[TR_ER].x, seg->vertex[TR_ER].y, seg->vertex[TR_ER].z);
SETPOINT(texLen, 0.33, seg->vertex[TR_ER].x, seg->vertex[TR_ER].y, seg->vertex[TR_ER].z + curBarrier->height);
break;
case 1:
SETPOINT(texLen, 0.33, seg->vertex[TR_ER].x, seg->vertex[TR_ER].y, seg->vertex[TR_ER].z + curBarrier->height);
trkpos.toStart = ts;
trkpos.toRight = -curBarrier->width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.66, x, y, seg->vertex[TR_ER].z + curBarrier->height);
break;
case 2:
trkpos.toStart = ts;
trkpos.toRight = -curBarrier->width;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.66, x, y, seg->vertex[TR_ER].z + curBarrier->height);
SETPOINT(texLen, 1.00, x, y, seg->vertex[TR_ER].z);
if ((mseg->next->barrier[0]->style != TR_WALL) || (mseg->next->barrier[0]->height != curBarrier->height)) {
SETPOINT(texLen + curBarrier->width/curTexSize, 0.66, seg->vertex[TR_ER].x, seg->vertex[TR_ER].y, seg->vertex[TR_ER].z + curBarrier->height);
SETPOINT(texLen + curBarrier->width/curTexSize, 1.00, seg->vertex[TR_ER].x, seg->vertex[TR_ER].y, seg->vertex[TR_ER].z);
}
break;
}
break;
}
startNeeded = 0;
runninglentgh += seg->length;
}
}
}
/* Left Barrier */
for (j = 0; j < 3; j++) {
prevTexId = 0;
texLen = 0;
startNeeded = 1;
runninglentgh = 0;
sprintf(sname, "B%dLt", j);
for (i = 0, mseg = Track->seg->next; i < Track->nseg; i++, mseg = mseg->next) {
if ((mseg->lside != NULL) && (mseg->lside->raceInfo & TR_PIT)) {
runninglentgh = 0;
startNeeded = 1;
NEWDISPLIST(0, sname, i);
} else {
curBarrier = mseg->barrier[1];
CHECKDISPLIST(curBarrier->surface->material, sname, i, 0);
if (!curTexLink) {
curTexSeg = 0;
} else {
curTexSeg = mseg->lgfromstart;
}
texLen = curTexSeg / curTexSize;
if (mseg->lside) {
seg = mseg->lside;
if (seg->lside) {
seg = seg->lside;
}
} else {
seg = mseg;
}
if (startNeeded || (runninglentgh > LG_STEP_MAX)) {
NEWDISPLIST(0, sname, i);
runninglentgh = 0;
if (curTexType == 0) texLen = 0;
switch (curBarrier->style) {
case TR_FENCE:
if (j == 0) {
SETPOINT(texLen, 1.0, seg->vertex[TR_SL].x, seg->vertex[TR_SL].y, seg->vertex[TR_SL].z + curBarrier->height);
SETPOINT(texLen, 0.0, seg->vertex[TR_SL].x, seg->vertex[TR_SL].y, seg->vertex[TR_SL].z);
}
break;
case TR_WALL:
switch (j) {
case 0:
trkpos.toStart = 0;
trkpos.toRight = curBarrier->width + RtTrackGetWidth(seg, 0);
trkpos.seg = seg;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
if ((mseg->prev->barrier[1]->style != TR_WALL) || (mseg->prev->barrier[1]->height != curBarrier->height)) {
SETPOINT(texLen - curBarrier->width/curTexSize, 1.00, seg->vertex[TR_SL].x, seg->vertex[TR_SL].y, seg->vertex[TR_SL].z);
SETPOINT(texLen - curBarrier->width/curTexSize, 0.66, seg->vertex[TR_SL].x, seg->vertex[TR_SL].y, seg->vertex[TR_SL].z + curBarrier->height);
}
SETPOINT(texLen, 1.0, x, y, seg->vertex[TR_SL].z);
SETPOINT(texLen, 0.66, x, y, seg->vertex[TR_SL].z + curBarrier->height);
break;
case 1:
trkpos.toStart = 0;
trkpos.toRight = curBarrier->width + RtTrackGetWidth(seg, 0);
trkpos.seg = seg;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.66, x, y, seg->vertex[TR_SL].z + curBarrier->height);
SETPOINT(texLen, 0.33, seg->vertex[TR_SL].x, seg->vertex[TR_SL].y, seg->vertex[TR_SL].z + curBarrier->height);
break;
case 2:
SETPOINT(texLen, 0.33, seg->vertex[TR_SL].x, seg->vertex[TR_SL].y, seg->vertex[TR_SL].z + curBarrier->height);
SETPOINT(texLen, 0.0, seg->vertex[TR_SL].x, seg->vertex[TR_SL].y, seg->vertex[TR_SL].z);
break;
}
break;
}
}
switch (seg->type) {
case TR_STR:
ts = LMAX;
texStep = LMAX / curTexSize;
texLen += texStep;
trkpos.seg = seg;
while (ts < seg->length) {
trkpos.toStart = ts;
trkpos.toRight = RtTrackGetWidth(seg, ts);
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
curHeight = RtTrackHeightL(&trkpos);
switch (curBarrier->style) {
case TR_FENCE:
if (j == 0) {
SETPOINT(texLen, 1.0, x, y, curHeight + curBarrier->height);
SETPOINT(texLen, 0, x, y, curHeight);
}
break;
case TR_WALL:
switch (j) {
case 0:
trkpos.toRight = curBarrier->width + RtTrackGetWidth(seg, ts);
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 1.0, x, y, curHeight);
SETPOINT(texLen, 0.66, x, y, curHeight + curBarrier->height);
break;
case 1:
trkpos.toRight = curBarrier->width + RtTrackGetWidth(seg, ts);
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.66, x, y, curHeight + curBarrier->height);
trkpos.toRight = RtTrackGetWidth(seg, ts);
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.33, x, y, curHeight + curBarrier->height);
break;
case 2:
SETPOINT(texLen, 0.33, x, y, curHeight + curBarrier->height);
SETPOINT(texLen, 0, x, y, curHeight);
break;
}
break;
}
ts += LMAX;
texLen += texStep;
}
ts = seg->length;
break;
case TR_LFT:
step = LMAX / (mseg->radiusr);
texStep = step * mseg->radius / curTexSize;
anz = seg->angle[TR_ZS] + step;
ts = step;
texLen += texStep;
radiusl = seg->radiusl;
trkpos.seg = seg;
while (anz < seg->angle[TR_ZE]) {
trkpos.toStart = ts;
trkpos.toRight = RtTrackGetWidth(seg, ts);
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
curHeight = RtTrackHeightL(&trkpos);
switch (curBarrier->style) {
case TR_FENCE:
if (j == 0) {
SETPOINT(texLen, 1.0, x, y, curHeight + curBarrier->height);
SETPOINT(texLen, 0, x, y, curHeight);
}
break;
case TR_WALL:
switch (j) {
case 0:
trkpos.toRight = curBarrier->width + RtTrackGetWidth(seg, ts);
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 1.0, x, y, curHeight);
SETPOINT(texLen, 0.66, x, y, curHeight + curBarrier->height);
break;
case 1:
trkpos.toRight = curBarrier->width + RtTrackGetWidth(seg, ts);
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.66, x, y, curHeight + curBarrier->height);
trkpos.toRight = RtTrackGetWidth(seg, ts);
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.33, x, y, curHeight + curBarrier->height);
break;
case 2:
SETPOINT(texLen, 0.33, x, y, curHeight + curBarrier->height);
SETPOINT(texLen, 0, x, y, curHeight);
break;
}
break;
}
ts += step;
texLen += texStep;
anz += step;
}
ts = seg->arc;
break;
case TR_RGT:
step = LMAX / (mseg->radiusl);
texStep = step * mseg->radius / curTexSize;
anz = seg->angle[TR_ZS] - step;
ts = step;
texLen += texStep;
radiusl = seg->radiusl;
trkpos.seg = seg;
while (anz > seg->angle[TR_ZE]) {
trkpos.toStart = ts;
trkpos.toRight = RtTrackGetWidth(seg, ts);
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
curHeight = RtTrackHeightL(&trkpos);
switch (curBarrier->style) {
case TR_FENCE:
if (j == 0) {
SETPOINT(texLen, 1.0, x, y, curHeight + curBarrier->height);
SETPOINT(texLen, 0, x, y, curHeight);
}
break;
case TR_WALL:
switch (j) {
case 0:
trkpos.toRight = curBarrier->width + RtTrackGetWidth(seg, ts);
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 1.0, x, y, curHeight);
SETPOINT(texLen, 0.66, x, y, curHeight + curBarrier->height);
break;
case 1:
trkpos.toRight = curBarrier->width + RtTrackGetWidth(seg, ts);
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.66, x, y, curHeight + curBarrier->height);
trkpos.toRight = RtTrackGetWidth(seg, ts);
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.33, x, y, curHeight + curBarrier->height);
break;
case 2:
SETPOINT(texLen, 0.33, x, y, curHeight + curBarrier->height);
SETPOINT(texLen, 0, x, y, curHeight);
break;
}
break;
}
ts += step;
texLen += texStep;
anz -= step;
}
ts = seg->arc;
break;
}
texLen = (curTexSeg + mseg->length) / curTexSize;
switch (curBarrier->style) {
case TR_FENCE:
if (j == 0) {
SETPOINT(texLen, 1.0, seg->vertex[TR_EL].x, seg->vertex[TR_EL].y, seg->vertex[TR_EL].z + curBarrier->height);
SETPOINT(texLen, 0, seg->vertex[TR_EL].x, seg->vertex[TR_EL].y, seg->vertex[TR_EL].z);
}
break;
case TR_WALL:
switch (j) {
case 0:
trkpos.toStart = ts;
trkpos.toRight = curBarrier->width + RtTrackGetWidth(seg, ts);
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 1.0, x, y, seg->vertex[TR_EL].z);
SETPOINT(texLen, 0.66, x, y, seg->vertex[TR_EL].z + curBarrier->height);
if ((mseg->next->barrier[1]->style != TR_WALL) || (mseg->next->barrier[1]->height != curBarrier->height)) {
SETPOINT(texLen + curBarrier->width/curTexSize, 1.00, seg->vertex[TR_EL].x, seg->vertex[TR_EL].y, seg->vertex[TR_EL].z);
SETPOINT(texLen + curBarrier->width/curTexSize, 0.66, seg->vertex[TR_EL].x, seg->vertex[TR_EL].y, seg->vertex[TR_EL].z + curBarrier->height);
}
break;
case 1:
trkpos.toStart = ts;
trkpos.toRight = curBarrier->width + RtTrackGetWidth(seg, ts);
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
SETPOINT(texLen, 0.66, x, y, seg->vertex[TR_EL].z + curBarrier->height);
SETPOINT(texLen, 0.33, seg->vertex[TR_EL].x, seg->vertex[TR_EL].y, seg->vertex[TR_EL].z + curBarrier->height);
break;
case 2:
SETPOINT(texLen, 0.33, seg->vertex[TR_EL].x, seg->vertex[TR_EL].y, seg->vertex[TR_EL].z + curBarrier->height);
SETPOINT(texLen, 0.0, seg->vertex[TR_EL].x, seg->vertex[TR_EL].y, seg->vertex[TR_EL].z);
break;
}
break;
}
startNeeded = 0;
runninglentgh += seg->length;
}
}
}
if (!bump) {
/* Turn Marks */
for (i = 0, seg = Track->seg->next; i < Track->nseg; i++, seg = seg->next) {
if (seg->ext) {
t3Dd normvec;
int nbMarks = seg->ext->nbMarks;
int *marks = seg->ext->marks;
int j, k;
for (j = 0; j < nbMarks; j++) {
/* find the segment */
tdble lgfs = seg->lgfromstart - (tdble)marks[j];
if (lgfs < 0) {
lgfs += Track->length;
}
for (k = 0, mseg = Track->seg->next; k < Track->nseg; k++, mseg = mseg->next) {
if ((lgfs >= mseg->lgfromstart) && (lgfs < (mseg->lgfromstart + mseg->length))) {
break;
}
}
if (seg->type == TR_RGT) {
sprintf(buf, "turn%dR", marks[j]);
trkpos.toRight = Track->width + tmHSpace + tmWidth;
} else {
sprintf(buf, "turn%dL", marks[j]);
trkpos.toRight = -tmHSpace;
}
trkpos.toStart = lgfs - mseg->lgfromstart;
if (mseg->type != TR_STR) {
trkpos.toStart = trkpos.toStart / mseg->radius;
}
trkpos.seg = mseg;
RtTrackLocal2Global(&trkpos, &x, &y, TR_TORIGHT);
z = tmVSpace + RtTrackHeightL(&trkpos);
if (seg->type == TR_LFT) {
RtTrackSideNormalG(mseg, x, y, TR_RGT, &normvec);
normvec.x = -normvec.x;
normvec.y = -normvec.y;
} else {
RtTrackSideNormalG(mseg, x, y, TR_LFT, &normvec);
}
CHECKDISPLIST2(buf, 0, "TuMk", mseg->id);
aDispElt->surfType = 0x10;
SETPOINT(0.0, 0.0, x, y, z);
SETPOINT(1.0, 0.0, x + tmWidth * normvec.x, y + tmWidth * normvec.y, z);
SETPOINT(0.0, 1.0, x, y, z + tmHeight);
SETPOINT(1.0, 1.0, x + tmWidth * normvec.x, y + tmWidth * normvec.y, z + tmHeight);
CHECKDISPLIST2("back-sign", 0, "TuMk", mseg->id);
aDispElt->surfType = 0x10;
SETPOINT(0.0, 0.0, x + tmWidth * normvec.x, y + tmWidth * normvec.y, z);
SETPOINT(1.0, 0.0, x, y, z);
SETPOINT(0.0, 1.0, x + tmWidth * normvec.x, y + tmWidth * normvec.y, z + tmHeight);
SETPOINT(1.0, 1.0, x, y, z + tmHeight);
printf("(%f, %f, %f), (%f, %f, %f)\n", x, y, z, x + tmWidth * normvec.x, y + tmWidth * normvec.y, z + tmHeight);
}
}
}
/* Start Bridge */
CHECKDISPLIST2("pylon1", 4, "S0Bg", 0);
#define BR_HEIGHT_1 8.0
#define BR_HEIGHT_2 6.0
#define BR_WIDTH_0 2.0
#define BR_WIDTH_1 2.0
mseg = Track->seg->next;
if (mseg->rside) {
seg = mseg->rside;
if (seg->rside) {
seg = seg->rside;
}
} else {
seg = mseg;
}
x = seg->vertex[TR_SR].x;
y = seg->vertex[TR_SR].y - 0.1;
z = seg->vertex[TR_SR].z;
SETPOINT(0, 0, x, y, z);
SETPOINT(0, 1, x, y, z + BR_HEIGHT_2);
x += BR_WIDTH_0;
SETPOINT(1, 0, x, y, z);
SETPOINT(1, 1, x, y, z + BR_HEIGHT_2);
y -= BR_WIDTH_1;
SETPOINT(2, 0, x, y, z);
SETPOINT(2, 1, x, y, z + BR_HEIGHT_2);
x -= BR_WIDTH_0;
SETPOINT(3, 0, x, y, z);
SETPOINT(3, 1, x, y, z + BR_HEIGHT_2);
y += BR_WIDTH_1;
SETPOINT(4, 0, x, y, z);
SETPOINT(4, 1, x, y, z + BR_HEIGHT_2);
NEWDISPLIST(0, "S1Bg", 0);
if (mseg->lside) {
seg = mseg->lside;
if (seg->lside) {
seg = seg->lside;
}
} else {
seg = mseg;
}
x2 = seg->vertex[TR_SL].x;
y2 = seg->vertex[TR_SL].y + 0.1;
z2 = seg->vertex[TR_SL].z;
SETPOINT(0, 1, x2, y2, z + BR_HEIGHT_2);
SETPOINT(0, 0, x2, y2, z2);
x2 += BR_WIDTH_0;
SETPOINT(1, 1, x2, y2, z + BR_HEIGHT_2);
SETPOINT(1, 0, x2, y2, z2);
y2 += BR_WIDTH_1;
SETPOINT(2, 1, x2, y2, z + BR_HEIGHT_2);
SETPOINT(2, 0, x2, y2, z2);
x2 -= BR_WIDTH_0;
SETPOINT(3, 1, x2, y2, z + BR_HEIGHT_2);
SETPOINT(3, 0, x2, y2, z2);
y2 -= BR_WIDTH_1;
SETPOINT(4, 1, x2, y2, z + BR_HEIGHT_2);
SETPOINT(4, 0, x2, y2, z2);
CHECKDISPLIST2("pylon2", 4, "S2Bg", 0);
SETPOINT(0, 1, x, y, z + BR_HEIGHT_1);
SETPOINT(0, 0, x, y, z + BR_HEIGHT_2);
y -= BR_WIDTH_1;
SETPOINT(1, 1, x, y, z + BR_HEIGHT_1);
SETPOINT(1, 0, x, y, z + BR_HEIGHT_2);
x += BR_WIDTH_0;
SETPOINT(2, 1, x, y, z + BR_HEIGHT_1);
SETPOINT(2, 0, x, y, z + BR_HEIGHT_2);
y += BR_WIDTH_1;
SETPOINT(3, 1, x, y, z + BR_HEIGHT_1);
SETPOINT(3, 0, x, y, z + BR_HEIGHT_2);
x -= BR_WIDTH_0;
SETPOINT(3, 1, x + BR_WIDTH_0, y, z + BR_HEIGHT_1);
SETPOINT(3, 0, x, y, z + BR_HEIGHT_1);
y -= BR_WIDTH_1;
SETPOINT(4, 1, x + BR_WIDTH_0, y, z + BR_HEIGHT_1);
SETPOINT(4, 0, x, y, z + BR_HEIGHT_1);
y += BR_WIDTH_1; /* back to origin */
NEWDISPLIST(0, "S3Bg", 0);
y2 += BR_WIDTH_1;
SETPOINT(0, 1, x2 + BR_WIDTH_0, y2, z + BR_HEIGHT_1);
SETPOINT(0, 0, x2, y2, z + BR_HEIGHT_1);
y2 -= BR_WIDTH_1;
SETPOINT(1, 1, x2 + BR_WIDTH_0, y2, z + BR_HEIGHT_1);
SETPOINT(1, 0, x2, y2, z + BR_HEIGHT_1);
x2 += BR_WIDTH_0;
SETPOINT(1, 1, x2, y2, z + BR_HEIGHT_1);
SETPOINT(1, 0, x2, y2, z + BR_HEIGHT_2);
y2 += BR_WIDTH_1;
SETPOINT(2, 1, x2, y2, z + BR_HEIGHT_1);
SETPOINT(2, 0, x2, y2, z + BR_HEIGHT_2);
x2 -= BR_WIDTH_0;
SETPOINT(3, 1, x2, y2, z + BR_HEIGHT_1);
SETPOINT(3, 0, x2, y2, z + BR_HEIGHT_2);
y2 -= BR_WIDTH_1;
SETPOINT(4, 1, x2, y2, z + BR_HEIGHT_1);
SETPOINT(4, 0, x2, y2, z + BR_HEIGHT_2);
/* Middle on the bridge */
CHECKDISPLIST2("pylon3", 4, "S4Bg", 2);
SETPOINT(0, 0, x2, y2, z + BR_HEIGHT_2);
SETPOINT(1, 0, x, y, z + BR_HEIGHT_2);
SETPOINT(0, 0.25, x2, y2, z + BR_HEIGHT_1);
SETPOINT(1, 0.25, x, y, z + BR_HEIGHT_1);
x += BR_WIDTH_0;
x2 += BR_WIDTH_0;
SETPOINT(0, 0.5, x2, y2, z + BR_HEIGHT_1);
SETPOINT(1, 0.5, x, y, z + BR_HEIGHT_1);
SETPOINT(0, 0.75, x2, y2, z + BR_HEIGHT_2);
SETPOINT(1, 0.75, x, y, z + BR_HEIGHT_2);
x -= BR_WIDTH_0;
x2 -= BR_WIDTH_0;
SETPOINT(0, 1, x2, y2, z + BR_HEIGHT_2);
SETPOINT(1, 1, x, y, z + BR_HEIGHT_2);
/* draw the pits */
#define PIT_HEIGHT 5.0
#define PIT_DEEP 10.0
#define PIT_TOP 0.2
pits = &(Track->pits);
initPits(pits);
if (pits->type == TR_PIT_ON_TRACK_SIDE) {
int uid = 1;
t3Dd normvec;
startNeeded = 1;
sprintf(sname, "P%dts", uid++);
CHECKDISPLIST3("concrete2.rgb", 4, sname, pits->driversPits[0].pos.seg->id);
RtTrackLocal2Global(&(pits->driversPits[0].pos), &x, &y, pits->driversPits[0].pos.type);
RtTrackSideNormalG(pits->driversPits[0].pos.seg, x, y, pits->side, &normvec);
z2 = RtTrackHeightG(pits->driversPits[0].pos.seg, x, y);
x2 = x + PIT_TOP * normvec.x;
y2 = y + PIT_TOP * normvec.y;
SETPOINT(1.0 - PIT_TOP, PIT_HEIGHT - PIT_TOP, x2, y2, z2 + PIT_HEIGHT - PIT_TOP);
SETPOINT(1.0 - PIT_TOP, PIT_HEIGHT, x2, y2, z2 + PIT_HEIGHT);
x2 = x;
y2 = y;
SETPOINT(1.0, PIT_HEIGHT - PIT_TOP, x2, y2, z2 + PIT_HEIGHT - PIT_TOP);
x2 = x - PIT_DEEP * normvec.x;
y2 = y - PIT_DEEP * normvec.y;
SETPOINT(1.0 + PIT_DEEP, PIT_HEIGHT, x2, y2, z2 + PIT_HEIGHT);
x2 = x;
y2 = y;
SETPOINT(1.0, 0, x2, y2, z2);
x2 = x - PIT_DEEP * normvec.x;
y2 = y - PIT_DEEP * normvec.y;
SETPOINT(1.0 + PIT_DEEP, 0, x2, y2, z2);
for (i = 0; i < pits->driversPitsNb; i++) {
tdble dx, dy;
startNeeded = 1;
sprintf(sname, "P%dts", uid++);
CHECKDISPLIST3("concrete.rgb", 4, sname, pits->driversPits[i].pos.seg->id);
RtTrackLocal2Global(&(pits->driversPits[i].pos), &x, &y, pits->driversPits[i].pos.type);
RtTrackSideNormalG(pits->driversPits[i].pos.seg, x, y, pits->side, &normvec);
x2 = x;
y2 = y;
z2 = RtTrackHeightG(pits->driversPits[i].pos.seg, x2, y2);
if (pits->side == TR_RGT) {
x3 = x + pits->len * normvec.y;
y3 = y - pits->len * normvec.x;
} else {
x3 = x - pits->len * normvec.y;
y3 = y + pits->len * normvec.x;
}
z3 = RtTrackHeightG(pits->driversPits[i].pos.seg, x3, y3);
SETPOINT(pits->len, 0, x2, y2, z2 + PIT_HEIGHT - PIT_TOP);
SETPOINT(0, 0, x3, y3, z3 + PIT_HEIGHT - PIT_TOP);
dx = PIT_TOP * normvec.x;
dy = PIT_TOP * normvec.y;
SETPOINT(pits->len, PIT_TOP, x2 + dx, y2 + dy, z2 + PIT_HEIGHT - PIT_TOP);
SETPOINT(0, PIT_TOP, x3 + dx, y3 + dy, z3 + PIT_HEIGHT - PIT_TOP);
SETPOINT(pits->len, 2 * PIT_TOP, x2 + dx, y2 + dy, z2 + PIT_HEIGHT);
SETPOINT(0, 2 * PIT_TOP, x3 + dx, y3 + dy, z3 + PIT_HEIGHT);
dx = - PIT_DEEP * normvec.x;
dy = - PIT_DEEP * normvec.y;
SETPOINT(pits->len, 2 * PIT_TOP + PIT_DEEP, x2 + dx, y2 + dy, z2 + PIT_HEIGHT);
SETPOINT(0, 2 * PIT_TOP + PIT_DEEP, x3 + dx, y3 + dy, z3 + PIT_HEIGHT);
SETPOINT(pits->len, 2 * PIT_TOP + PIT_DEEP + PIT_HEIGHT, x2 + dx, y2 + dy, z2);
SETPOINT(0, 2 * PIT_TOP + PIT_DEEP + PIT_HEIGHT, x3 + dx, y3 + dy, z3);
}
startNeeded = 1;
i--;
sprintf(sname, "P%dts", uid++);
CHECKDISPLIST3("concrete2.rgb", 4, sname, pits->driversPits[i].pos.seg->id);
RtTrackLocal2Global(&(pits->driversPits[i].pos), &x, &y, pits->driversPits[i].pos.type);
RtTrackSideNormalG(pits->driversPits[i].pos.seg, x, y, pits->side, &normvec);
if (pits->side == TR_RGT) {
x = x + pits->len * normvec.y;
y = y - pits->len * normvec.x;
} else {
x = x - pits->len * normvec.y;
y = y + pits->len * normvec.x;
}
z2 = RtTrackHeightG(pits->driversPits[i].pos.seg, x, y);
x2 = x + PIT_TOP * normvec.x;
y2 = y + PIT_TOP * normvec.y;
SETPOINT(1.0 - PIT_TOP, PIT_HEIGHT, x2, y2, z2 + PIT_HEIGHT);
SETPOINT(1.0 - PIT_TOP, PIT_HEIGHT - PIT_TOP, x2, y2, z2 + PIT_HEIGHT - PIT_TOP);
x2 = x - PIT_DEEP * normvec.x;
y2 = y - PIT_DEEP * normvec.y;
SETPOINT(1.0 + PIT_DEEP, PIT_HEIGHT, x2, y2, z2 + PIT_HEIGHT);
x2 = x;
y2 = y;
SETPOINT(1.0, PIT_HEIGHT - PIT_TOP, x2, y2, z2 + PIT_HEIGHT - PIT_TOP);
x2 = x - PIT_DEEP * normvec.x;
y2 = y - PIT_DEEP * normvec.y;
SETPOINT(1.0 + PIT_DEEP, 0, x2, y2, z2);
x2 = x;
y2 = y;
SETPOINT(1.0, 0, x2, y2, z2);
}
}
CLOSEDISPLIST();
printf("=== Indices really used = %d\n", nbvert);
return 0;
}
static void
saveObject(FILE *curFd, int nb, int start, char *texture, char *name, int surfType)
{
int i, index;
fprintf(curFd, "OBJECT poly\n");
fprintf(curFd, "name \"%s\"\n", name);
fprintf(curFd, "texture \"%s\"\n", texture);
fprintf(curFd, "numvert %d\n", nb);
for (i = 0; i < nb; i++) {
index = 3 * (start + i);
fprintf(curFd, "%f %f %f\n", trackvertices[index], trackvertices[index+2], -trackvertices[index+1]);
}
fprintf(curFd, "numsurf %d\n", nb - 2);
if (surfType) {
fprintf(curFd, "SURF 0x10\n");
} else {
fprintf(curFd, "SURF 0x30\n");
}
fprintf(curFd, "mat 0\n");
fprintf(curFd, "refs 3\n");
fprintf(curFd, "%d %f %f\n", 0, tracktexcoord[2*start], tracktexcoord[2*start+1]);
fprintf(curFd, "%d %f %f\n", 1, tracktexcoord[2*(start+1)], tracktexcoord[2*(start+1)+1]);
fprintf(curFd, "%d %f %f\n", 2, tracktexcoord[2*(start+2)], tracktexcoord[2*(start+2)+1]);
/* triangle strip conversion to triangles */
for (i = 2; i < nb-1; i++) {
if (surfType) {
fprintf(curFd, "SURF 0x10\n");
} else {
fprintf(curFd, "SURF 0x30\n");
}
fprintf(curFd, "mat 0\n");
fprintf(curFd, "refs 3\n");
if ((i % 2) == 0) {
index = i;
fprintf(curFd, "%d %f %f\n", index, tracktexcoord[2*(start+index)], tracktexcoord[2*(start+index)+1]);
index = i - 1;
fprintf(curFd, "%d %f %f\n", index, tracktexcoord[2*(start+index)], tracktexcoord[2*(start+index)+1]);
index = i + 1;
fprintf(curFd, "%d %f %f\n", index, tracktexcoord[2*(start+index)], tracktexcoord[2*(start+index)+1]);
} else {
index = i - 1;
fprintf(curFd, "%d %f %f\n", index, tracktexcoord[2*(start+index)], tracktexcoord[2*(start+index)+1]);
index = i;
fprintf(curFd, "%d %f %f\n", index, tracktexcoord[2*(start+index)], tracktexcoord[2*(start+index)+1]);
index = i + 1;
fprintf(curFd, "%d %f %f\n", index, tracktexcoord[2*(start+index)], tracktexcoord[2*(start+index)+1]);
}
}
fprintf(curFd, "kids 0\n");
}
static void
SaveMainTrack(FILE *curFd, int bump)
{
tDispElt *aDispElt;
char buf[256];
int i;
for (i = 0; i < GroupNb; i++) {
if (Groups[i].nb != 0) {
aDispElt = Groups[i].dispList;
sprintf(buf, "TKMN%d", i);
Ac3dGroup(curFd, buf, Groups[i].nb);
do {
aDispElt = aDispElt->next;
if (aDispElt->nb != 0) {
sprintf(buf, "%s%d", aDispElt->name, aDispElt->id);
if (bump) {
saveObject(curFd, aDispElt->nb, aDispElt->start, aDispElt->texture->namebump, buf, aDispElt->surfType);
} else {
saveObject(curFd, aDispElt->nb, aDispElt->start, aDispElt->texture->name, buf, aDispElt->surfType);
}
}
} while (aDispElt != Groups[i].dispList);
}
}
}
/** Calculate track parameters and exit without any file creation
It is for information only, mainly for use from TrackEditor.
@param Track track structure
@param TrackHandle handle on the track description
@return none
*/
void CalculateTrack(tTrack * Track, void *TrackHandle, int bump)
{
TrackStep = GfParmGetNum(TrackHandle, TRK_SECT_TERRAIN, TRK_ATT_TSTEP, NULL, TrackStep);
GfOut("Track step: %.2f ", TrackStep);
InitScene(Track, TrackHandle, bump);
printf("Calculation finished\n");
}
/** Generate the track AC3D file(s).
@param Track track structure
@param TrackHandle handle on the track description
@param outFile output file name for track only
@param AllFd fd of the merged file
@return none
*/
void
GenerateTrack(tTrack * Track, void *TrackHandle, char *outFile, FILE *AllFd, int bump)
{
FILE *curFd;
TrackStep = GfParmGetNum(TrackHandle, TRK_SECT_TERRAIN, TRK_ATT_TSTEP, NULL, TrackStep);
GfOut("Track step: %.2f ", TrackStep);
InitScene(Track, TrackHandle, bump);
if (outFile) {
curFd = Ac3dOpen(outFile, 1);
Ac3dGroup(curFd, "track", ActiveGroups);
SaveMainTrack(curFd, bump);
Ac3dClose(curFd);
}
if (AllFd) {
Ac3dGroup(AllFd, "track", ActiveGroups);
SaveMainTrack(AllFd, bump);
}
}