void load_params(void) { int i, j; int nbcol; char *col; char buf[256]; tFace *curFace; char *s; ImgSize = (int)GfParmGetNum(ParamHandle, "image", "size", NULL, 256); NbRows = GfParmGetEltNb(ParamHandle, "faces"); Row = (tRow*)calloc(NbRows, sizeof(tRow)); GfParmListSeekFirst(ParamHandle, "faces"); for (i = 0; i < NbRows; i++) { col = GfParmListGetCurEltName(ParamHandle, "faces"); GF_TAILQ_INIT(&(Row[i].faces)); sprintf(buf, "faces/%s/col", col); nbcol = GfParmGetEltNb(ParamHandle, buf); GfParmListSeekFirst(ParamHandle, buf); for (j = 0; j < nbcol; j++) { curFace = (tFace*)calloc(1, sizeof(tFace)); GF_TAILQ_INSERT_TAIL(&(Row[i].faces), curFace, link); curFace->faceName = GfParmGetCurStr(ParamHandle, buf, "face name", NULL); if ((curFace->faceName != 0) && (strlen(curFace->faceName) != 0)) { curFace->isPresent = true; curFace->xform.hpr[1] = GfParmGetCurNum(ParamHandle, buf, "rotX", NULL, 0.0); curFace->xform.hpr[2] = -GfParmGetCurNum(ParamHandle, buf, "rotZ", NULL, 0.0); curFace->xform.hpr[0] = GfParmGetCurNum(ParamHandle, buf, "rotY", NULL, 0.0); curFace->lscale[0] = GfParmGetCurNum(ParamHandle, buf, "scaleX", NULL, 1.0); curFace->lscale[1] = GfParmGetCurNum(ParamHandle, buf, "scaleZ", NULL, 1.0); curFace->lscale[2] = GfParmGetCurNum(ParamHandle, buf, "scaleY", NULL, 1.0); s = GfParmGetCurStr(ParamHandle, buf, "align", ""); switch (s[0]) { case 'X': case 'x': curFace->align[0] = 1.0; break; case 'Y': case 'y': curFace->align[2] = 1.0; break; case 'Z': case 'z': curFace->align[1] = -1.0; break; } } GfParmListSeekNext(ParamHandle, buf); } GfParmListSeekNext(ParamHandle, "faces"); } }
// Read initial value from setup file int TGeneticParameter::GetVal(void* SetupHandle, bool First, bool Local) { char ParamSection[64]; sprintf(ParamSection,"%s",Section); if (Local) { if (First) { GfParmListSeekFirst(Handle, ParamSection); } else GfParmListSeekNext(Handle, ParamSection); if (LeftRight) { char SideParam[64]; sprintf(SideParam,ParamSection,SECT_PH_LEFT); Val = GfParmGetCurNum(SetupHandle, SideParam, Parameter, Unit, Val); sprintf(SideParam,ParamSection,SECT_PH_RGHT); if (SameSign) Val = (Val + GfParmGetCurNum(SetupHandle, SideParam, Parameter, Unit, Val)) / 2; else Val = (Val - GfParmGetCurNum(SetupHandle, SideParam, Parameter, Unit, Val)) / 2; } else Val = GfParmGetCurNum(SetupHandle, Section, Parameter, Unit, Val); } else { if (LeftRight) { char SideParam[64]; sprintf(SideParam,ParamSection,SECT_PH_LEFT); Val = GfParmGetNum(SetupHandle, SideParam, Parameter, Unit, Val); sprintf(SideParam,ParamSection,SECT_PH_RGHT); if (SameSign) Val = (Val + GfParmGetNum(SetupHandle, SideParam, Parameter, Unit, Val)) / 2; else Val = (Val - GfParmGetNum(SetupHandle, SideParam, Parameter, Unit, Val)) / 2; } else Val = GfParmGetNum(SetupHandle, Section, Parameter, Unit, Val); } Def = LastVal = OptVal = Val; return 0; };
void ReCalculateClassPoints(char const *race) { double points; char *path3; int rank = 1; int count; snprintf(buf, sizeof(buf), "%s/%s/%s/%s", ReInfo->track->name, RE_SECT_RESULTS, ReInfo->_reRaceName, RE_SECT_RANK); path3 = strdup(buf); if (GfParmListSeekFirst(ReInfo->results, path3) != 0) { free(path3); return; /* No result found */ } count = GfParmGetEltNb(ReInfo->results, path3); do { snprintf( path2, sizeof(path2), "%s/%s", race, RM_SECT_CLASSPOINTS ); if (GfParmListSeekFirst( ReInfo->params, path2 ) != 0) { GfLogDebug( "ReCalculateClassPoints: First not found in %s)\n", path2 ); continue; } do { snprintf( buf, sizeof(buf), "%s/%s", path2, GfParmListGetCurEltName( ReInfo->params, path2 ) ); snprintf( path, sizeof(path), "%s/%s/%d/%d/%s", RE_SECT_CLASSPOINTS, GfParmGetCurStr (ReInfo->results, path3, RE_ATTR_MODULE, ""), (int)GfParmGetCurNum (ReInfo->results, path3, RM_ATTR_EXTENDED, NULL, 0), (int)GfParmGetCurNum (ReInfo->results, path3, RE_ATTR_IDX, NULL, 0), GfParmGetStr( ReInfo->params, buf, RM_ATTR_SUFFIX, "" ) ); points = GfParmGetNum (ReInfo->results, path, RE_ATTR_POINTS, NULL, 0); GfParmSetVariable (ReInfo->params, buf, "pos", (tdble)rank); GfParmSetVariable (ReInfo->params, buf, "cars", (tdble)count); //GfLogDebug( "ReCalculateClassPoints: pos = %d; count = %d\n", rank, count); //GfLogDebug( "ReCalculateClassPoints: GfParmGetNum (..., %s, %s, NULL, 0)\n", buf, RM_ATTR_POINTS ); points += ( GfParmGetNum (ReInfo->params, buf, RM_ATTR_POINTS, NULL, 0) / GfParmGetNum (ReInfo->params, RM_SECT_TRACKS, RM_ATTR_NUMBER, NULL, 1) ); GfParmRemoveVariable (ReInfo->params, buf, "pos"); GfParmRemoveVariable (ReInfo->params, buf, "cars"); GfParmSetNum (ReInfo->results, path, RE_ATTR_POINTS, NULL, (tdble)points); } while (GfParmListSeekNext( ReInfo->params, path2 ) == 0); ++rank; } while (GfParmListSeekNext (ReInfo->results, path3) == 0); free(path3); }
/** * ReHumanInGroup * Checks if there is a human-driven car among the racing cars. * * @return True if there is a human. */ bool ReHumanInGroup() { if (GfParmListSeekFirst(ReInfo->params, RM_SECT_DRIVERS) == 0) { do { if (strcmp (GfParmGetCurStr(ReInfo->params, RM_SECT_DRIVERS, RM_ATTR_MODULE, ""), "human") == 0) return true; } while (GfParmListSeekNext(ReInfo->params, RM_SECT_DRIVERS) == 0); } return false; }//ReHumanInGroup
/* * 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); } }
/* * 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); } }
static void CreateSegRing(void *TrackHandle, char *section, tTrackSeg **pRoot, tdble *pLength, int *pNseg, tTrackSeg *start, tTrackSeg *end, int ext) { int j; int segread, curindex; tdble radius; tdble innerradius; tdble arc; tdble length; tTrackSeg *curSeg; tTrackSeg *root; 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; tdble bankings, bankinge, dz, dzl, dzr; tdble etgt, stgt; tdble etgtl, stgtl; tdble etgtr, stgtr; int steps, curStep; char *segtype = (char*)NULL; char *material; char *segName; int type; tdble kFriction, kRollRes; tdble kRoughness, kRoughWaveLenP, kRoughWaveLen; char *profil; tdble totLength; tdble tl, dtl, T1l, T2l; tdble tr, dtr, T1r, T2r; tdble curzel, curzer, curArc, curLength, curzsl, curzsr; tdble grade; char path[256]; char path2[256]; #define MAX_TMP_INTS 256 int mi[MAX_TMP_INTS]; int ind = 0; radius = arc = length = alf = xr = yr = newxr = newyr = xl = yl = 0; zel = zer = etgtl = etgtr = newxl = newyl = 0; type = 0; width = GfParmGetNum(TrackHandle, section, TRK_ATT_WIDTH, (char*)NULL, 15.0); wi2 = width / 2.0; grade = -100000.0; root = (tTrackSeg*)NULL; totLength = 0; sprintf(path, "%s/%s", section, TRK_LST_SEG); if (start == NULL) { xr = xl = 0.0; yr = 0.0; yl = width; alf = 0.0; zsl = zsr = zel = zer = zs = ze = 0.0; stgt = etgt = 0.0; stgtl = etgtl = 0.0; stgtr = etgtr = 0.0; } else { GfParmListSeekFirst(TrackHandle, path); segtype = GfParmGetCurStr(TrackHandle, path, TRK_ATT_TYPE, ""); if (strcmp(segtype, TRK_VAL_STR) == 0) { } else if (strcmp(segtype, TRK_VAL_LFT) == 0) { } else if (strcmp(segtype, TRK_VAL_RGT) == 0) { xr = start->vertex[TR_SR].x; yr = start->vertex[TR_SR].y; zsl = zsr = zel = zer = zs = ze = start->vertex[TR_SR].z; alf = start->angle[TR_ZS]; xl = xr - width * sin(alf); yl = yr + width * cos(alf); stgt = etgt = 0.0; stgtl = etgtl = 0.0; stgtr = etgtr = 0.0; } } /* Main Track */ material = GfParmGetStr(TrackHandle, section, TRK_ATT_SURF, TRK_VAL_ASPHALT); sprintf(path2, "%s/%s/%s", TRK_SECT_SURFACES, TRK_LST_SURF, material); kFriction = GfParmGetNum(TrackHandle, path2, TRK_ATT_FRICTION, (char*)NULL, 0.8); kRollRes = GfParmGetNum(TrackHandle, path2, TRK_ATT_ROLLRES, (char*)NULL, 0.001); kRoughness = GfParmGetNum(TrackHandle, path2, TRK_ATT_ROUGHT, (char*)NULL, 0.0) / 2.0; kRoughWaveLenP = GfParmGetNum(TrackHandle, path2, TRK_ATT_ROUGHTWL, (char*)NULL, 1.0); kRoughWaveLen = 2.0 * PI / kRoughWaveLenP; envIndex = 0; InitSides(TrackHandle, section); segread = 0; curindex = 0; 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); /* Turn Marks */ if (ext) { char *marks = GfParmGetCurStr(TrackHandle, path, TRK_ATT_MARKS, NULL); ind = 0; if (marks) { marks = strdup(marks); char *s = strtok(marks, ";"); while ((s != NULL) && (ind < MAX_TMP_INTS)) { mi[ind] = (int)strtol(s, NULL, 0); ind++; s = strtok(NULL, ";"); } free(marks); } } /* surface change */ material = GfParmGetCurStr(TrackHandle, path, TRK_ATT_SURF, material); sprintf(path2, "%s/%s/%s", TRK_SECT_SURFACES, TRK_LST_SURF, material); kFriction = GfParmGetNum(TrackHandle, path2, TRK_ATT_FRICTION, (char*)NULL, kFriction); kRollRes = GfParmGetNum(TrackHandle, path2, TRK_ATT_ROLLRES, (char*)NULL, kRollRes); kRoughness = GfParmGetNum(TrackHandle, path2, TRK_ATT_ROUGHT, (char*)NULL, kRoughness * 2.0) / 2.0; kRoughWaveLenP = GfParmGetNum(TrackHandle, path2, TRK_ATT_ROUGHTWL, (char*)NULL, kRoughWaveLenP); kRoughWaveLen = 2.0 * PI / kRoughWaveLenP; envIndex = (int)GfParmGetCurNum(TrackHandle, path, TRK_ATT_ENVIND, (char*)NULL, envIndex+1) - 1; /* get segment type and lenght */ if (strcmp(segtype, TRK_VAL_STR) == 0) { /* straight */ length = GfParmGetCurNum(TrackHandle, path, TRK_ATT_LG, (char*)NULL, 0); type = TR_STR; } 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); type = TR_LFT; length = radius * arc; } 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); type = TR_RGT; length = radius * arc; } segName = GfParmListGetCurEltName(TrackHandle, path); /* elevation and banking */ 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); grade = GfParmGetCurNum(TrackHandle, path, TRK_ATT_GRADE, (char*)NULL, grade); if (zs != -100000.0) { zsr = zsl = zs; } else { zs = (zsl + zsr) / 2.0; } if (ze != -100000.0) { zer = zel = ze; } else if (grade != -100000.0) { ze = zs + length * grade; } else { ze = (zel + zer) / 2.0; } bankings = atan2(zsl - zsr, width); bankinge = atan2(zel - zer, width); bankings = GfParmGetCurNum(TrackHandle, path, TRK_ATT_BKS, (char*)NULL, bankings); bankinge = GfParmGetCurNum(TrackHandle, path, TRK_ATT_BKE, (char*)NULL, bankinge); dz = tan(bankings) * width / 2.0; zsl = zs + dz; zsr = zs - dz; dz = tan(bankinge) * width / 2.0; zel = ze + dz; zer = ze - dz; TSTZ(zsl); TSTZ(zsr); /* Get segment profil */ profil = GfParmGetCurStr(TrackHandle, path, TRK_ATT_PROFIL, TRK_VAL_LINEAR); stgtl = etgtl; stgtr = etgtr; if (strcmp(profil, TRK_VAL_SPLINE) == 0) { steps = (int)GfParmGetCurNum(TrackHandle, path, TRK_ATT_PROFSTEPS, (char*)NULL, 1.0); stgtl = GfParmGetCurNum(TrackHandle, path, TRK_ATT_PROFTGTSL, (char*)NULL, stgtl); etgtl = GfParmGetCurNum(TrackHandle, path, TRK_ATT_PROFTGTEL, (char*)NULL, etgtl); stgtr = GfParmGetCurNum(TrackHandle, path, TRK_ATT_PROFTGTSR, (char*)NULL, stgtr); etgtr = GfParmGetCurNum(TrackHandle, path, TRK_ATT_PROFTGTER, (char*)NULL, etgtr); stgt = etgt = -100000.0; stgt = GfParmGetCurNum(TrackHandle, path, TRK_ATT_PROFTGTS, (char*)NULL, stgt); etgt = GfParmGetCurNum(TrackHandle, path, TRK_ATT_PROFTGTE, (char*)NULL, etgt); if (stgt != -100000.0) { stgtl = stgtr = stgt; } if (etgt != -100000.0) { etgtl = etgtr = etgt; } } else { steps = 1; stgtl = etgtl = (zel - zsl) / length; stgtr = etgtr = (zer - zsr) / length; } GfParmSetCurNum(TrackHandle, path, TRK_ATT_ID, (char*)NULL, (tdble)curindex); dzl = zel - zsl; dzr = zer - zsr; T1l = stgtl * length; T2l = etgtl * length; tl = 0.0; dtl = 1.0 / (tdble)steps; T1r = stgtr * length; T2r = etgtr * length; tr = 0.0; dtr = 1.0 / (tdble)steps; curStep = 0; curzel = zsl; curzer = zsr; curArc = arc / (tdble)steps; curLength = length / (tdble)steps; while (curStep < steps) { tl += dtl; tr += dtr; curzsl = curzel; curzel = TrackSpline(zsl, zel, T1l, T2l, tl); curzsr = curzer; curzer = TrackSpline(zsr, zer, T1r, T2r, tr); /* allocate a new segment */ curSeg = (tTrackSeg*)calloc(1, sizeof(tTrackSeg)); if (root == NULL) { root = curSeg; curSeg->next = curSeg; curSeg->prev = curSeg; } else { curSeg->next = root->next; curSeg->next->prev = curSeg; curSeg->prev = root; root->next = curSeg; root = curSeg; } curSeg->type2 = TR_MAIN; curSeg->name = segName; curSeg->id = curindex; curSeg->width = curSeg->startWidth = curSeg->endWidth = width; curSeg->material = material; curSeg->kFriction = kFriction; curSeg->kRollRes = kRollRes; curSeg->kRoughness = kRoughness; curSeg->kRoughWaveLen = kRoughWaveLen; curSeg->envIndex = envIndex; curSeg->lgfromstart = totLength; if (ext && ind) { int *mrks = (int*)calloc(ind, sizeof(int)); tSegExt *segExt = (tSegExt*)calloc(1, sizeof(tSegExt)); memcpy(mrks, mi, ind*sizeof(int)); segExt->nbMarks = ind; segExt->marks = mrks; curSeg->ext = segExt; ind = 0; } switch (type) { case TR_STR: /* straight */ curSeg->type = TR_STR; curSeg->length = curLength; newxr = xr + curLength * cos(alf); /* find end coordinates */ newyr = yr + curLength * sin(alf); newxl = xl + curLength * cos(alf); newyl = yl + curLength * sin(alf); curSeg->vertex[TR_SR].x = xr; curSeg->vertex[TR_SR].y = yr; curSeg->vertex[TR_SR].z = curzsr; curSeg->vertex[TR_SL].x = xl; curSeg->vertex[TR_SL].y = yl; curSeg->vertex[TR_SL].z = curzsl; curSeg->vertex[TR_ER].x = newxr; curSeg->vertex[TR_ER].y = newyr; curSeg->vertex[TR_ER].z = curzer; curSeg->vertex[TR_EL].x = newxl; curSeg->vertex[TR_EL].y = newyl; curSeg->vertex[TR_EL].z = curzel; 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, curLength); curSeg->angle[TR_YL] = atan2(curSeg->vertex[TR_EL].z - curSeg->vertex[TR_SL].z, curLength); 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]) / curLength; curSeg->Kyl = 0; curSeg->rgtSideNormal.x = -sin(alf); curSeg->rgtSideNormal.y = cos(alf); TSTX(newxr); TSTX(newxl); TSTY(newyr); TSTY(newyl); break; case TR_LFT: /* left curve */ curSeg->type = TR_LFT; curSeg->radius = radius; curSeg->radiusr = radius + wi2; curSeg->radiusl = radius - wi2; curSeg->arc = curArc; curSeg->length = curLength; 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 += curArc; 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 = curzsr; curSeg->vertex[TR_SL].x = xl; curSeg->vertex[TR_SL].y = yl; curSeg->vertex[TR_SL].z = curzsl; curSeg->vertex[TR_ER].x = newxr; curSeg->vertex[TR_ER].y = newyr; curSeg->vertex[TR_ER].z = curzer; curSeg->vertex[TR_EL].x = newxl; curSeg->vertex[TR_EL].y = newyl; curSeg->vertex[TR_EL].z = curzel; curSeg->angle[TR_YR] = atan2(curSeg->vertex[TR_ER].z - curSeg->vertex[TR_SR].z, curArc * (innerradius + width)); curSeg->angle[TR_YL] = atan2(curSeg->vertex[TR_EL].z - curSeg->vertex[TR_SL].z, curArc * 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]) / curArc; 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); } break; case TR_RGT: /* right curve */ curSeg->type = TR_RGT; curSeg->radius = radius; curSeg->radiusr = radius - wi2; curSeg->radiusl = radius + wi2; curSeg->arc = curArc; curSeg->length = curLength; 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 = curzsr; curSeg->vertex[TR_SL].x = xl; curSeg->vertex[TR_SL].y = yl; curSeg->vertex[TR_SL].z = curzsl; curSeg->vertex[TR_ER].x = newxr; curSeg->vertex[TR_ER].y = newyr; curSeg->vertex[TR_ER].z = curzer; curSeg->vertex[TR_EL].x = newxl; curSeg->vertex[TR_EL].y = newyl; curSeg->vertex[TR_EL].z = curzel; curSeg->angle[TR_YR] = atan2(curSeg->vertex[TR_ER].z - curSeg->vertex[TR_SR].z, curArc * innerradius); curSeg->angle[TR_YL] = atan2(curSeg->vertex[TR_EL].z - curSeg->vertex[TR_SL].z, curArc * (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]) / curArc; 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); } break; } AddSides(curSeg, TrackHandle, section, curStep, steps); totLength += curSeg->length; xr = newxr; yr = newyr; xl = newxl; yl = newyl; curindex++; curStep++; } } while (GfParmListSeekNext(TrackHandle, path) == 0); *pRoot = root; *pLength = totLength; *pNseg = curindex; }
// Read parameter meta data from xml file int TGeneticParameter::Get(bool First, const char* Part) { char ParamSection[64]; if (Part == NULL) sprintf(ParamSection,SECT_GLOBAL); else sprintf(ParamSection,"%s",Part); if (First) { GfParmListSeekFirst(Handle, ParamSection); First = false; } else GfParmListSeekNext(Handle, ParamSection); Active = 0 < GfParmGetCurNum(Handle, ParamSection, PRM_ACTIVE, 0, 1); int Flags = GfParmGetCurNum(Handle, ParamSection, PRM_TWOSIDE, 0, 0); if (Flags != 0) { LeftRight = true; if (Flags > 0) SameSign = true; else SameSign = false; } else { SameSign = true; LeftRight = false; } char* Value = (char *) GfParmGetCurStr(Handle, ParamSection, PRM_LABEL, Label); if (Label) free((void *) Label); if (Value) Label = strdup(Value); else Label = NULL; Value = (char *) GfParmGetCurStr(Handle, ParamSection, PRM_SECT, Section); if (Section) free((void *) Section); if (Value) Section = strdup(Value); else Section = NULL; Value = (char *) GfParmGetCurStr(Handle, ParamSection, PRM_PRM, Parameter); if (Parameter) free((void *) Parameter); if (Value) Parameter = strdup(Value); else Parameter = NULL; Value = (char *) GfParmGetCurStr(Handle, ParamSection, PRM_UNIT, Unit); if (Unit) free((void *) Unit); if (Value) Unit = strdup(Value); else Unit = NULL; Min = GfParmGetCurNumMin(Handle, ParamSection, PRM_RANGE, Unit, Min); Max = GfParmGetCurNumMax(Handle, ParamSection, PRM_RANGE, Unit, Max); Val = GfParmGetCurNum(Handle, ParamSection, PRM_RANGE, Unit, Val); Weight = GfParmGetCurNum(Handle, ParamSection, PRM_WEIGHT, 0, Weight); Scale = GfParmGetCurNum(Handle, ParamSection, PRM_SCALE, 0, Scale); Round = GfParmGetCurNum(Handle, ParamSection, PRM_ROUND, 0, Round); Range = Max - Min; Def = LastVal = OptVal = Val; return 0; };
/* Put given player settings (from PlayersInfo array) to the human drivers and preferences params (index is the identification number in params, beginning at 1)*/ static void PutPlayerSettings(unsigned index) { if (!PlayerHdle || !PrefHdle) { return; } tPlayerInfo *player = PlayersInfo[index-1]; // Graphics params (take driver name changes into account for camera settings). char drvSectionPath[128]; snprintf(drvSectionPath, sizeof(drvSectionPath), "%s/%s/%u", ROB_SECT_ROBOTS, ROB_LIST_INDEX, index); const char* pszOldDispName = GfParmGetStr(PlayerHdle, drvSectionPath, ROB_ATTR_NAME, ""); if (strcmp(pszOldDispName, player->dispName())) { // Only if the display name changed. char drvDispSecPath[128]; snprintf(drvDispSecPath, sizeof(drvDispSecPath), "%s/%s", GR_SCT_DISPMODE, pszOldDispName); if (!GraphHdle) // Load graphic params file if not already done. { char pszGraphFileName[256]; snprintf(pszGraphFileName, sizeof(pszGraphFileName), "%s%s", GfLocalDir(), GR_PARAM_FILE); GraphHdle = GfParmReadFile(pszGraphFileName, GFPARM_RMODE_REREAD); } if (GfParmExistsSection(GraphHdle, drvDispSecPath)) { // Change section name. GfParmListRenameElt(GraphHdle, GR_SCT_DISPMODE, pszOldDispName, player->dispName()); } if (!GfParmListSeekFirst(GraphHdle, GR_SCT_DISPMODE)) { do { const char* pszSecName = GfParmListGetCurEltName(GraphHdle, GR_SCT_DISPMODE); if (!pszSecName || !isdigit(*pszSecName)) continue; // Ignore sections whose name is not (likely) a screen id. snprintf(drvDispSecPath, sizeof(drvDispSecPath), "%s/%s", GR_SCT_DISPMODE, pszSecName); const char* pszCurDrvName = GfParmGetStr(GraphHdle, drvDispSecPath, GR_ATT_CUR_DRV, ""); if (!strcmp(pszOldDispName, pszCurDrvName)) // Change current driver name. GfParmSetStr(GraphHdle, drvDispSecPath, GR_ATT_CUR_DRV, player->dispName()); } while (!GfParmListSeekNext(GraphHdle, GR_SCT_DISPMODE)); } } // Human driver params GfParmSetStr(PlayerHdle, drvSectionPath, ROB_ATTR_NAME, player->dispName()); GfParmSetStr(PlayerHdle, drvSectionPath, ROB_ATTR_SNAME, player->dispName()); GfParmSetStr(PlayerHdle, drvSectionPath, ROB_ATTR_CODE, "PLA"); GfParmSetStr(PlayerHdle, drvSectionPath, ROB_ATTR_CAR, player->defaultCarName()); GfParmSetNum(PlayerHdle, drvSectionPath, ROB_ATTR_RACENUM, (char*)NULL, player->raceNumber()); GfParmSetNum(PlayerHdle, drvSectionPath, ROB_ATTR_RED, (char*)NULL, player->color(0)); GfParmSetNum(PlayerHdle, drvSectionPath, ROB_ATTR_GREEN, (char*)NULL, player->color(1)); GfParmSetNum(PlayerHdle, drvSectionPath, ROB_ATTR_BLUE, (char*)NULL, player->color(2)); GfParmSetStr(PlayerHdle, drvSectionPath, ROB_ATTR_TYPE, ROB_VAL_HUMAN); GfParmSetStr(PlayerHdle, drvSectionPath, ROB_ATTR_LEVEL, SkillLevelString[player->skillLevel()]); // Driver preferences params snprintf(drvSectionPath, sizeof(drvSectionPath), "%s/%s/%u", HM_SECT_PREF, HM_LIST_DRV, index); GfParmSetStr(PrefHdle, drvSectionPath, HM_ATT_TRANS, player->gearChangeModeString()); GfParmSetNum(PrefHdle, drvSectionPath, HM_ATT_NBPITS, (char*)NULL, (tdble)player->nbPitStops()); GfParmSetStr(PrefHdle, drvSectionPath, HM_ATT_AUTOREVERSE, Yn[player->autoReverse()]); /* Allow neutral gear in sequential mode if neutral gear command not defined */ if (player->gearChangeMode() == GEAR_MODE_SEQ && !strcmp(GfParmGetStr(PrefHdle, drvSectionPath, HM_ATT_GEAR_N, "-"), "-")) GfParmSetStr(PrefHdle, drvSectionPath, HM_ATT_SEQSHFT_ALLOW_NEUTRAL, HM_VAL_YES); else GfParmSetStr(PrefHdle, drvSectionPath, HM_ATT_SEQSHFT_ALLOW_NEUTRAL, HM_VAL_NO); /* Allow reverse gear in sequential mode if reverse gear command not defined */ if (player->gearChangeMode() == GEAR_MODE_SEQ && !strcmp(GfParmGetStr(PrefHdle, drvSectionPath, HM_ATT_GEAR_R, "-"), "-")) GfParmSetStr(PrefHdle, drvSectionPath, HM_ATT_SEQSHFT_ALLOW_REVERSE, HM_VAL_YES); else GfParmSetStr(PrefHdle, drvSectionPath, HM_ATT_SEQSHFT_ALLOW_REVERSE, HM_VAL_NO); /* Release gear lever goes neutral in grid mode if no neutral gear command defined */ if (player->gearChangeMode() == GEAR_MODE_GRID && !strcmp(GfParmGetStr(PrefHdle, drvSectionPath, HM_ATT_GEAR_N, "-"), "-")) GfParmSetStr(PrefHdle, drvSectionPath, HM_ATT_REL_BUT_NEUTRAL, HM_VAL_YES); else GfParmSetStr(PrefHdle, drvSectionPath, HM_ATT_REL_BUT_NEUTRAL, HM_VAL_NO); }
void GfFileSetup() { void *dataVersionHandle; void *localVersionHandle; char *filename; size_t filenameLength; char *dataLocation; char *localLocation; char *absLocalLocation; char *absDataLocation; bool *isIndexUsed; int isIndexUsedLen; int index; bool anyLocalChange, fileFound; int major; int minor; struct stat st; // Open data (installation) version.xml. filenameLength = strlen(GfDataDir()) + 12 + 40; filename = (char*)malloc( sizeof(char) * filenameLength ); sprintf( filename, "%sversion.xml", GfDataDir() ); dataVersionHandle = GfParmReadFile( filename, GFPARM_RMODE_STD ); if( !dataVersionHandle ) { free( filename ); return; } // Exit if nothing inside. if( GfParmListSeekFirst( dataVersionHandle, "versions" ) != 0 ) { free( filename ); GfParmReleaseHandle( dataVersionHandle ); return; } // Create LocalDir (user settings root) if not already done. GfDirCreate( GfLocalDir() ); // Open local (user settings) version.xml (create it if not there). if( filenameLength < strlen(GfLocalDir()) + 12 ) { free( filename ); filenameLength = strlen(GfLocalDir()) + 12 + 40; filename = (char*)malloc( sizeof(char) * filenameLength ); } sprintf( filename, "%sversion.xml", GfLocalDir() ); anyLocalChange = !GfFileExists(filename); localVersionHandle = GfParmReadFile( filename, GFPARM_RMODE_CREAT ); // Exit if open/creation failed. if( !localVersionHandle ) { free( filename ); GfParmReleaseHandle( dataVersionHandle ); return; } // Setup the index of the XML files referenced in the local version.xml. isIndexUsedLen = GfParmGetEltNb( localVersionHandle, "versions" ) + GfParmGetEltNb( dataVersionHandle, "versions" ) + 2; isIndexUsed = (bool*)malloc( sizeof(bool) * isIndexUsedLen ); for( index = 0; index < isIndexUsedLen; index++ ) isIndexUsed[index] = false; if( GfParmListSeekFirst( localVersionHandle, "versions" ) == 0 ) { do { index = atoi( GfParmListGetCurEltName( localVersionHandle, "versions" ) ); if( 0 <= index && index < isIndexUsedLen ) isIndexUsed[index] = true; } while( GfParmListSeekNext( localVersionHandle, "versions" ) == 0 ); } // For each file referenced in the installation version.xml do { fileFound = false; // Get its installation path (data), user settings path (local), // and new major and minor version numbers dataLocation = strdup( GfParmGetCurStr( dataVersionHandle, "versions", "Data location", "" ) ); localLocation = strdup( GfParmGetCurStr( dataVersionHandle, "versions", "Local location", "" ) ); major = (int)GfParmGetCurNum( dataVersionHandle, "versions", "Major version", NULL, 0 ); minor = (int)GfParmGetCurNum( dataVersionHandle, "versions", "Minor version", NULL, 0 ); absLocalLocation = (char*)malloc( sizeof(char)*(strlen(GfLocalDir())+strlen(localLocation)+3) ); sprintf( absLocalLocation, "%s%s", GfLocalDir(), localLocation ); absDataLocation = (char*)malloc( sizeof(char)*(strlen(GfDataDir())+strlen(dataLocation)+3) ); sprintf( absDataLocation, "%s%s", GfDataDir(), dataLocation ); GfLogTrace("Checking %s : user settings version ", localLocation); // Search for its old major and minor version numbers in the user settings. if( GfParmListSeekFirst( localVersionHandle, "versions" ) == 0 ) { do { if( strcmp( absLocalLocation, GfParmGetCurStr( localVersionHandle, "versions", "Local location", "" ) ) == 0 ) { fileFound = true; const int locMinor = (int)GfParmGetCurNum( localVersionHandle, "versions", "Minor version", NULL, 0 ); const int locMajor = (int)GfParmGetCurNum( localVersionHandle, "versions", "Major version", NULL, 0 ); GfLogTrace("%d.%d is ", locMajor, locMinor); if( locMajor != major || locMinor < minor) { GfLogTrace("obsolete (installed one is %d.%d) => updating ...\n", major, minor); if ( gfFileSetupCopy( absDataLocation, absLocalLocation, major, minor, localVersionHandle, -1 ) ) anyLocalChange = true; } else { GfLogTrace("up-to-date"); if (stat(absLocalLocation, &st)) { GfLogTrace(", but not there => installing ...\n"); if ( gfFileSetupCopy( absDataLocation, absLocalLocation, major, minor, localVersionHandle, -1 ) ) anyLocalChange = true; } else GfLogTrace(".\n"); } break; } } while( GfParmListSeekNext( localVersionHandle, "versions" ) == 0 ); } if( !fileFound) { index = 0; while( isIndexUsed[index] ) ++index; GfLogTrace("not found => installing ...\n"); if ( gfFileSetupCopy( absDataLocation, absLocalLocation, major, minor, localVersionHandle, index ) ) anyLocalChange = true; isIndexUsed[index] = true; } free( dataLocation ); free( localLocation ); free( absDataLocation ); free( absLocalLocation ); } while( GfParmListSeekNext( dataVersionHandle, "versions" ) == 0 ); // Write the user settings version.xml if changed. if (anyLocalChange) GfParmWriteFile( NULL, localVersionHandle, "versions" ); GfParmReleaseHandle( localVersionHandle ); GfParmReleaseHandle( dataVersionHandle ); free( isIndexUsed ); free( filename ); }
/** * This function initialize some values which can only be done after the track is loaded. * * This function for example defines the sector start and ends * * @param TrackHandle The handle containing the information about the track */ static void FinishTrackLoading(void* TrackHandle) { double *distances = NULL; double currentDistance; double tmpDistance; int currentLength; int xx; theTrack->numberOfSectors = GfParmGetEltNb(TrackHandle, TRK_SECT_SECTORS); if (theTrack->numberOfSectors < 0) theTrack->numberOfSectors = 0; //TODO(kilo): possible divison by zero!!! if (theTrack->length / (double)theTrack->numberOfSectors < 100.0f ) { theTrack->numberOfSectors = (int)floor( theTrack->length / 100.0f ); GfOut( "WARNING: too many sectors" ); } if (theTrack->numberOfSectors == 0) { /* Default is: * 1 sector on circuits of 1km or shorter * 3 sectors on circuits between 1km and 6km * the minimum number of sectors such that every sector is at most 2km if the track is longer then 6km * * Note: the sector end at start-finish is added later */ if (theTrack->length < 1000.0f) theTrack->numberOfSectors = 0; else if(theTrack->length < 6000.0f) theTrack->numberOfSectors = 2; else theTrack->numberOfSectors = (int)floor( theTrack->length / 2000.0f ); if (theTrack->numberOfSectors > 0) { distances = (double*)malloc( sizeof( double ) * theTrack->numberOfSectors ); for( xx = 0; xx < theTrack->numberOfSectors; ++xx ) distances[ xx ] = theTrack->length * (double)(xx + 1) / (double)(theTrack->numberOfSectors + 1); } } else { distances = (double*)malloc( sizeof( double ) * theTrack->numberOfSectors ); currentLength = 0; if (GfParmListSeekFirst( TrackHandle, TRK_SECT_SECTORS ) == 0) { do { currentDistance = GfParmGetCurNum( TrackHandle, TRK_SECT_SECTORS, TRK_ATT_SECTOR_DFS, NULL, 0.0f); if (currentDistance <= 0.0f || currentDistance >= theTrack->length) continue; /* Don't add the startline as sector */ for (xx = 0; xx < currentLength; ++xx) { if (distances[xx] > currentDistance) { tmpDistance = distances[xx]; distances[xx] = currentDistance; currentDistance = tmpDistance; } } distances[currentLength] = currentDistance; ++currentLength; } while (GfParmListSeekNext(TrackHandle, TRK_SECT_SECTORS) == 0); } theTrack->numberOfSectors = currentLength; } /* All know, now allocte the structures with the right size */ if (theTrack->numberOfSectors > 0) { theTrack->sectors = (double*)malloc( sizeof(double) * theTrack->numberOfSectors ); for( xx = 0; xx < theTrack->numberOfSectors; ++xx ) theTrack->sectors[xx] = distances[xx]; } else { theTrack->sectors = NULL; } /* Add the finish line as last sector */ ++theTrack->numberOfSectors; /* Free unused memory */ if (distances) free( distances ); }