Ejemplo n.º 1
0
/*
 * Read version 1 track segments
 */
void 
ReadTrack1(tTrack *theTrack, void *TrackHandle, tRoadCam **camList)
{
    int		i,j;
    int		segread, curindex;
    tdble	radius;
    tdble	innerradius;
    tdble	arc;
    tdble	length;
    tTrackSeg	*curSeg;
    tdble	alf;
    tdble	xr, yr, newxr, newyr;
    tdble	xl, yl, newxl, newyl;
    tdble	cenx, ceny;
    tdble	width, wi2;
    tdble	x1, x2, y1, y2;
    tdble	al, alfl;
    tdble	zsl, zsr, zel, zer, zs, ze;
    char        *segtype = (char*)NULL;
    char	*material;
    char	*segName;
    int		segId;
    tRoadCam	*curCam;
    tTrkLocPos	trkPos;
    tdble	kFriction, kRollRes;
    tdble	kRoughness, kRoughWaveLen;
    char	path[256];
    char	path2[256];

    /* sides */
    tdble	lsw, rsw;
    char	*lsmaterial;
    char	*rsmaterial;
    int 	lst, rst;
    
    

    width = theTrack->width;
    wi2 = width / 2.0;
    xr = xl = newxr = newxl = 0.0;
    yr = newyr = newyl = 0.0;
    yl = width;
    xmin = xmax = ymin = zmin = zmax = 0.0;
    ymax = yl;
    alf = alfl = 0.0;
    zsl = zsr = zel = zer = zs = ze = 0.0;
    lsw = rsw = 0.0;

    /* Main Track */
    material = GfParmGetStr(TrackHandle, TRK_SECT_HDR, TRK_ATT_SURF, TRK_VAL_ASPHALT);
    sprintf(path, "%s/%s/%s", TRK_SECT_SURFACES, TRK_LST_SURF, material);
    kFriction = GfParmGetNum(TrackHandle, path, TRK_ATT_FRICTION, (char*)NULL, 0.8);
    kRollRes = GfParmGetNum(TrackHandle, path, TRK_ATT_ROLLRES, (char*)NULL, 0.001);
    kRoughness = GfParmGetNum(TrackHandle, path, TRK_ATT_ROUGHT, (char*)NULL, 0.0) / 2.0;
    kRoughWaveLen = 2.0 * PI / GfParmGetNum(TrackHandle, path, TRK_ATT_ROUGHTWL, (char*)NULL, 1.0);
    lsw = GfParmGetNum(TrackHandle, TRK_SECT_HDR, TRK_ATT_LSW, (char*)NULL, 0.0);
    rsw = GfParmGetNum(TrackHandle, TRK_SECT_HDR, TRK_ATT_RSW, (char*)NULL, 0.0);
    lsmaterial = GfParmGetStr(TrackHandle, TRK_SECT_HDR, TRK_ATT_LSSURF, TRK_VAL_GRASS);
    rsmaterial = GfParmGetStr(TrackHandle, TRK_SECT_HDR, TRK_ATT_RSSURF, TRK_VAL_GRASS);

    if (strcmp("level", GfParmGetStr(TrackHandle, TRK_SECT_HDR, TRK_ATT_RST, "level")) == 0) {
	rst = 0;
    } else {
	rst = 1;
    }
    if (strcmp("level", GfParmGetStr(TrackHandle, TRK_SECT_HDR, TRK_ATT_LST, "level")) == 0) {
	lst = 0;
    } else {
	lst = 1;
    }
    
    segread = 0;
    curindex = 0;
    sprintf(path, "%s/%s", TRK_SECT_CAM, TRK_LST_CAM);
    GfParmListSeekFirst(TrackHandle, path);
    do {
	segtype = GfParmGetCurStr(TrackHandle, path, TRK_ATT_TYPE, NULL);
	if (segtype == 0) {
	    continue;
	}
	segread++;
	
	zsl = zel;
	zsr = zer;
	TSTZ(zsl);
	TSTZ(zsr);
	

	/* allocate a new segment */
	curSeg = (tTrackSeg*)calloc(1, sizeof(tTrackSeg));
	if (theTrack->seg == NULL) {
	    theTrack->seg = curSeg;
	    curSeg->next = curSeg;
	} else {
	    curSeg->next = theTrack->seg->next;
	    theTrack->seg->next = curSeg;
	    theTrack->seg = curSeg;
	}
	GfParmSetCurNum(TrackHandle, path, TRK_ATT_ID, (char*)NULL, (tdble)curindex);
	curSeg->name = GfParmListGetCurEltName(TrackHandle, path);
	//sprintf(path, "%s/%s/%s", TRK_SECT_CAM, TRK_LST_CAM, curSeg->name);
	curSeg->id = curindex;
	curSeg->width = width;
	curSeg->material = material;
	curSeg->kFriction = kFriction;
	curSeg->kRollRes = kRollRes;
	curSeg->kRoughness = kRoughness;
	curSeg->kRoughWaveLen = kRoughWaveLen;
	curSeg->lgfromstart = theTrack->length;

	zsl = GfParmGetCurNum(TrackHandle, path, TRK_ATT_ZSL, (char*)NULL, zsl);
	zsr = GfParmGetCurNum(TrackHandle, path, TRK_ATT_ZSR, (char*)NULL, zsr);
	zel = GfParmGetCurNum(TrackHandle, path, TRK_ATT_ZEL, (char*)NULL, zel);
	zer = GfParmGetCurNum(TrackHandle, path, TRK_ATT_ZER, (char*)NULL, zer);
	ze = zs = -100000.0;
	ze = GfParmGetCurNum(TrackHandle, path, TRK_ATT_ZE, (char*)NULL, ze);
	zs = GfParmGetCurNum(TrackHandle, path, TRK_ATT_ZS, (char*)NULL, zs);

	if (ze != -100000.0) {
	    zer = zel = ze;
	}
	if (zs != -100000.0) {
	    zsr = zsl = zs;
	}
	TSTZ(zsl);
	TSTZ(zsr);

	if (strcmp(segtype, TRK_VAL_STR) == 0) {
	    /* straight */
	    length = GfParmGetCurNum(TrackHandle, path, TRK_ATT_LG, (char*)NULL, 0);
	    
	    curSeg->type = TR_STR;
	    curSeg->length = length;

	    newxr = xr + length * cos(alf);      /* find end coordinates */
	    newyr = yr + length * sin(alf);
	    newxl = xl + length * cos(alf);
	    newyl = yl + length * sin(alf);

	    curSeg->vertex[TR_SR].x = xr;
	    curSeg->vertex[TR_SR].y = yr;
	    curSeg->vertex[TR_SR].z = zsr;

	    curSeg->vertex[TR_SL].x = xl;
	    curSeg->vertex[TR_SL].y = yl;
	    curSeg->vertex[TR_SL].z = zsl;

	    curSeg->vertex[TR_ER].x = newxr;
	    curSeg->vertex[TR_ER].y = newyr;
	    curSeg->vertex[TR_ER].z = zer;

	    curSeg->vertex[TR_EL].x = newxl;
	    curSeg->vertex[TR_EL].y = newyl;
	    curSeg->vertex[TR_EL].z = zel;

	    curSeg->angle[TR_ZS] = alf;
	    curSeg->angle[TR_ZE] = alf;
	    curSeg->angle[TR_YR] = atan2(curSeg->vertex[TR_ER].z - curSeg->vertex[TR_SR].z, length);
	    curSeg->angle[TR_YL] = atan2(curSeg->vertex[TR_EL].z - curSeg->vertex[TR_SL].z, length);
	    curSeg->angle[TR_XS] = atan2(curSeg->vertex[TR_SL].z - curSeg->vertex[TR_SR].z, width);
	    curSeg->angle[TR_XE] = atan2(curSeg->vertex[TR_EL].z - curSeg->vertex[TR_ER].z, width);
	    
	    curSeg->Kzl = tan(curSeg->angle[TR_YR]);
	    curSeg->Kzw = (curSeg->angle[TR_XE] - curSeg->angle[TR_XS]) / length;
	    curSeg->Kyl = 0;

	    curSeg->rgtSideNormal.x = -sin(alf);
	    curSeg->rgtSideNormal.y = cos(alf);

	    TSTX(newxr); TSTX(newxl);
	    TSTY(newyr); TSTY(newyl);


	} else if (strcmp(segtype, TRK_VAL_LFT) == 0) {
	    /* left curve */
	    radius = GfParmGetCurNum(TrackHandle, path, TRK_ATT_RADIUS, (char*)NULL, 0);
	    arc = GfParmGetCurNum(TrackHandle, path, TRK_ATT_ARC, (char*)NULL, 0);

	    curSeg->type = TR_LFT;
	    curSeg->radius = radius;
	    curSeg->radiusr = radius + wi2;
	    curSeg->radiusl = radius - wi2;
	    curSeg->arc = arc;
	    curSeg->length = radius * arc;
	    
	    innerradius = radius - wi2; /* left side aligned */
	    cenx = xl - innerradius * sin(alf);  /* compute center location: */
	    ceny = yl + innerradius * cos(alf);
	    curSeg->center.x = cenx;
	    curSeg->center.y = ceny;

	    curSeg->angle[TR_ZS] = alf;
	    curSeg->angle[TR_CS] = alf - PI / 2.0;
	    alf += arc;
	    curSeg->angle[TR_ZE] = alf;

	    newxl = cenx + innerradius * sin(alf);   /* location of end */
	    newyl = ceny - innerradius * cos(alf);
	    newxr = cenx + (innerradius + width) * sin(alf);   /* location of end */
	    newyr = ceny - (innerradius + width) * cos(alf);

	    curSeg->vertex[TR_SR].x = xr;
	    curSeg->vertex[TR_SR].y = yr;
	    curSeg->vertex[TR_SR].z = zsr;

	    curSeg->vertex[TR_SL].x = xl;
	    curSeg->vertex[TR_SL].y = yl;
	    curSeg->vertex[TR_SL].z = zsl;

	    curSeg->vertex[TR_ER].x = newxr;
	    curSeg->vertex[TR_ER].y = newyr;
	    curSeg->vertex[TR_ER].z = zer;

	    curSeg->vertex[TR_EL].x = newxl;
	    curSeg->vertex[TR_EL].y = newyl;
	    curSeg->vertex[TR_EL].z = zel;

	    curSeg->angle[TR_YR] = atan2(curSeg->vertex[TR_ER].z - curSeg->vertex[TR_SR].z, arc * (innerradius + width));
	    curSeg->angle[TR_YL] = atan2(curSeg->vertex[TR_EL].z - curSeg->vertex[TR_SL].z, arc * innerradius);
	    curSeg->angle[TR_XS] = atan2(curSeg->vertex[TR_SL].z - curSeg->vertex[TR_SR].z, width);
	    curSeg->angle[TR_XE] = atan2(curSeg->vertex[TR_EL].z - curSeg->vertex[TR_ER].z, width);

	    curSeg->Kzl = tan(curSeg->angle[TR_YR]) * (innerradius + width);
	    curSeg->Kzw = (curSeg->angle[TR_XE] - curSeg->angle[TR_XS]) / arc;
	    curSeg->Kyl = 0;
	    
	    /* to find the boundary */
	    al = (curSeg->angle[TR_ZE] - curSeg->angle[TR_ZS])/36.0;
	    alfl = curSeg->angle[TR_ZS];

	    for (j = 0; j < 36; j++) {
		alfl += al;
		x1 = curSeg->center.x + (innerradius) * sin(alfl);   /* location of end */
		y1 = curSeg->center.y - (innerradius) * cos(alfl);
		x2 = curSeg->center.x + (innerradius + width) * sin(alfl);   /* location of end */
		y2 = curSeg->center.y - (innerradius + width) * cos(alfl);
		TSTX(x1); TSTX(x2);
		TSTY(y1); TSTY(y2);
	    }

	} else if (strcmp(segtype, TRK_VAL_RGT) == 0) {
	    /* right curve */
	    radius = GfParmGetCurNum(TrackHandle, path, TRK_ATT_RADIUS, (char*)NULL, 0);
	    arc = GfParmGetCurNum(TrackHandle, path, TRK_ATT_ARC, (char*)NULL, 0);

	    curSeg->type = TR_RGT;
	    curSeg->radius = radius;
	    curSeg->radiusr = radius - wi2;
	    curSeg->radiusl = radius + wi2;
	    curSeg->arc = arc;
	    curSeg->length = radius * arc;

	    innerradius = radius - wi2; /* right side aligned */
	    cenx = xr + innerradius * sin(alf);  /* compute center location */
	    ceny = yr - innerradius * cos(alf);
	    curSeg->center.x = cenx;
	    curSeg->center.y = ceny;

	    curSeg->angle[TR_ZS] = alf;
	    curSeg->angle[TR_CS] = alf + PI / 2.0;
	    alf -= curSeg->arc;
	    curSeg->angle[TR_ZE] = alf;

	    newxl = cenx - (innerradius + width) * sin(alf);   /* location of end */
	    newyl = ceny + (innerradius + width) * cos(alf);
	    newxr = cenx - innerradius * sin(alf);   /* location of end */
	    newyr = ceny + innerradius * cos(alf);

	    curSeg->vertex[TR_SR].x = xr;
	    curSeg->vertex[TR_SR].y = yr;
	    curSeg->vertex[TR_SR].z = zsr;

	    curSeg->vertex[TR_SL].x = xl;
	    curSeg->vertex[TR_SL].y = yl;
	    curSeg->vertex[TR_SL].z = zsl;

	    curSeg->vertex[TR_ER].x = newxr;
	    curSeg->vertex[TR_ER].y = newyr;
	    curSeg->vertex[TR_ER].z = zer;

	    curSeg->vertex[TR_EL].x = newxl;
	    curSeg->vertex[TR_EL].y = newyl;
	    curSeg->vertex[TR_EL].z = zel;

	    curSeg->angle[TR_YR] = atan2(curSeg->vertex[TR_ER].z - curSeg->vertex[TR_SR].z, arc * innerradius);
	    curSeg->angle[TR_YL] = atan2(curSeg->vertex[TR_EL].z - curSeg->vertex[TR_SL].z, arc * (innerradius + width));
	    curSeg->angle[TR_XS] = atan2(curSeg->vertex[TR_SL].z - curSeg->vertex[TR_SR].z, width);
	    curSeg->angle[TR_XE] = atan2(curSeg->vertex[TR_EL].z - curSeg->vertex[TR_ER].z, width);

	    curSeg->Kzl = tan(curSeg->angle[TR_YR]) * innerradius;
	    curSeg->Kzw = (curSeg->angle[TR_XE] - curSeg->angle[TR_XS]) / arc;
	    curSeg->Kyl = 0;

	    /* to find the boundaries */
	    al = (curSeg->angle[TR_ZE] - curSeg->angle[TR_ZS])/36.0;
	    alfl = curSeg->angle[TR_ZS];

	    for (j = 0; j < 36; j++) {
		alfl += al;
		x1 = curSeg->center.x - (innerradius + width) * sin(alfl);   /* location of end */
		y1 = curSeg->center.y + (innerradius + width) * cos(alfl);
		x2 = curSeg->center.x - innerradius * sin(alfl);   /* location of end */
		y2 = curSeg->center.y + innerradius * cos(alfl);
		TSTX(x1); TSTX(x2);
		TSTY(y1); TSTY(y2);
	    }

	}

	if (lsw > 0.0) {
	    AddSide(curSeg, lsw, lsmaterial, 1, lst, TrackHandle);
	}
	if (rsw > 0.0) {
	    AddSide(curSeg, rsw, rsmaterial, 0, rst, TrackHandle);
	}

	theTrack->length += curSeg->length;
	xr = newxr;
	yr = newyr;
	xl = newxl;
	yl = newyl;
	curindex++;
        //sprintf(path, "%s/%s", TRK_SECT_MAIN, TRK_LST_SEG);

    } while (GfParmListSeekNext(TrackHandle, path) == 0);

    theTrack->nseg = segread;

    /* 
     * camera definitions
     */
    sprintf(path, "%s/%s", TRK_SECT_CAM, TRK_LST_CAM);
    if (GfParmListSeekFirst(TrackHandle, path) == 0) {
	do {
	    curCam = (tRoadCam*)calloc(1, sizeof(tRoadCam));
	    if (*camList == NULL) {
		*camList = curCam;
		curCam->next = curCam;
	    } else {
		curCam->next = (*camList)->next;
		(*camList)->next = curCam;
		*camList = curCam;
	    }
	    curCam->name = GfParmListGetCurEltName(TrackHandle, path);
	    segName = GfParmGetCurStr(TrackHandle, path, TRK_ATT_SEGMENT, NULL);
	    if (segName == 0) {
		GfFatal("Bad Track Definition: in Camera %s %s is missing\n", curCam->name, TRK_ATT_SEGMENT);
	    }
	    sprintf(path2, "%s/%s/%s", TRK_SECT_MAIN, TRK_LST_SEG, segName);
	    segId = (int)GfParmGetNum(TrackHandle, path2, TRK_ATT_ID, (char*)NULL, 0);
	    curSeg = theTrack->seg;
	    for(i=0; i<theTrack->nseg; i++)  {
		if (curSeg->id == segId) {
		    break;
		}
		curSeg = curSeg->next;
	    }

	    trkPos.seg = curSeg;
	    trkPos.toRight = GfParmGetNum(TrackHandle, path2, TRK_ATT_TORIGHT, (char*)NULL, 0);
	    trkPos.toStart = GfParmGetNum(TrackHandle, path2, TRK_ATT_TOSTART, (char*)NULL, 0);
	    TrackLocal2Global(&trkPos, &(curCam->pos.x), &(curCam->pos.y));
	    curCam->pos.z = GfParmGetNum(TrackHandle, path2, TRK_ATT_HEIGHT, (char*)NULL, 0);

	    segName = GfParmGetCurStr(TrackHandle, path, TRK_ATT_CAM_FOV, NULL);
	    if (segName == 0) {
		GfFatal("Bad Track Definition: in Camera %s %s is missing\n", curCam->name, TRK_ATT_CAM_FOV);
	    }
	    sprintf(path2, "%s/%s/%s", TRK_SECT_MAIN, TRK_LST_SEG, segName);
	    segId = (int)GfParmGetNum(TrackHandle, path2, TRK_ATT_ID, (char*)NULL, 0);
	    curSeg = theTrack->seg;
	    for(i=0; i<theTrack->nseg; i++)  {
		if (curSeg->id == segId) {
		    break;
		}
		curSeg = curSeg->next;
	    }
	    segName = GfParmGetCurStr(TrackHandle, path, TRK_ATT_CAM_FOVE, NULL);
	    if (segName == 0) {
		GfFatal("Bad Track Definition: in Camera %s %s is missing\n", curCam->name, TRK_ATT_CAM_FOVE);
	    }
	    sprintf(path2, "%s/%s/%s", TRK_SECT_MAIN, TRK_LST_SEG, segName);
	    segId = (int)GfParmGetNum(TrackHandle, path2, TRK_ATT_ID, (char*)NULL, 0);
	
	    do {
		curSeg->cam = curCam;
		curSeg = curSeg->next;
	    } while (curSeg->id != segId);
	} while (GfParmListSeekNext(TrackHandle, path) == 0);
    }

    /* Update the coord to be positives */
    theTrack->min.x = 0;
    theTrack->min.y = 0;
    theTrack->min.z = 0;
    theTrack->max.x = xmax - xmin;
    theTrack->max.y = ymax - ymin;
    theTrack->max.z = zmax - zmin;

    curSeg = theTrack->seg;
    for(i=0; i<theTrack->nseg; i++)  {         /* read the segment data: */
	if (i == 0) {
	    curSeg->raceInfo = TR_START;
	} else if (i == theTrack->nseg-1) {
	    curSeg->raceInfo = TR_LAST;
	} else {
	    curSeg->raceInfo = TR_NORMAL;
	}
	normSeg(curSeg);
	if (curSeg->lside) {
	    normSeg(curSeg->lside);
	}
	if (curSeg->rside) {
	    normSeg(curSeg->rside);
	}
	curSeg->next->prev = curSeg;
	curSeg = curSeg->next;
    }

    if (*camList != NULL) {
	curCam = *camList;
	do {
	    curCam = curCam->next;
	    curCam->pos.x -= xmin;
	    curCam->pos.y -= ymin;
	    curCam->pos.z -= zmin;
	} while (curCam != *camList);
    }
    
}
Ejemplo n.º 2
0
/*
 * Read version 2 track segments
 */
void 
ReadTrack2(tTrack *theTrack, void *TrackHandle, tRoadCam **camList, int ext)
{
    int		i;
    tTrackSeg	*curSeg = NULL, *mSeg;
    tTrackSeg	*pitEntrySeg = NULL;
    tTrackSeg	*pitExitSeg = NULL;
    tTrackSeg	*pitStart = NULL;
    tTrackSeg	*pitEnd = NULL;
    char	*segName;
    int		segId;
    tRoadCam	*curCam;
    tTrkLocPos	trkPos;
    int		found = 0;
    char	*paramVal;
    char	*pitType;
    char	path[256];
    char	path2[256];

    xmin = xmax = ymin = ymax = zmin = zmax = 0.0;
    
    CreateSegRing(TrackHandle, TRK_SECT_MAIN, &(theTrack->seg), &(theTrack->length), &(theTrack->nseg), (tTrackSeg*)NULL, (tTrackSeg*)NULL, ext);

    pitType = GfParmGetStr(TrackHandle, TRK_SECT_MAIN, TRK_ATT_PIT_TYPE, TRK_VAL_PIT_TYPE_NONE);
    
    if (strcmp(pitType, TRK_VAL_PIT_TYPE_NONE) != 0) {
	segName = GfParmGetStr(TrackHandle, TRK_SECT_MAIN, TRK_ATT_PIT_ENTRY, NULL);
	if (segName != 0) {
	    pitEntrySeg = theTrack->seg;
	    found = 0;
	    for(i = 0; i < theTrack->nseg; i++)  {
		if (!strcmp(segName, pitEntrySeg->name)) {
		    found = 1;
		} else if (found) {
		    pitEntrySeg = pitEntrySeg->next;
		    break;
		}
		pitEntrySeg = pitEntrySeg->prev;
	    }
	    if (!found) {
		pitEntrySeg = NULL;
	    }
	}
	segName = GfParmGetStr(TrackHandle, TRK_SECT_MAIN, TRK_ATT_PIT_EXIT, NULL);
	if (segName != 0) {
	    pitExitSeg = theTrack->seg->next;
	    found = 0;
	    for(i = 0; i < theTrack->nseg; i++)  {
		if (!strcmp(segName, pitExitSeg->name)) {
		    found = 1;
		} else if (found) {
		    pitExitSeg = pitExitSeg->prev;
		    break;
		}
		pitExitSeg = pitExitSeg->next;
	    }
	    if (!found) {
		pitExitSeg = NULL;
	    }
	}
	segName = GfParmGetStr(TrackHandle, TRK_SECT_MAIN, TRK_ATT_PIT_START, NULL);
	if (segName != 0) {
	    pitStart = theTrack->seg;
	    found = 0;
	    for(i = 0; i < theTrack->nseg; i++)  {
		if (!strcmp(segName, pitStart->name)) {
		    found = 1;
		} else if (found) {
		    pitStart = pitStart->next;
		    break;
		}
		pitStart = pitStart->prev;
	    }
	    if (!found) {
		pitStart = NULL;
	    }
	}
	segName = GfParmGetStr(TrackHandle, TRK_SECT_MAIN, TRK_ATT_PIT_END, NULL);
	if (segName != 0) {
	    pitEnd = theTrack->seg->next;
	    found = 0;
	    for(i = 0; i < theTrack->nseg; i++)  {
		if (!strcmp(segName, pitEnd->name)) {
		    found = 1;
		} else if (found) {
		    pitEnd = pitEnd->prev;
		    break;
		}
		pitEnd = pitEnd->next;
	    }
	    if (!found) {
		pitEnd = NULL;
	    }
	}
	paramVal = GfParmGetStr(TrackHandle, TRK_SECT_MAIN, TRK_ATT_PIT_SIDE, "right");
	if (strcmp(paramVal, "right") == 0) {
	    theTrack->pits.side = TR_RGT;
	} else {
	    theTrack->pits.side = TR_LFT;
	}
	if ((pitEntrySeg != NULL) && (pitExitSeg != NULL) && (pitStart != NULL) && (pitEnd != NULL)) {
	    theTrack->pits.pitEntry = pitEntrySeg;
	    theTrack->pits.pitExit  = pitExitSeg;
	    theTrack->pits.pitStart = pitStart;
	    theTrack->pits.pitEnd = pitEnd;
	    pitEntrySeg->raceInfo |= TR_PITENTRY;
	    pitExitSeg->raceInfo |= TR_PITEXIT;
	    theTrack->pits.len   = GfParmGetNum(TrackHandle, TRK_SECT_MAIN, TRK_ATT_PIT_LEN, (char*)NULL, 15.0);
	    theTrack->pits.width = GfParmGetNum(TrackHandle, TRK_SECT_MAIN, TRK_ATT_PIT_WIDTH, (char*)NULL, 5.0);
	    found = 1;
	} else {
	    found = 0;
	}
    }

    if (found && (strcmp(pitType, TRK_VAL_PIT_TYPE_SIDE) == 0)) {
	theTrack->pits.type     = TR_PIT_ON_TRACK_SIDE;
	theTrack->pits.nPitSeg  = 0;
	if (pitStart->lgfromstart > pitEnd->lgfromstart) {
	    theTrack->pits.nMaxPits = (int)((theTrack->length - pitStart->lgfromstart + pitEnd->lgfromstart +
					     pitEnd->length + theTrack->pits.len / 2.0) / theTrack->pits.len);
	} else {
	    theTrack->pits.nMaxPits = (int)((- pitStart->lgfromstart + pitEnd->lgfromstart +
					     pitEnd->length + theTrack->pits.len / 2.0) / theTrack->pits.len);
	}
	for (mSeg = pitStart; mSeg != pitEnd->next; mSeg = mSeg->next) {
	    switch(theTrack->pits.side) {
	    case TR_RGT:
		curSeg = mSeg->rside;
		break;
	    case TR_LFT:
		curSeg = mSeg->lside;
		break;
	    }
	    curSeg->raceInfo |= TR_PIT;
	}
	    
    }

#ifdef EEE
    if (found && (strcmp(pitType, TRK_VAL_PIT_TYPE_SEP_PATH) == 0)) {
	tTrackSeg	*pitSeg = NULL;
	tdble		pitLen;
	int		pitNseg;

	theTrack->pits.type = TR_PIT_ON_SEPARATE_PATH;
	CreateSegRing(TrackHandle, TRK_SECT_PITS, &pitSeg, &pitLen, &pitNseg, pitEntrySeg, pitExitSeg->next);
	theTrack->pits.nPitSeg = pitNseg;
	pitSeg->next->raceInfo |= TR_PITENTRY;
	pitSeg->raceInfo |= TR_PITEXIT;

	segName = GfParmGetStr(TrackHandle, TRK_SECT_PITS, TRK_ATT_FINISH, NULL);
	if (segName != 0) {
	    sprintf(path, "%s/%s/%s", TRK_SECT_MAIN, TRK_LST_SEG, segName);
	    segId = (int)GfParmGetNum(TrackHandle, path, TRK_ATT_ID, (char*)NULL, 0);
	    curSeg = pitSeg->next;
	    found = 0;
	    for (i = 0; i < pitNseg; i++) {
		if (curSeg->id == segId) {
		    found = 1;
		    break;
		}
		curSeg = curSeg->next;
	    }
	    if (found) {
		curSeg->raceInfo |= TR_LAST;
		curSeg->next->raceInfo |= TR_START;
	    }
	}

	switch(pitSeg->next->type) {
	case TR_RGT:
	    pitEntrySeg->ralt = pitSeg->next;
	    pitSeg->next->lalt = pitEntrySeg;
	    break;
	case TR_LFT:
	    pitEntrySeg->lalt = pitSeg->next;
	    pitSeg->next->ralt = pitEntrySeg;
	    break;
	case TR_STR:
	    switch(pitEntrySeg->type) {
	    case TR_RGT:
		pitEntrySeg->lalt = pitSeg->next;
		pitSeg->next->ralt = pitEntrySeg;
		break;
	    case TR_LFT:
		pitEntrySeg->ralt = pitSeg->next;
		pitSeg->next->lalt = pitEntrySeg;
		break;
	    }
	    break;
	}
	switch(pitSeg->type) {
	case TR_RGT:
	    pitExitSeg->ralt = pitSeg;
	    pitSeg->lalt = pitExitSeg;
	    break;
	case TR_LFT:
	    pitExitSeg->lalt = pitSeg;
	    pitSeg->ralt = pitExitSeg;
	    break;
	case TR_STR:
	    switch(pitExitSeg->type) {
	    case TR_RGT:
		pitExitSeg->lalt = pitSeg;
		pitSeg->ralt = pitExitSeg;
		break;
	    case TR_LFT:
		pitExitSeg->ralt = pitSeg;
		pitSeg->lalt = pitExitSeg;
		break;
	    }
	    break;
	}
	pitSeg->next = pitExitSeg;
    }
#endif
    

    /* 
     * camera definitions
     */
    sprintf(path, "%s/%s", TRK_SECT_CAM, TRK_LST_CAM);
    if (GfParmListSeekFirst(TrackHandle, path) == 0) {
	do {
	    curCam = (tRoadCam*)calloc(1, sizeof(tRoadCam));
	    if (*camList == NULL) {
		*camList = curCam;
		curCam->next = curCam;
	    } else {
		curCam->next = (*camList)->next;
		(*camList)->next = curCam;
		*camList = curCam;
	    }
	    curCam->name = GfParmListGetCurEltName(TrackHandle, path);
	    segName = GfParmGetCurStr(TrackHandle, path, TRK_ATT_SEGMENT, NULL);
	    if (segName == 0) {
		GfFatal("Bad Track Definition: in Camera %s %s is missing\n", curCam->name, TRK_ATT_SEGMENT);
	    }
	    sprintf(path2, "%s/%s/%s", TRK_SECT_MAIN, TRK_LST_SEG, segName);
	    segId = (int)GfParmGetNum(TrackHandle, path2, TRK_ATT_ID, (char*)NULL, 0);
	    curSeg = theTrack->seg;
	    for(i=0; i<theTrack->nseg; i++)  {
		if (curSeg->id == segId) {
		    break;
		}
		curSeg = curSeg->next;
	    }

	    trkPos.seg = curSeg;
	    trkPos.toRight = GfParmGetCurNum(TrackHandle, path, TRK_ATT_TORIGHT, (char*)NULL, 0);
	    trkPos.toStart = GfParmGetCurNum(TrackHandle, path, TRK_ATT_TOSTART, (char*)NULL, 0);
	    TrackLocal2Global(&trkPos, &(curCam->pos.x), &(curCam->pos.y));
	    curCam->pos.z = TrackHeightL(&trkPos) + GfParmGetCurNum(TrackHandle, path, TRK_ATT_HEIGHT, (char*)NULL, 0);

	    segName = GfParmGetCurStr(TrackHandle, path, TRK_ATT_CAM_FOV, NULL);
	    if (segName == 0) {
		GfFatal("Bad Track Definition: in Camera %s %s is missing\n", curCam->name, TRK_ATT_CAM_FOV);
	    }
	    sprintf(path2, "%s/%s/%s", TRK_SECT_MAIN, TRK_LST_SEG, segName);
	    segId = (int)GfParmGetNum(TrackHandle, path2, TRK_ATT_ID, (char*)NULL, 0);
	    curSeg = theTrack->seg;
	    for(i=0; i<theTrack->nseg; i++)  {
		if (curSeg->id == segId) {
		    break;
		}
		curSeg = curSeg->next;
	    }
	    segName = GfParmGetCurStr(TrackHandle, path, TRK_ATT_CAM_FOVE, NULL);
	    if (segName == 0) {
		GfFatal("Bad Track Definition: in Camera %s %s is missing\n", curCam->name, TRK_ATT_CAM_FOVE);
	    }
	    sprintf(path2, "%s/%s/%s", TRK_SECT_MAIN, TRK_LST_SEG, segName);
	    segId = (int)GfParmGetNum(TrackHandle, path2, TRK_ATT_ID, (char*)NULL, 0);
	
	    do {
		curSeg->cam = curCam;
		curSeg = curSeg->next;
	    } while (curSeg->id != segId);
	} while (GfParmListSeekNext(TrackHandle, path) == 0);
    }

    /* Update the coord to be positives */
    theTrack->min.x = 0;
    theTrack->min.y = 0;
    theTrack->min.z = 0;
    theTrack->max.x = xmax - xmin;
    theTrack->max.y = ymax - ymin;
    theTrack->max.z = zmax - zmin;

    if (theTrack->pits.type == TR_PIT_ON_SEPARATE_PATH) {
	curSeg = theTrack->pits.pitEntry;
	for(i = 0; i < theTrack->pits.nPitSeg; i++)  {         /* read the segment data: */
	    normSeg(curSeg);
	    if (curSeg->lside) {
		normSeg(curSeg->lside);
	    }
	    if (curSeg->rside) {
		normSeg(curSeg->rside);
	    }
	    curSeg->next->prev = curSeg;
	    curSeg = curSeg->next;
	}
    }
    
    curSeg = theTrack->seg;
    for(i=0; i<theTrack->nseg; i++)  {         /* read the segment data: */
	if (curSeg->lgfromstart > (theTrack->length - 50.0)) {
	    curSeg->raceInfo |= TR_LAST;
	} else if (curSeg->lgfromstart < 50.0) {
	    curSeg->raceInfo |= TR_START;
	} else {
	    curSeg->raceInfo |= TR_NORMAL;
	}
	normSeg(curSeg);
	if (curSeg->lside) {
	    normSeg(curSeg->lside);
	}
	if (curSeg->rside) {
	    normSeg(curSeg->rside);
	}
	curSeg->next->prev = curSeg;
	curSeg = curSeg->next;
    }
    

    if (*camList != NULL) {
	curCam = *camList;
	do {
	    curCam = curCam->next;
	    curCam->pos.x -= xmin;
	    curCam->pos.y -= ymin;
	    curCam->pos.z -= zmin;
	} while (curCam != *camList);
    }
}