TORCS  1.3.10
The Open Racing Car Simulator
Loading...
Searching...
No Matches
track3.cpp
Go to the documentation of this file.
1/***************************************************************************
2
3 file : track3.cpp
4 created : Fri Aug 31 20:32:33 /etc/localtime 2001
5 copyright : (C) 2001 by Eric Espie
6 email : eric.espie@torcs.org
7 version : $Id$
8
9 ***************************************************************************/
10
11/***************************************************************************
12 * *
13 * This program is free software; you can redistribute it and/or modify *
14 * it under the terms of the GNU General Public License as published by *
15 * the Free Software Foundation; either version 2 of the License, or *
16 * (at your option) any later version. *
17 * *
18 ***************************************************************************/
19
20#include <stdlib.h>
21#include <math.h>
22#include <stdio.h>
23
24#include <tgf.h>
25#include <robottools.h>
26#include <track.h>
27#include <portability.h>
28#include "trackinc.h"
29
31
32#define TSTX(x) \
33 if (xmin > (x)) xmin = (x); \
34 if (xmax < (x)) xmax = (x);
35
36#define TSTY(y) \
37 if (ymin > (y)) ymin = (y); \
38 if (ymax < (y)) ymax = (y);
39
40#define TSTZ(z) \
41 if (zmin > (z)) zmin = (z); \
42 if (zmax < (z)) zmax = (z);
43
44/*
45 * Sides global variables
46 */
47static const char *KeySideSurface[2] = {TRK_ATT_RSSURF, TRK_ATT_LSSURF};
48static const char *KeySideWidth[2] = {TRK_ATT_RSW, TRK_ATT_LSW};
49static const char *KeySideStartWidth[2] = {TRK_ATT_RSWS, TRK_ATT_LSWS};
50static const char *KeySideEndWidth[2] = {TRK_ATT_RSWE, TRK_ATT_LSWE};
51static const char *KeySideBankType[2] = {TRK_ATT_RST, TRK_ATT_LST};
52
54static const char *KeyBorderWidth[2] = {TRK_ATT_RBW, TRK_ATT_LBW};
55static const char *KeyBorderStyle[2] = {TRK_ATT_RBS, TRK_ATT_LBS};
56static const char *KeyBorderHeight[2] = {TRK_ATT_RBH, TRK_ATT_LBH};
57
59static const char *KeyBarrierWidth[2] = {TRK_ATT_RBAW, TRK_ATT_LBAW};
60static const char *KeyBarrierStyle[2] = {TRK_ATT_RBAS, TRK_ATT_LBAS};
61static const char *KeyBarrierHeight[2] = {TRK_ATT_RBAH, TRK_ATT_LBAH};
62
64
65
68static int sideBankType[2];
69static const char *sideMaterial[2];
71
72
73static int envIndex;
74
77static int borderStyle[2];
78static const char *borderMaterial[2];
80
83static int barrierStyle[2];
84static const char *barrierMaterial[2];
86
88
89static tTrackSurface*
90AddTrackSurface(void *TrackHandle, tTrack *theTrack, const char *material)
91{
92 const int BUFSIZE = 256;
93 char path[BUFSIZE];
94 tTrackSurface *curSurf;
95
96 /* search within existing surfaces */
97 curSurf = theTrack->surfaces;
98 while (curSurf) {
99 if (strcmp(curSurf->material, material) == 0) {
100 return curSurf;
101 }
102 curSurf = curSurf->next;
103 }
104
105 /* Create a new surface */
106 curSurf = (tTrackSurface*)malloc(sizeof(tTrackSurface));
107 if (!curSurf) {
108 GfFatal("AddTrackSurface: Memory allocation failed\n");
109 }
110
111 curSurf->material = material;
112 snprintf(path, BUFSIZE, "%s/%s/%s", TRK_SECT_SURFACES, TRK_LST_SURF, material);
113 curSurf->kFriction = GfParmGetNum(TrackHandle, path, TRK_ATT_FRICTION, (char*)NULL, 0.8f);
114 curSurf->kRollRes = GfParmGetNum(TrackHandle, path, TRK_ATT_ROLLRES, (char*)NULL, 0.001f);
115 curSurf->kRoughness = GfParmGetNum(TrackHandle, path, TRK_ATT_ROUGHT, (char*)NULL, 0.0f) / 2.0f;
116 curSurf->kRoughWaveLen = 2.0 * PI / GfParmGetNum(TrackHandle, path, TRK_ATT_ROUGHTWL, (char*)NULL, 1.0f);
117 curSurf->kDammage = GfParmGetNum(TrackHandle, path, TRK_ATT_DAMMAGE, (char*)NULL, 10.0f);
118 curSurf->kRebound = GfParmGetNum(TrackHandle, path, TRK_ATT_REBOUND, (char*)NULL, 1.0f);
119
120 curSurf->next = theTrack->surfaces;
121 theTrack->surfaces = curSurf;
122
123 return curSurf;
124}
125
126
127static void
129{
130 int side;
131
132 for (side = 0; side < 2; side++) {
135 sideEndWidth[side] = GfParmGetNum(TrackHandle, TRK_SECT_MAIN, KeySideWidth[side], (char*)NULL, 0.0);
136
137 /* banking of borders */
139 sideBankType[side] = 0;
140 } else {
141 sideBankType[side] = 1;
142 }
143
146 borderWidth[side] = GfParmGetNum(TrackHandle, TRK_SECT_MAIN, KeyBorderWidth[side], (char*)NULL, 0.0);
147 borderHeight[side] = GfParmGetNum(TrackHandle, TRK_SECT_MAIN, KeyBorderHeight[side], (char*)NULL, 0.0);
149
150 if (strcmp(style, TRK_VAL_PLAN) == 0) {
151 borderStyle[side] = TR_PLAN;
152 } else if (strcmp(style, TRK_VAL_CURB) == 0) {
153 borderStyle[side] = TR_CURB;
154 } else {
155 borderStyle[side] = TR_WALL;
156 }
157
158 /* Barrier parameters */
161 barrierHeight[side] = GfParmGetNum(TrackHandle, TRK_SECT_MAIN, KeyBarrierHeight[side], (char*)NULL, 1.0);
163
164 if (strcmp(style, TRK_VAL_FENCE) == 0) {
165 barrierStyle[side] = TR_FENCE;
166 barrierWidth[side] = 0;
167 } else {
168 barrierStyle[side] = TR_WALL;
169 barrierWidth[side] = GfParmGetNum(TrackHandle, TRK_SECT_MAIN, KeyBarrierWidth[side], (char*)NULL, 0.5);
170 }
171 }
172}
173
174
175static void
176AddSides(tTrackSeg *curSeg, void *TrackHandle, tTrack *theTrack, int curStep, int steps)
177{
178 tTrackSeg *curSide;
179 tTrackSeg *mSeg;
180 tTrackSeg *curBorder;
181 tTrackBarrier *curBarrier;
182 tdble x, y, z;
183 tdble al, alfl;
184 int j;
185 tdble x1, x2, y1, y2;
186 tdble sw, ew, bw;
187 tdble minWidth;
188 tdble maxWidth;
189 int type;
190 int side;
191 tdble Kew;
192 const int BUFSIZE = 256;
193 char path[BUFSIZE];
194
195 x = y = z = 0;
196 mSeg = curSeg;
197
198 snprintf(path, BUFSIZE, "%s/%s", TRK_SECT_MAIN, TRK_LST_SEG);
199 for (side = 0; side < 2; side++) {
200 curSeg = mSeg;
201 if (curStep == 0) {
202 /* Side parameters */
203 sw = GfParmGetCurNum(TrackHandle, path, KeySideStartWidth[side], (char*)NULL, sideEndWidth[side]);
204 ew = GfParmGetCurNum(TrackHandle, path, KeySideEndWidth[side], (char*)NULL, sw);
205 sideStartWidth[side] = sw;
206 sideEndWidth[side] = ew;
209
210 /* Border parameters */
211 bw = GfParmGetCurNum(TrackHandle, path, KeyBorderWidth[side], (char*)NULL, borderWidth[side]);
212 borderWidth[side] = bw;
213 borderHeight[side] = GfParmGetCurNum(TrackHandle, path, KeyBorderHeight[side], (char*)NULL, 0.0);
216 const char* style = GfParmGetCurStr(TrackHandle, path, KeyBorderStyle[side], ValStyle[borderStyle[side]]);
217 if (strcmp(style, TRK_VAL_PLAN) == 0) {
218 borderStyle[side] = TR_PLAN;
219 } else if (strcmp(style, TRK_VAL_CURB) == 0) {
220 borderStyle[side] = TR_CURB;
221 } else {
222 borderStyle[side] = TR_WALL;
223 }
224
225 /* Barrier parameters */
230 if (strcmp(style, TRK_VAL_FENCE) == 0) {
231 barrierStyle[side] = TR_FENCE;
232 barrierWidth[side] = 0;
233 } else {
234 barrierStyle[side] = TR_WALL;
236 }
237 } else {
238 sw = sideStartWidth[side];
239 ew = sideEndWidth[side];
240 bw = borderWidth[side];
241 }
242 Kew = (ew - sw) / (tdble)steps;
243 ew = sw + (tdble)(curStep+1) * Kew;
244 sw = sw + (tdble)(curStep) * Kew;
245
246 /* Borders */
247 if (bw != 0.0) {
248 curBorder = (tTrackSeg*)calloc(1, sizeof(tTrackSeg));
249 if (side == 1) {
250 curSeg->lside = curBorder;
251 curBorder->vertex[TR_SR] = curSeg->vertex[TR_SL];
252 curBorder->vertex[TR_ER] = curSeg->vertex[TR_EL];
253 curBorder->type2 = TR_LBORDER;
254 } else {
255 curSeg->rside = curBorder;
256 curBorder->vertex[TR_SL] = curSeg->vertex[TR_SR];
257 curBorder->vertex[TR_EL] = curSeg->vertex[TR_ER];
258 curBorder->type2 = TR_RBORDER;
259 }
260
261 type = sideBankType[side];
262 curBorder->startWidth = bw;
263 curBorder->endWidth = bw;
264 curBorder->width = bw;
265 curBorder->type = curSeg->type;
266 curBorder->surface = borderSurface[side];
267 curBorder->height = borderHeight[side];
268 curBorder->style = borderStyle[side];
269 curBorder->envIndex = envIndex;
270 curBorder->angle[TR_XS] = curSeg->angle[TR_XS] * (tdble)type;
271 curBorder->angle[TR_XE] = curSeg->angle[TR_XE] * (tdble)type;
272 curBorder->angle[TR_ZS] = curSeg->angle[TR_ZS];
273 curBorder->angle[TR_ZE] = curSeg->angle[TR_ZE];
274 curBorder->angle[TR_CS] = curSeg->angle[TR_CS];
275
276 switch(curSeg->type) {
277 case TR_STR:
278 curBorder->length = curSeg->length;
279
280 switch(side) {
281 case 1:
282 curBorder->vertex[TR_SL].x = curBorder->vertex[TR_SR].x + bw * curSeg->rgtSideNormal.x;
283 curBorder->vertex[TR_SL].y = curBorder->vertex[TR_SR].y + bw * curSeg->rgtSideNormal.y;
284 curBorder->vertex[TR_SL].z = curBorder->vertex[TR_SR].z + (tdble)type * bw * tan(curSeg->angle[TR_XS]);
285 x = curBorder->vertex[TR_EL].x = curBorder->vertex[TR_ER].x + bw * curSeg->rgtSideNormal.x;
286 y = curBorder->vertex[TR_EL].y = curBorder->vertex[TR_ER].y + bw * curSeg->rgtSideNormal.y;
287 z = curBorder->vertex[TR_EL].z = curBorder->vertex[TR_ER].z + (tdble)type * bw * tan(curSeg->angle[TR_XE]);
288 break;
289 case 0:
290 curBorder->vertex[TR_SR].x = curBorder->vertex[TR_SL].x - bw * curSeg->rgtSideNormal.x;
291 curBorder->vertex[TR_SR].y = curBorder->vertex[TR_SL].y - bw * curSeg->rgtSideNormal.y;
292 curBorder->vertex[TR_SR].z = curBorder->vertex[TR_SL].z - (tdble)type * bw * tan(curSeg->angle[TR_XS]);
293 x = curBorder->vertex[TR_ER].x = curBorder->vertex[TR_EL].x - bw * curSeg->rgtSideNormal.x;
294 y = curBorder->vertex[TR_ER].y = curBorder->vertex[TR_EL].y - bw * curSeg->rgtSideNormal.y;
295 z = curBorder->vertex[TR_ER].z = curBorder->vertex[TR_EL].z - (tdble)type * bw * tan(curSeg->angle[TR_XE]);
296 break;
297 }
298 curBorder->angle[TR_YR] = atan2(curBorder->vertex[TR_ER].z - curBorder->vertex[TR_SR].z, curBorder->length);
299 curBorder->angle[TR_YL] = atan2(curBorder->vertex[TR_EL].z - curBorder->vertex[TR_SL].z, curBorder->length);
300
301 curBorder->Kzl = tan(curBorder->angle[TR_YR]);
302 curBorder->Kzw = (curBorder->angle[TR_XE] - curBorder->angle[TR_XS]) / curBorder->length;
303 curBorder->Kyl = 0;
304
305 curBorder->rgtSideNormal.x = curSeg->rgtSideNormal.x;
306 curBorder->rgtSideNormal.y = curSeg->rgtSideNormal.y;
307
308 TSTX(x);
309 TSTY(y);
310 TSTZ(z);
311 break;
312
313 case TR_LFT:
314 curBorder->center.x = curSeg->center.x;
315 curBorder->center.y = curSeg->center.y;
316
317 switch(side) {
318 case 1:
319 curBorder->radius = curSeg->radiusl - bw / 2.0;
320 curBorder->radiusr = curSeg->radiusl;
321 curBorder->radiusl = curSeg->radiusl - bw;
322 curBorder->arc = curSeg->arc;
323 curBorder->length = curBorder->radius * curBorder->arc;
324
325 curBorder->vertex[TR_SL].x = curBorder->vertex[TR_SR].x - bw * cos(curBorder->angle[TR_CS]);
326 curBorder->vertex[TR_SL].y = curBorder->vertex[TR_SR].y - bw * sin(curBorder->angle[TR_CS]);
327 curBorder->vertex[TR_SL].z = curBorder->vertex[TR_SR].z + (tdble)type * bw * tan(curSeg->angle[TR_XS]);
328 curBorder->vertex[TR_EL].x = curBorder->vertex[TR_ER].x - bw * cos(curBorder->angle[TR_CS] + curBorder->arc);
329 curBorder->vertex[TR_EL].y = curBorder->vertex[TR_ER].y - (tdble)type * bw * sin(curBorder->angle[TR_CS] + curBorder->arc);
330 z = curBorder->vertex[TR_EL].z = curBorder->vertex[TR_ER].z + bw * tan(curSeg->angle[TR_XE]);
331
332 curBorder->angle[TR_YR] = atan2(curBorder->vertex[TR_ER].z - curBorder->vertex[TR_SR].z,
333 curBorder->arc * curBorder->radiusr);
334 curBorder->angle[TR_YL] = atan2(curBorder->vertex[TR_EL].z - curBorder->vertex[TR_SL].z,
335 curBorder->arc * curBorder->radiusl);
336
337 curBorder->Kzl = tan(curBorder->angle[TR_YR]) * curBorder->radiusr;
338 curBorder->Kzw = (curBorder->angle[TR_XE] - curBorder->angle[TR_XS]) / curBorder->arc;
339 curBorder->Kyl = 0;
340
341 /* to find the boundary */
342 al = (curBorder->angle[TR_ZE] - curBorder->angle[TR_ZS])/36.0;
343 alfl = curBorder->angle[TR_ZS];
344
345 for (j = 0; j < 36; j++) {
346 alfl += al;
347 x1 = curBorder->center.x + (curBorder->radiusl) * sin(alfl); /* location of end */
348 y1 = curBorder->center.y - (curBorder->radiusl) * cos(alfl);
349 TSTX(x1);
350 TSTY(y1);
351 }
352 TSTZ(z);
353 break;
354
355 case 0:
356 curBorder->radius = curSeg->radiusr + bw / 2.0;
357 curBorder->radiusl = curSeg->radiusr;
358 curBorder->radiusr = curSeg->radiusr + bw;
359 curBorder->arc = curSeg->arc;
360 curBorder->length = curBorder->radius * curBorder->arc;
361
362 curBorder->vertex[TR_SR].x = curBorder->vertex[TR_SL].x + bw * cos(curBorder->angle[TR_CS]);
363 curBorder->vertex[TR_SR].y = curBorder->vertex[TR_SL].y + bw * sin(curBorder->angle[TR_CS]);
364 curBorder->vertex[TR_SR].z = curBorder->vertex[TR_SL].z - (tdble)type * bw * tan(curSeg->angle[TR_XS]);
365 curBorder->vertex[TR_ER].x = curBorder->vertex[TR_EL].x + bw * cos(curBorder->angle[TR_CS] + curBorder->arc);
366 curBorder->vertex[TR_ER].y = curBorder->vertex[TR_EL].y + bw * sin(curBorder->angle[TR_CS] + curBorder->arc);
367 z = curBorder->vertex[TR_ER].z = curBorder->vertex[TR_EL].z - (tdble)type * bw * tan(curSeg->angle[TR_XE]);
368
369 curBorder->angle[TR_YR] = atan2(curBorder->vertex[TR_ER].z - curBorder->vertex[TR_SR].z,
370 curBorder->arc * curBorder->radiusr);
371 curBorder->angle[TR_YL] = atan2(curBorder->vertex[TR_EL].z - curBorder->vertex[TR_SL].z,
372 curBorder->arc * curBorder->radiusl);
373
374 curBorder->Kzl = tan(curBorder->angle[TR_YR]) * (curBorder->radiusr);
375 curBorder->Kzw = (curBorder->angle[TR_XE] - curBorder->angle[TR_XS]) / curBorder->arc;
376 curBorder->Kyl = 0;
377
378 /* to find the boundary */
379 al = (curBorder->angle[TR_ZE] - curBorder->angle[TR_ZS])/36.0;
380 alfl = curBorder->angle[TR_ZS];
381
382 for (j = 0; j < 36; j++) {
383 alfl += al;
384 x2 = curBorder->center.x + (curBorder->radiusr) * sin(alfl); /* location of end */
385 y2 = curBorder->center.y - (curBorder->radiusr) * cos(alfl);
386 TSTX(x2);
387 TSTY(y2);
388 }
389 TSTZ(z);
390 break;
391
392 }
393 break;
394 case TR_RGT:
395 curBorder->center.x = curSeg->center.x;
396 curBorder->center.y = curSeg->center.y;
397
398 switch(side) {
399 case 1:
400 curBorder->radius = curSeg->radiusl + bw / 2.0;
401 curBorder->radiusr = curSeg->radiusl;
402 curBorder->radiusl = curSeg->radiusl + bw;
403 curBorder->arc = curSeg->arc;
404 curBorder->length = curBorder->radius * curBorder->arc;
405
406 curBorder->vertex[TR_SL].x = curBorder->vertex[TR_SR].x + bw * cos(curBorder->angle[TR_CS]);
407 curBorder->vertex[TR_SL].y = curBorder->vertex[TR_SR].y + bw * sin(curBorder->angle[TR_CS]);
408 curBorder->vertex[TR_SL].z = curBorder->vertex[TR_SR].z + (tdble)type * bw * tan(curSeg->angle[TR_XS]);
409 curBorder->vertex[TR_EL].x = curBorder->vertex[TR_ER].x + bw * cos(curBorder->angle[TR_CS] - curBorder->arc);
410 curBorder->vertex[TR_EL].y = curBorder->vertex[TR_ER].y + bw * sin(curBorder->angle[TR_CS] - curBorder->arc);
411 z = curBorder->vertex[TR_EL].z = curBorder->vertex[TR_ER].z + (tdble)type * bw * tan(curSeg->angle[TR_XE]);
412
413 curBorder->angle[TR_YR] = atan2(curBorder->vertex[TR_ER].z - curBorder->vertex[TR_SR].z,
414 curBorder->arc * curBorder->radiusr);
415 curBorder->angle[TR_YL] = atan2(curBorder->vertex[TR_EL].z - curBorder->vertex[TR_SL].z,
416 curBorder->arc * curBorder->radiusl);
417
418 curBorder->Kzl = tan(curBorder->angle[TR_YR]) * curBorder->radiusr;
419 curBorder->Kzw = (curBorder->angle[TR_XE] - curBorder->angle[TR_XS]) / curBorder->arc;
420 curBorder->Kyl = 0;
421
422 /* to find the boundary */
423 al = (curBorder->angle[TR_ZE] - curBorder->angle[TR_ZS])/36.0;
424 alfl = curBorder->angle[TR_ZS];
425
426 for (j = 0; j < 36; j++) {
427 alfl += al;
428 x1 = curBorder->center.x - (curBorder->radiusl) * sin(alfl); /* location of end */
429 y1 = curBorder->center.y + (curBorder->radiusl) * cos(alfl);
430 TSTX(x1);
431 TSTY(y1);
432 }
433 TSTZ(z);
434 break;
435
436 case 0:
437 curBorder->radius = curSeg->radiusr - bw / 2.0;
438 curBorder->radiusl = curSeg->radiusr;
439 curBorder->radiusr = curSeg->radiusr - bw;
440 curBorder->arc = curSeg->arc;
441 curBorder->length = curBorder->radius * curBorder->arc;
442
443 curBorder->vertex[TR_SR].x = curBorder->vertex[TR_SL].x - bw * cos(curBorder->angle[TR_CS]);
444 curBorder->vertex[TR_SR].y = curBorder->vertex[TR_SL].y - bw * sin(curBorder->angle[TR_CS]);
445 curBorder->vertex[TR_SR].z = curBorder->vertex[TR_SL].z - (tdble)type * bw * tan(curSeg->angle[TR_XS]);
446 curBorder->vertex[TR_ER].x = curBorder->vertex[TR_EL].x - bw * cos(curBorder->angle[TR_CS] - curBorder->arc);
447 curBorder->vertex[TR_ER].y = curBorder->vertex[TR_EL].y - bw * sin(curBorder->angle[TR_CS] - curBorder->arc);
448 z = curBorder->vertex[TR_ER].z = curBorder->vertex[TR_EL].z - (tdble)type * bw * tan(curSeg->angle[TR_XE]);
449
450 curBorder->angle[TR_YR] = atan2(curBorder->vertex[TR_ER].z - curBorder->vertex[TR_SR].z,
451 curBorder->arc * curBorder->radiusr);
452 curBorder->angle[TR_YL] = atan2(curBorder->vertex[TR_EL].z - curBorder->vertex[TR_SL].z,
453 curBorder->arc * curBorder->radiusl);
454
455 curBorder->Kzl = tan(curBorder->angle[TR_YR]) * (curBorder->radiusr);
456 curBorder->Kzw = (curBorder->angle[TR_XE] - curBorder->angle[TR_XS]) / curBorder->arc;
457 curBorder->Kyl = 0;
458
459 /* to find the boundary */
460 al = (curBorder->angle[TR_ZE] - curBorder->angle[TR_ZS])/36.0;
461 alfl = curBorder->angle[TR_ZS];
462
463 for (j = 0; j < 36; j++) {
464 alfl += al;
465 x2 = curBorder->center.x - (curBorder->radiusr) * sin(alfl); /* location of end */
466 y2 = curBorder->center.y - (curBorder->radiusr) * cos(alfl);
467 TSTX(x2);
468 TSTY(y2);
469 }
470 TSTZ(z);
471 break;
472 }
473 break;
474 }
475
476 curSeg = curBorder;
477 }
478
479
480 /* Sides */
481 if ((sw != 0.0) || (ew != 0)) {
482 curSide = (tTrackSeg*)calloc(1, sizeof(tTrackSeg));
483 if (side == 1) {
484 curSeg->lside = curSide;
485 curSide->vertex[TR_SR] = curSeg->vertex[TR_SL];
486 curSide->vertex[TR_ER] = curSeg->vertex[TR_EL];
487 curSide->type2 = TR_LSIDE;
488 } else {
489 curSeg->rside = curSide;
490 curSide->vertex[TR_SL] = curSeg->vertex[TR_SR];
491 curSide->vertex[TR_EL] = curSeg->vertex[TR_ER];
492 curSide->type2 = TR_RSIDE;
493 }
494
495 type = sideBankType[side];
496 curSide->startWidth = sw;
497 curSide->endWidth = ew;
498 curSide->width = minWidth = MIN(sw, ew);
499 maxWidth = MAX(sw, ew);
500 curSide->type = curSeg->type;
501 curSide->surface = sideSurface[side];
502 curSide->envIndex = envIndex;
503 curSide->angle[TR_XS] = curSeg->angle[TR_XS] * (tdble)type;
504 curSide->angle[TR_XE] = curSeg->angle[TR_XE] * (tdble)type;
505 curSide->angle[TR_ZS] = curSeg->angle[TR_ZS];
506 curSide->angle[TR_ZE] = curSeg->angle[TR_ZE];
507 curSide->angle[TR_CS] = curSeg->angle[TR_CS];
508
509 switch(curSeg->type) {
510 case TR_STR:
511 curSide->length = curSeg->length;
512
513 switch(side) {
514 case 1:
515 curSide->vertex[TR_SL].x = curSide->vertex[TR_SR].x + sw * curSeg->rgtSideNormal.x;
516 curSide->vertex[TR_SL].y = curSide->vertex[TR_SR].y + sw * curSeg->rgtSideNormal.y;
517 curSide->vertex[TR_SL].z = curSide->vertex[TR_SR].z + (tdble)type * sw * tan(curSeg->angle[TR_XS]);
518 x = curSide->vertex[TR_EL].x = curSide->vertex[TR_ER].x + ew * curSeg->rgtSideNormal.x;
519 y = curSide->vertex[TR_EL].y = curSide->vertex[TR_ER].y + ew * curSeg->rgtSideNormal.y;
520 z = curSide->vertex[TR_EL].z = curSide->vertex[TR_ER].z + (tdble)type * ew * tan(curSeg->angle[TR_XE]);
521 break;
522 case 0:
523 curSide->vertex[TR_SR].x = curSide->vertex[TR_SL].x - sw * curSeg->rgtSideNormal.x;
524 curSide->vertex[TR_SR].y = curSide->vertex[TR_SL].y - sw * curSeg->rgtSideNormal.y;
525 curSide->vertex[TR_SR].z = curSide->vertex[TR_SL].z - (tdble)type * sw * tan(curSeg->angle[TR_XS]);
526 x = curSide->vertex[TR_ER].x = curSide->vertex[TR_EL].x - ew * curSeg->rgtSideNormal.x;
527 y = curSide->vertex[TR_ER].y = curSide->vertex[TR_EL].y - ew * curSeg->rgtSideNormal.y;
528 z = curSide->vertex[TR_ER].z = curSide->vertex[TR_EL].z - (tdble)type * ew * tan(curSeg->angle[TR_XE]);
529 break;
530 }
531 curSide->angle[TR_YR] = atan2(curSide->vertex[TR_ER].z - curSide->vertex[TR_SR].z, curSide->length);
532 curSide->angle[TR_YL] = atan2(curSide->vertex[TR_EL].z - curSide->vertex[TR_SL].z, curSide->length);
533
534 curSide->Kzl = tan(curSide->angle[TR_YR]);
535 curSide->Kzw = (curSide->angle[TR_XE] - curSide->angle[TR_XS]) / curSide->length;
536 curSide->Kyl = (ew - sw) / curSide->length;
537
538 curSide->rgtSideNormal.x = curSeg->rgtSideNormal.x;
539 curSide->rgtSideNormal.y = curSeg->rgtSideNormal.y;
540
541 TSTX(x);
542 TSTY(y);
543 TSTZ(z);
544 break;
545
546 case TR_LFT:
547 curSide->center.x = curSeg->center.x;
548 curSide->center.y = curSeg->center.y;
549
550 switch(side) {
551 case 1:
552 curSide->radius = curSeg->radiusl - sw / 2.0;
553 curSide->radiusr = curSeg->radiusl;
554 curSide->radiusl = curSeg->radiusl - maxWidth;
555 curSide->arc = curSeg->arc;
556 curSide->length = curSide->radius * curSide->arc;
557
558 curSide->vertex[TR_SL].x = curSide->vertex[TR_SR].x - sw * cos(curSide->angle[TR_CS]);
559 curSide->vertex[TR_SL].y = curSide->vertex[TR_SR].y - sw * sin(curSide->angle[TR_CS]);
560 curSide->vertex[TR_SL].z = curSide->vertex[TR_SR].z + (tdble)type * sw * tan(curSeg->angle[TR_XS]);
561 curSide->vertex[TR_EL].x = curSide->vertex[TR_ER].x - ew * cos(curSide->angle[TR_CS] + curSide->arc);
562 curSide->vertex[TR_EL].y = curSide->vertex[TR_ER].y - ew * sin(curSide->angle[TR_CS] + curSide->arc);
563 z = curSide->vertex[TR_EL].z = curSide->vertex[TR_ER].z + (tdble)type * ew * tan(curSeg->angle[TR_XE]);
564
565 curSide->angle[TR_YR] = atan2(curSide->vertex[TR_ER].z - curSide->vertex[TR_SR].z,
566 curSide->arc * curSide->radiusr);
567 curSide->angle[TR_YL] = atan2(curSide->vertex[TR_EL].z - curSide->vertex[TR_SL].z,
568 curSide->arc * curSide->radiusl);
569
570 curSide->Kzl = tan(curSide->angle[TR_YR]) * curSide->radiusr;
571 curSide->Kzw = (curSide->angle[TR_XE] - curSide->angle[TR_XS]) / curSide->arc;
572 curSide->Kyl = (ew - sw) / curSide->arc;
573
574 /* to find the boundary */
575 al = (curSide->angle[TR_ZE] - curSide->angle[TR_ZS])/36.0;
576 alfl = curSide->angle[TR_ZS];
577
578 for (j = 0; j < 36; j++) {
579 alfl += al;
580 x1 = curSide->center.x + (curSide->radiusl) * sin(alfl); /* location of end */
581 y1 = curSide->center.y - (curSide->radiusl) * cos(alfl);
582 TSTX(x1);
583 TSTY(y1);
584 }
585 TSTZ(z);
586 break;
587
588 case 0:
589 curSide->radius = curSeg->radiusr + sw / 2.0;
590 curSide->radiusl = curSeg->radiusr;
591 curSide->radiusr = curSeg->radiusr + maxWidth;
592 curSide->arc = curSeg->arc;
593 curSide->length = curSide->radius * curSide->arc;
594
595 curSide->vertex[TR_SR].x = curSide->vertex[TR_SL].x + sw * cos(curSide->angle[TR_CS]);
596 curSide->vertex[TR_SR].y = curSide->vertex[TR_SL].y + sw * sin(curSide->angle[TR_CS]);
597 curSide->vertex[TR_SR].z = curSide->vertex[TR_SL].z - (tdble)type * sw * tan(curSeg->angle[TR_XS]);
598 curSide->vertex[TR_ER].x = curSide->vertex[TR_EL].x + ew * cos(curSide->angle[TR_CS] + curSide->arc);
599 curSide->vertex[TR_ER].y = curSide->vertex[TR_EL].y + ew * sin(curSide->angle[TR_CS] + curSide->arc);
600 z = curSide->vertex[TR_ER].z = curSide->vertex[TR_EL].z - (tdble)type * ew * tan(curSeg->angle[TR_XE]);
601
602 curSide->angle[TR_YR] = atan2(curSide->vertex[TR_ER].z - curSide->vertex[TR_SR].z,
603 curSide->arc * curSide->radiusr);
604 curSide->angle[TR_YL] = atan2(curSide->vertex[TR_EL].z - curSide->vertex[TR_SL].z,
605 curSide->arc * curSide->radiusl);
606
607 curSide->Kzl = tan(curSide->angle[TR_YR]) * (curSide->radiusr);
608 curSide->Kzw = (curSide->angle[TR_XE] - curSide->angle[TR_XS]) / curSide->arc;
609 curSide->Kyl = (ew - sw) / curSide->arc;
610
611 /* to find the boundary */
612 al = (curSide->angle[TR_ZE] - curSide->angle[TR_ZS])/36.0;
613 alfl = curSide->angle[TR_ZS];
614
615 for (j = 0; j < 36; j++) {
616 alfl += al;
617 x2 = curSide->center.x + (curSide->radiusr) * sin(alfl); /* location of end */
618 y2 = curSide->center.y - (curSide->radiusr) * cos(alfl);
619 TSTX(x2);
620 TSTY(y2);
621 }
622 TSTZ(z);
623 break;
624
625 }
626 break;
627 case TR_RGT:
628 curSide->center.x = curSeg->center.x;
629 curSide->center.y = curSeg->center.y;
630
631 switch(side) {
632 case 1:
633 curSide->radius = curSeg->radiusl + sw / 2.0;
634 curSide->radiusr = curSeg->radiusl;
635 curSide->radiusl = curSeg->radiusl + maxWidth;
636 curSide->arc = curSeg->arc;
637 curSide->length = curSide->radius * curSide->arc;
638
639 curSide->vertex[TR_SL].x = curSide->vertex[TR_SR].x + sw * cos(curSide->angle[TR_CS]);
640 curSide->vertex[TR_SL].y = curSide->vertex[TR_SR].y + sw * sin(curSide->angle[TR_CS]);
641 curSide->vertex[TR_SL].z = curSide->vertex[TR_SR].z + (tdble)type * sw * tan(curSeg->angle[TR_XS]);
642 curSide->vertex[TR_EL].x = curSide->vertex[TR_ER].x + ew * cos(curSide->angle[TR_CS] - curSide->arc);
643 curSide->vertex[TR_EL].y = curSide->vertex[TR_ER].y + ew * sin(curSide->angle[TR_CS] - curSide->arc);
644 z = curSide->vertex[TR_EL].z = curSide->vertex[TR_ER].z + (tdble)type * ew * tan(curSeg->angle[TR_XE]);
645
646 curSide->angle[TR_YR] = atan2(curSide->vertex[TR_ER].z - curSide->vertex[TR_SR].z,
647 curSide->arc * curSide->radiusr);
648 curSide->angle[TR_YL] = atan2(curSide->vertex[TR_EL].z - curSide->vertex[TR_SL].z,
649 curSide->arc * curSide->radiusl);
650
651 curSide->Kzl = tan(curSide->angle[TR_YR]) * curSide->radiusr;
652 curSide->Kzw = (curSide->angle[TR_XE] - curSide->angle[TR_XS]) / curSide->arc;
653 curSide->Kyl = (ew - sw) / curSide->arc;
654
655 /* to find the boundary */
656 al = (curSide->angle[TR_ZE] - curSide->angle[TR_ZS])/36.0;
657 alfl = curSide->angle[TR_ZS];
658
659 for (j = 0; j < 36; j++) {
660 alfl += al;
661 x1 = curSide->center.x - (curSide->radiusl) * sin(alfl); /* location of end */
662 y1 = curSide->center.y + (curSide->radiusl) * cos(alfl);
663 TSTX(x1);
664 TSTY(y1);
665 }
666 TSTZ(z);
667 break;
668
669 case 0:
670 curSide->radius = curSeg->radiusr - sw / 2.0;
671 curSide->radiusl = curSeg->radiusr;
672 curSide->radiusr = curSeg->radiusr - maxWidth;
673 curSide->arc = curSeg->arc;
674 curSide->length = curSide->radius * curSide->arc;
675
676 curSide->vertex[TR_SR].x = curSide->vertex[TR_SL].x - sw * cos(curSide->angle[TR_CS]);
677 curSide->vertex[TR_SR].y = curSide->vertex[TR_SL].y - sw * sin(curSide->angle[TR_CS]);
678 curSide->vertex[TR_SR].z = curSide->vertex[TR_SL].z - (tdble)type * sw * tan(curSeg->angle[TR_XS]);
679 curSide->vertex[TR_ER].x = curSide->vertex[TR_EL].x - ew * cos(curSide->angle[TR_CS] - curSide->arc);
680 curSide->vertex[TR_ER].y = curSide->vertex[TR_EL].y - ew * sin(curSide->angle[TR_CS] - curSide->arc);
681 z = curSide->vertex[TR_ER].z = curSide->vertex[TR_EL].z - (tdble)type * ew * tan(curSeg->angle[TR_XE]);
682
683 curSide->angle[TR_YR] = atan2(curSide->vertex[TR_ER].z - curSide->vertex[TR_SR].z,
684 curSide->arc * curSide->radiusr);
685 curSide->angle[TR_YL] = atan2(curSide->vertex[TR_EL].z - curSide->vertex[TR_SL].z,
686 curSide->arc * curSide->radiusl);
687
688 curSide->Kzl = tan(curSide->angle[TR_YR]) * (curSide->radiusr);
689 curSide->Kzw = (curSide->angle[TR_XE] - curSide->angle[TR_XS]) / curSide->arc;
690 curSide->Kyl = (ew - sw) / curSide->arc;
691
692 /* to find the boundary */
693 al = (curSide->angle[TR_ZE] - curSide->angle[TR_ZS])/36.0;
694 alfl = curSide->angle[TR_ZS];
695
696 for (j = 0; j < 36; j++) {
697 alfl += al;
698 x2 = curSide->center.x - (curSide->radiusr) * sin(alfl); /* location of end */
699 /* This legacy sign overestimates right-turn bounds, but v3 models were
700 authored against the resulting origin. Fixing it would misalign them.
701 Correct: y2 = curSide->center.y + (curSide->radiusr) * cos(alfl); */
702 y2 = curSide->center.y - (curSide->radiusr) * cos(alfl);
703 TSTX(x2);
704 TSTY(y2);
705 }
706 TSTZ(z);
707 break;
708 }
709 break;
710 }
711 }
712
713 /* Barrier */
714 curBarrier = (tTrackBarrier*)malloc(sizeof(tTrackBarrier));
715 if (!curBarrier) {
716 GfFatal("AddSides: memory allocation error");
717 }
718 curBarrier->style = barrierStyle[side];
719 curBarrier->width = barrierWidth[side];
720 curBarrier->height = barrierHeight[side];
721 curBarrier->surface = barrierSurface[side];
722
723 // Compute normal of barrier for side collisions.
724 tTrackSeg *bseg = mSeg;
725 int bstart, bend;
726 float bsign;
727
728 if (side == TR_SIDE_LFT) {
729 bstart = TR_SL;
730 bend = TR_EL;
731 bsign = -1.0f;
732 } else {
733 bstart = TR_SR;
734 bend = TR_ER;
735 bsign = 1.0f;
736 }
737
738 while (bseg->side[side] != NULL) {
739 bseg = bseg->side[side];
740 }
741
742 vec2f n(
743 -(bseg->vertex[bend].y - bseg->vertex[bstart].y)*bsign,
744 (bseg->vertex[bend].x - bseg->vertex[bstart].x)*bsign
745 );
746
747 n.normalize();
748 curBarrier->normal = n;
749
750 mSeg->barrier[side] = curBarrier;
751 }
752}
753
754
755static void
757{
758 curSeg->vertex[TR_SR].x -= xmin;
759 curSeg->vertex[TR_SR].y -= ymin;
760 curSeg->vertex[TR_SR].z -= zmin;
761 curSeg->vertex[TR_SL].x -= xmin;
762 curSeg->vertex[TR_SL].y -= ymin;
763 curSeg->vertex[TR_SL].z -= zmin;
764 curSeg->vertex[TR_ER].x -= xmin;
765 curSeg->vertex[TR_ER].y -= ymin;
766 curSeg->vertex[TR_ER].z -= zmin;
767 curSeg->vertex[TR_EL].x -= xmin;
768 curSeg->vertex[TR_EL].y -= ymin;
769 curSeg->vertex[TR_EL].z -= zmin;
770 curSeg->center.x -= xmin;
771 curSeg->center.y -= ymin;
772}
773
774static void
776{
777 int j;
778 int segread, curindex;
779 tdble radius, radiusend = 0, dradius;
780 tdble innerradius;
781 tdble arc;
783 tTrackSeg *curSeg;
784 tTrackSeg *root;
785 tdble alf;
786 tdble xr, yr, newxr, newyr;
787 tdble xl, yl, newxl, newyl;
788 tdble cenx, ceny;
789 tdble width, wi2;
790 tdble x1, x2, y1, y2;
791 tdble al, alfl;
792 tdble zsl, zsr, zel, zer, zs, ze;
793 tdble bankings, bankinge, dz; // dzl, dzr;
794 tdble etgt, stgt;
795 tdble etgtl, stgtl;
796 tdble etgtr, stgtr;
797 tdble stepslg = 0;
798 int steps, curStep;
799 tTrackSurface *surface;
800 char *segName;
801 int type;
802 const char *profil;
803 tdble totLength;
804
805 tdble tl, dtl, T1l, T2l;
806 tdble tr, dtr, T1r, T2r;
807 tdble curzel, curzer, curArc, curLength, curzsl, curzsr;
808 tdble grade;
809
810 const int BUFSIZE = 256;
811 char path[BUFSIZE];
812#define MAX_TMP_INTS 256
813 int mi[MAX_TMP_INTS];
814 int ind = 0;
815
816 radius = arc = length = alf = xr = yr = newxr = newyr = xl = yl = 0;
817 zel = zer = etgtl = etgtr = newxl = newyl = 0;
818 type = 0;
819
820 width = GfParmGetNum(TrackHandle, TRK_SECT_MAIN, TRK_ATT_WIDTH, (char*)NULL, 15.0);
821 wi2 = width / 2.0;
822
823 grade = -100000.0;
824 root = (tTrackSeg*)NULL;
825 totLength = 0;
826
827 snprintf(path, BUFSIZE, "%s/%s", TRK_SECT_MAIN, TRK_LST_SEG);
828 if (start == NULL) {
829 xr = xl = 0.0;
830 yr = 0.0;
831 yl = width;
832 alf = 0.0;
833 zsl = zsr = zel = zer = zs = ze = 0.0;
834 stgt = etgt = 0.0;
835 stgtl = etgtl = 0.0;
836 stgtr = etgtr = 0.0;
837 } else {
839 const char* segtype = GfParmGetCurStr(TrackHandle, path, TRK_ATT_TYPE, "");
840 if (strcmp(segtype, TRK_VAL_STR) == 0) {
841
842 } else if (strcmp(segtype, TRK_VAL_LFT) == 0) {
843
844 } else if (strcmp(segtype, TRK_VAL_RGT) == 0) {
845 xr = start->vertex[TR_SR].x;
846 yr = start->vertex[TR_SR].y;
847 zsl = zsr = zel = zer = zs = ze = start->vertex[TR_SR].z;
848 alf = start->angle[TR_ZS];
849 xl = xr - width * sin(alf);
850 yl = yr + width * cos(alf);
851 stgt = etgt = 0.0;
852 stgtl = etgtl = 0.0;
853 stgtr = etgtr = 0.0;
854 }
855 }
856
857
858 /* Main Track */
860 surface = AddTrackSurface(TrackHandle, theTrack, material);
861 envIndex = 0;
862
864
865 segread = 0;
866 curindex = 0;
868 do {
869 const char* segtype = GfParmGetCurStr(TrackHandle, path, TRK_ATT_TYPE, NULL);
870 if (segtype == 0) {
871 continue;
872 }
873 segread++;
874
875 zsl = zel;
876 zsr = zer;
877 TSTZ(zsl);
878 TSTZ(zsr);
879
880 /* Turn Marks */
881 if (ext) {
882 const char *marks = GfParmGetCurStr(TrackHandle, path, TRK_ATT_MARKS, NULL);
883 ind = 0;
884 if (marks) {
885 char* tmpmarks = strdup(marks);
886 char *s = strtok(tmpmarks, ";");
887 while ((s != NULL) && (ind < MAX_TMP_INTS)) {
888 mi[ind] = (int)strtol(s, NULL, 0);
889 ind++;
890 s = strtok(NULL, ";");
891 }
892 free(tmpmarks);
893 }
894 }
895
896 /* surface change */
897 material = GfParmGetCurStr(TrackHandle, path, TRK_ATT_SURF, material);
898 surface = AddTrackSurface(TrackHandle, theTrack, material);
899 envIndex = (int)GfParmGetCurNum(TrackHandle, path, TRK_ATT_ENVIND, (char*)NULL, (float) (envIndex+1)) - 1;
900
901 /* get segment type and lenght */
902 if (strcmp(segtype, TRK_VAL_STR) == 0) {
903 /* straight */
904 length = GfParmGetCurNum(TrackHandle, path, TRK_ATT_LG, (char*)NULL, 0);
905 type = TR_STR;
906 radius = radiusend = 0;
907 } else if (strcmp(segtype, TRK_VAL_LFT) == 0) {
908 /* left curve */
909 radius = GfParmGetCurNum(TrackHandle, path, TRK_ATT_RADIUS, (char*)NULL, 0);
910 radiusend = GfParmGetCurNum(TrackHandle, path, TRK_ATT_RADIUSEND, (char*)NULL, radius);
911 arc = GfParmGetCurNum(TrackHandle, path, TRK_ATT_ARC, (char*)NULL, 0);
912 type = TR_LFT;
913 length = (radius + radiusend) / 2.0 * arc;
914 } else if (strcmp(segtype, TRK_VAL_RGT) == 0) {
915 /* right curve */
916 radius = GfParmGetCurNum(TrackHandle, path, TRK_ATT_RADIUS, (char*)NULL, 0);
917 radiusend = GfParmGetCurNum(TrackHandle, path, TRK_ATT_RADIUSEND, (char*)NULL, radius);
918 arc = GfParmGetCurNum(TrackHandle, path, TRK_ATT_ARC, (char*)NULL, 0);
919 type = TR_RGT;
920 length = (radius + radiusend) / 2.0 * arc;
921 }
922
923 segName = GfParmListGetCurEltName(TrackHandle, path);
924
925 /* elevation and banking */
926 zsl = GfParmGetCurNum(TrackHandle, path, TRK_ATT_ZSL, (char*)NULL, zsl);
927 zsr = GfParmGetCurNum(TrackHandle, path, TRK_ATT_ZSR, (char*)NULL, zsr);
928 zel = GfParmGetCurNum(TrackHandle, path, TRK_ATT_ZEL, (char*)NULL, zel);
929 zer = GfParmGetCurNum(TrackHandle, path, TRK_ATT_ZER, (char*)NULL, zer);
930 ze = zs = -100000.0;
931 ze = GfParmGetCurNum(TrackHandle, path, TRK_ATT_ZE, (char*)NULL, ze);
932 zs = GfParmGetCurNum(TrackHandle, path, TRK_ATT_ZS, (char*)NULL, zs);
933 grade = GfParmGetCurNum(TrackHandle, path, TRK_ATT_GRADE, (char*)NULL, grade);
934 if (zs != -100000.0) {
935 zsr = zsl = zs;
936 } else {
937 zs = (zsl + zsr) / 2.0;
938 }
939 if (ze != -100000.0) {
940 zer = zel = ze;
941 } else if (grade != -100000.0) {
942 ze = zs + length * grade;
943 } else {
944 ze = (zel + zer) / 2.0;
945 }
946 bankings = atan2(zsl - zsr, width);
947 bankinge = atan2(zel - zer, width);
948 bankings = GfParmGetCurNum(TrackHandle, path, TRK_ATT_BKS, (char*)NULL, bankings);
949 bankinge = GfParmGetCurNum(TrackHandle, path, TRK_ATT_BKE, (char*)NULL, bankinge);
950 dz = tan(bankings) * width / 2.0;
951 zsl = zs + dz;
952 zsr = zs - dz;
953 dz = tan(bankinge) * width / 2.0;
954 zel = ze + dz;
955 zer = ze - dz;
956
957 TSTZ(zsl);
958 TSTZ(zsr);
959
960 /* Get segment profil */
962 stgtl = etgtl;
963 stgtr = etgtr;
964 if (strcmp(profil, TRK_VAL_SPLINE) == 0) {
965 steps = (int)GfParmGetCurNum(TrackHandle, path, TRK_ATT_PROFSTEPS, (char*)NULL, 1.0);
966 if (steps == 1) {
967 stepslg = GfParmGetCurNum(TrackHandle, path, TRK_ATT_PROFSTEPSLEN, (char*)NULL, GlobalStepLen);
968 if (stepslg) {
969 steps = (int)(length / stepslg) + 1;
970 } else {
971 steps = 1;
972 }
973 }
974 stgtl = GfParmGetCurNum(TrackHandle, path, TRK_ATT_PROFTGTSL, (char*)NULL, stgtl);
975 etgtl = GfParmGetCurNum(TrackHandle, path, TRK_ATT_PROFTGTEL, (char*)NULL, etgtl);
976 stgtr = GfParmGetCurNum(TrackHandle, path, TRK_ATT_PROFTGTSR, (char*)NULL, stgtr);
977 etgtr = GfParmGetCurNum(TrackHandle, path, TRK_ATT_PROFTGTER, (char*)NULL, etgtr);
978 stgt = etgt = -100000.0;
979 stgt = GfParmGetCurNum(TrackHandle, path, TRK_ATT_PROFTGTS, (char*)NULL, stgt);
980 etgt = GfParmGetCurNum(TrackHandle, path, TRK_ATT_PROFTGTE, (char*)NULL, etgt);
981 if (stgt != -100000.0) {
982 stgtl = stgtr = stgt;
983 }
984 if (etgt != -100000.0) {
985 etgtl = etgtr = etgt;
986 }
987 } else {
988 steps = 1;
989 stgtl = etgtl = (zel - zsl) / length;
990 stgtr = etgtr = (zer - zsr) / length;
991 }
992 GfParmSetCurNum(TrackHandle, path, TRK_ATT_ID, (char*)NULL, (tdble)curindex);
993
994 //dzl = zel - zsl;
995 //dzr = zer - zsr;
996 T1l = stgtl * length;
997 T2l = etgtl * length;
998 tl = 0.0;
999 dtl = 1.0 / (tdble)steps;
1000 T1r = stgtr * length;
1001 T2r = etgtr * length;
1002 tr = 0.0;
1003 dtr = 1.0 / (tdble)steps;
1004
1005 curStep = 0;
1006 curzel = zsl;
1007 curzer = zsr;
1008 curArc = arc / (tdble)steps;
1009 curLength = length / (tdble)steps;
1010 dradius = (radiusend - radius) / (tdble)steps;
1011 if (radiusend != radius) {
1012 /* Compute the correct curLength... */
1013 if (steps != 1) {
1014 dradius = (radiusend - radius) / (tdble)(steps - 1);
1015 tdble tmpAngle = 0;
1016 tdble tmpRadius = radius;
1017 for (curStep = 0; curStep < steps; curStep++) {
1018 tmpAngle += curLength / tmpRadius;
1019 tmpRadius += dradius;
1020 }
1021 curLength *= arc / tmpAngle;
1022 }
1023 }
1024 curStep = 0;
1025
1026 while (curStep < steps) {
1027
1028 tl += dtl;
1029 tr += dtr;
1030
1031 curzsl = curzel;
1032 curzel = TrackSpline(zsl, zel, T1l, T2l, tl);
1033
1034 curzsr = curzer;
1035 curzer = TrackSpline(zsr, zer, T1r, T2r, tr);
1036
1037 if (dradius != 0) {
1038 curArc = curLength / radius;
1039 }
1040
1041 /* allocate a new segment */
1042 curSeg = (tTrackSeg*)calloc(1, sizeof(tTrackSeg));
1043 if (root == NULL) {
1044 root = curSeg;
1045 curSeg->next = curSeg;
1046 curSeg->prev = curSeg;
1047 } else {
1048 curSeg->next = root->next;
1049 curSeg->next->prev = curSeg;
1050 curSeg->prev = root;
1051 root->next = curSeg;
1052 root = curSeg;
1053 }
1054 curSeg->type2 = TR_MAIN;
1055 curSeg->name = segName;
1056 curSeg->id = curindex;
1057 curSeg->width = curSeg->startWidth = curSeg->endWidth = width;
1058 curSeg->surface = surface;
1059 curSeg->envIndex = envIndex;
1060 curSeg->lgfromstart = totLength;
1061
1062 if (ext && ind) {
1063 int *mrks = (int*)calloc(ind, sizeof(int));
1064 tSegExt *segExt = (tSegExt*)calloc(1, sizeof(tSegExt));
1065
1066 memcpy(mrks, mi, ind*sizeof(int));
1067 segExt->nbMarks = ind;
1068 segExt->marks = mrks;
1069 curSeg->ext = segExt;
1070 ind = 0;
1071 }
1072
1073
1074 switch (type) {
1075 case TR_STR:
1076 /* straight */
1077 curSeg->type = TR_STR;
1078 curSeg->length = curLength;
1079
1080 newxr = xr + curLength * cos(alf); /* find end coordinates */
1081 newyr = yr + curLength * sin(alf);
1082 newxl = xl + curLength * cos(alf);
1083 newyl = yl + curLength * sin(alf);
1084
1085 curSeg->vertex[TR_SR].x = xr;
1086 curSeg->vertex[TR_SR].y = yr;
1087 curSeg->vertex[TR_SR].z = curzsr;
1088
1089 curSeg->vertex[TR_SL].x = xl;
1090 curSeg->vertex[TR_SL].y = yl;
1091 curSeg->vertex[TR_SL].z = curzsl;
1092
1093 curSeg->vertex[TR_ER].x = newxr;
1094 curSeg->vertex[TR_ER].y = newyr;
1095 curSeg->vertex[TR_ER].z = curzer;
1096
1097 curSeg->vertex[TR_EL].x = newxl;
1098 curSeg->vertex[TR_EL].y = newyl;
1099 curSeg->vertex[TR_EL].z = curzel;
1100
1101 curSeg->angle[TR_ZS] = alf;
1102 curSeg->angle[TR_ZE] = alf;
1103 curSeg->angle[TR_YR] = atan2(curSeg->vertex[TR_ER].z - curSeg->vertex[TR_SR].z, curLength);
1104 curSeg->angle[TR_YL] = atan2(curSeg->vertex[TR_EL].z - curSeg->vertex[TR_SL].z, curLength);
1105 curSeg->angle[TR_XS] = atan2(curSeg->vertex[TR_SL].z - curSeg->vertex[TR_SR].z, width);
1106 curSeg->angle[TR_XE] = atan2(curSeg->vertex[TR_EL].z - curSeg->vertex[TR_ER].z, width);
1107
1108 curSeg->Kzl = tan(curSeg->angle[TR_YR]);
1109 curSeg->Kzw = (curSeg->angle[TR_XE] - curSeg->angle[TR_XS]) / curLength;
1110 curSeg->Kyl = 0;
1111
1112 curSeg->rgtSideNormal.x = -sin(alf);
1113 curSeg->rgtSideNormal.y = cos(alf);
1114
1115 TSTX(newxr); TSTX(newxl);
1116 TSTY(newyr); TSTY(newyl);
1117
1118 break;
1119
1120 case TR_LFT:
1121 /* left curve */
1122 curSeg->type = TR_LFT;
1123 curSeg->radius = radius;
1124 curSeg->radiusr = radius + wi2;
1125 curSeg->radiusl = radius - wi2;
1126 curSeg->arc = curArc;
1127 curSeg->length = curLength;
1128
1129 innerradius = radius - wi2; /* left side aligned */
1130 cenx = xl - innerradius * sin(alf); /* compute center location: */
1131 ceny = yl + innerradius * cos(alf);
1132 curSeg->center.x = cenx;
1133 curSeg->center.y = ceny;
1134
1135 curSeg->angle[TR_ZS] = alf;
1136 curSeg->angle[TR_CS] = alf - PI / 2.0;
1137 alf += curArc;
1138 curSeg->angle[TR_ZE] = alf;
1139
1140 newxl = cenx + innerradius * sin(alf); /* location of end */
1141 newyl = ceny - innerradius * cos(alf);
1142 newxr = cenx + (innerradius + width) * sin(alf); /* location of end */
1143 newyr = ceny - (innerradius + width) * cos(alf);
1144
1145 curSeg->vertex[TR_SR].x = xr;
1146 curSeg->vertex[TR_SR].y = yr;
1147 curSeg->vertex[TR_SR].z = curzsr;
1148
1149 curSeg->vertex[TR_SL].x = xl;
1150 curSeg->vertex[TR_SL].y = yl;
1151 curSeg->vertex[TR_SL].z = curzsl;
1152
1153 curSeg->vertex[TR_ER].x = newxr;
1154 curSeg->vertex[TR_ER].y = newyr;
1155 curSeg->vertex[TR_ER].z = curzer;
1156
1157 curSeg->vertex[TR_EL].x = newxl;
1158 curSeg->vertex[TR_EL].y = newyl;
1159 curSeg->vertex[TR_EL].z = curzel;
1160
1161 curSeg->angle[TR_YR] = atan2(curSeg->vertex[TR_ER].z - curSeg->vertex[TR_SR].z, curArc * (innerradius + width));
1162 curSeg->angle[TR_YL] = atan2(curSeg->vertex[TR_EL].z - curSeg->vertex[TR_SL].z, curArc * innerradius);
1163 curSeg->angle[TR_XS] = atan2(curSeg->vertex[TR_SL].z - curSeg->vertex[TR_SR].z, width);
1164 curSeg->angle[TR_XE] = atan2(curSeg->vertex[TR_EL].z - curSeg->vertex[TR_ER].z, width);
1165
1166 curSeg->Kzl = tan(curSeg->angle[TR_YR]) * (innerradius + width);
1167 curSeg->Kzw = (curSeg->angle[TR_XE] - curSeg->angle[TR_XS]) / curArc;
1168 curSeg->Kyl = 0;
1169
1170 /* to find the boundary */
1171 al = (curSeg->angle[TR_ZE] - curSeg->angle[TR_ZS])/36.0;
1172 alfl = curSeg->angle[TR_ZS];
1173
1174 for (j = 0; j < 36; j++) {
1175 alfl += al;
1176 x1 = curSeg->center.x + (innerradius) * sin(alfl); /* location of end */
1177 y1 = curSeg->center.y - (innerradius) * cos(alfl);
1178 x2 = curSeg->center.x + (innerradius + width) * sin(alfl); /* location of end */
1179 y2 = curSeg->center.y - (innerradius + width) * cos(alfl);
1180 TSTX(x1); TSTX(x2);
1181 TSTY(y1); TSTY(y2);
1182 }
1183
1184 break;
1185
1186 case TR_RGT:
1187 /* right curve */
1188 curSeg->type = TR_RGT;
1189 curSeg->radius = radius;
1190 curSeg->radiusr = radius - wi2;
1191 curSeg->radiusl = radius + wi2;
1192 curSeg->arc = curArc;
1193 curSeg->length = curLength;
1194
1195 innerradius = radius - wi2; /* right side aligned */
1196 cenx = xr + innerradius * sin(alf); /* compute center location */
1197 ceny = yr - innerradius * cos(alf);
1198 curSeg->center.x = cenx;
1199 curSeg->center.y = ceny;
1200
1201 curSeg->angle[TR_ZS] = alf;
1202 curSeg->angle[TR_CS] = alf + PI / 2.0;
1203 alf -= curSeg->arc;
1204 curSeg->angle[TR_ZE] = alf;
1205
1206 newxl = cenx - (innerradius + width) * sin(alf); /* location of end */
1207 newyl = ceny + (innerradius + width) * cos(alf);
1208 newxr = cenx - innerradius * sin(alf); /* location of end */
1209 newyr = ceny + innerradius * cos(alf);
1210
1211 curSeg->vertex[TR_SR].x = xr;
1212 curSeg->vertex[TR_SR].y = yr;
1213 curSeg->vertex[TR_SR].z = curzsr;
1214
1215 curSeg->vertex[TR_SL].x = xl;
1216 curSeg->vertex[TR_SL].y = yl;
1217 curSeg->vertex[TR_SL].z = curzsl;
1218
1219 curSeg->vertex[TR_ER].x = newxr;
1220 curSeg->vertex[TR_ER].y = newyr;
1221 curSeg->vertex[TR_ER].z = curzer;
1222
1223 curSeg->vertex[TR_EL].x = newxl;
1224 curSeg->vertex[TR_EL].y = newyl;
1225 curSeg->vertex[TR_EL].z = curzel;
1226
1227 curSeg->angle[TR_YR] = atan2(curSeg->vertex[TR_ER].z - curSeg->vertex[TR_SR].z, curArc * innerradius);
1228 curSeg->angle[TR_YL] = atan2(curSeg->vertex[TR_EL].z - curSeg->vertex[TR_SL].z, curArc * (innerradius + width));
1229 curSeg->angle[TR_XS] = atan2(curSeg->vertex[TR_SL].z - curSeg->vertex[TR_SR].z, width);
1230 curSeg->angle[TR_XE] = atan2(curSeg->vertex[TR_EL].z - curSeg->vertex[TR_ER].z, width);
1231
1232 curSeg->Kzl = tan(curSeg->angle[TR_YR]) * innerradius;
1233 curSeg->Kzw = (curSeg->angle[TR_XE] - curSeg->angle[TR_XS]) / curArc;
1234 curSeg->Kyl = 0;
1235
1236 /* to find the boundaries */
1237 al = (curSeg->angle[TR_ZE] - curSeg->angle[TR_ZS])/36.0;
1238 alfl = curSeg->angle[TR_ZS];
1239
1240 for (j = 0; j < 36; j++) {
1241 alfl += al;
1242 x1 = curSeg->center.x - (innerradius + width) * sin(alfl); /* location of end */
1243 y1 = curSeg->center.y + (innerradius + width) * cos(alfl);
1244 x2 = curSeg->center.x - innerradius * sin(alfl); /* location of end */
1245 y2 = curSeg->center.y + innerradius * cos(alfl);
1246 TSTX(x1); TSTX(x2);
1247 TSTY(y1); TSTY(y2);
1248 }
1249 break;
1250
1251 }
1252
1253 AddSides(curSeg, TrackHandle, theTrack, curStep, steps);
1254
1255 totLength += curSeg->length;
1256 xr = newxr;
1257 yr = newyr;
1258 xl = newxl;
1259 yl = newyl;
1260 curindex++;
1261 curStep++;
1262 if (type != TR_STR) {
1263 /* printf("radius = %f arc = %f steps %d, length %f, stepslg %f\n", radius, RAD2DEG(curArc), steps, length, curLength); */
1264 radius += dradius;
1265 }
1266 }
1267
1268 } while (GfParmListSeekNext(TrackHandle, path) == 0);
1269
1270 theTrack->seg = root;
1271 theTrack->length = totLength;
1272 theTrack->nseg = curindex;
1273}
1274
1275
1276
1277
1278/*
1279 * Read version 3 track segments
1280 */
1281void
1282ReadTrack3(tTrack *theTrack, void *TrackHandle, tRoadCam **camList, int ext)
1283{
1284 int i;
1285 tTrackSeg *curSeg = NULL, *mSeg;
1286 tTrackSeg *curSeg2;
1287 tTrackSeg *pitEntrySeg = NULL;
1288 tTrackSeg *pitExitSeg = NULL;
1289 tTrackSeg *pitStart = NULL;
1290 tTrackSeg *pitEnd = NULL;
1291 tTrackSeg *curPitSeg = NULL;
1292 tTrackPitInfo *pits;
1293 const char *segName;
1294 int segId;
1295 tRoadCam *curCam;
1296 tTrkLocPos trkPos;
1297 int found = 0;
1298 const char *paramVal;
1299 const char *pitType;
1300 const int BUFSIZE = 256;
1301 char path[BUFSIZE];
1302 char path2[BUFSIZE];
1303 int changeSeg;
1304 tdble offset = 0;
1305 tdble toStart;
1306
1307 xmin = xmax = ymin = ymax = zmin = zmax = 0.0;
1308
1310
1311 CreateSegRing3(TrackHandle, theTrack, (tTrackSeg*)NULL, (tTrackSeg*)NULL, ext);
1312
1313 pits = &(theTrack->pits);
1315
1316
1317 if (strcmp(pitType, TRK_VAL_PIT_TYPE_NONE) != 0) {
1319 if (segName != 0) {
1320 snprintf(path, BUFSIZE, "%s/%s/%s", TRK_SECT_MAIN, TRK_LST_SEG, segName);
1321 segId = (int)GfParmGetNum(TrackHandle, path, TRK_ATT_ID, (char*)NULL, -1);
1322 pitEntrySeg = theTrack->seg;
1323 found = 0;
1324 for(i = 0; i < theTrack->nseg; i++) {
1325 if (pitEntrySeg->id == segId) {
1326 found = 1;
1327 } else if (found) {
1328 pitEntrySeg = pitEntrySeg->next;
1329 break;
1330 }
1331 pitEntrySeg = pitEntrySeg->prev;
1332 }
1333 if (!found) {
1334 pitEntrySeg = NULL;
1335 }
1336 }
1337
1339 if (segName != 0) {
1340 pitExitSeg = theTrack->seg->next;
1341 found = 0;
1342 for(i = 0; i < theTrack->nseg; i++) {
1343 /* set the flag on the last segment of pit_exit */
1344 if (!strcmp(segName, pitExitSeg->name)) {
1345 found = 1;
1346 } else if (found) {
1347 pitExitSeg = pitExitSeg->prev;
1348 break;
1349 }
1350 pitExitSeg = pitExitSeg->next;
1351 }
1352 if (!found) {
1353 pitExitSeg = NULL;
1354 }
1355 }
1356
1358 if (segName != 0) {
1359 pitStart = theTrack->seg;
1360 found = 0;
1361 for(i = 0; i < theTrack->nseg; i++) {
1362 if (!strcmp(segName, pitStart->name)) {
1363 found = 1;
1364 } else if (found) {
1365 pitStart = pitStart->next;
1366 break;
1367 }
1368 pitStart = pitStart->prev;
1369 }
1370 if (!found) {
1371 pitStart = NULL;
1372 }
1373
1374 }
1376 if (segName != 0) {
1377 pitEnd = theTrack->seg->next;
1378 found = 0;
1379 for(i = 0; i < theTrack->nseg; i++) {
1380 if (!strcmp(segName, pitEnd->name)) {
1381 found = 1;
1382 } else if (found) {
1383 pitEnd = pitEnd->prev;
1384 break;
1385 }
1386 pitEnd = pitEnd->next;
1387 }
1388 if (!found) {
1389 pitEnd = NULL;
1390 }
1391 }
1393 if (strcmp(paramVal, "right") == 0) {
1394 pits->side = TR_RGT;
1395 } else {
1396 pits->side = TR_LFT;
1397 }
1398 pits->speedLimit = GfParmGetNum(TrackHandle, TRK_SECT_MAIN, TRK_ATT_SPD_LIM, (char*)NULL, 25.0);
1399 if ((pitEntrySeg != NULL) && (pitExitSeg != NULL) && (pitStart != NULL) && (pitEnd != NULL)) {
1400 pits->pitEntry = pitEntrySeg;
1401 pits->pitExit = pitExitSeg;
1402 pits->pitStart = pitStart;
1403 pits->pitEnd = pitEnd;
1404 pitEntrySeg->raceInfo |= TR_PITENTRY;
1405 pitExitSeg->raceInfo |= TR_PITEXIT;
1406 pits->len = GfParmGetNum(TrackHandle, TRK_SECT_MAIN, TRK_ATT_PIT_LEN, (char*)NULL, 15.0);
1407 pits->width = GfParmGetNum(TrackHandle, TRK_SECT_MAIN, TRK_ATT_PIT_WIDTH, (char*)NULL, 5.0);
1408 found = 1;
1409 } else {
1410 found = 0;
1411 }
1412 }
1413
1414 if (found && (strcmp(pitType, TRK_VAL_PIT_TYPE_SIDE) == 0)) {
1415 pits->type = TR_PIT_ON_TRACK_SIDE;
1416 pits->nPitSeg = 0;
1417 if (pitStart->lgfromstart > pitEnd->lgfromstart) {
1418 pits->nMaxPits = (int)((theTrack->length - pitStart->lgfromstart +
1419 pitEnd->lgfromstart + pitEnd->length + pits->len / 2.0) / pits->len);
1420 } else {
1421 pits->nMaxPits = (int)((- pitStart->lgfromstart + pitEnd->lgfromstart +
1422 pitEnd->length + pits->len / 2.0) / pits->len);
1423 }
1424 pits->driversPits = (tTrackOwnPit*)calloc(pits->nMaxPits, sizeof(tTrackOwnPit));
1425
1426 mSeg = pits->pitStart->prev;
1427 changeSeg = 1;
1428 toStart = 0;
1429 i = 0;
1430 while (i < pits->nMaxPits) {
1431 pits->driversPits[i].pos.type = TR_LPOS_MAIN;
1432 if (changeSeg) {
1433 changeSeg = 0;
1434 offset = 0;
1435 mSeg = mSeg->next;
1436 switch (pits->side) {
1437 case TR_RGT:
1438 curPitSeg = mSeg->rside;
1439 if (curPitSeg->rside) {
1440 offset = curPitSeg->width;
1441 curPitSeg = curPitSeg->rside;
1442 }
1443 break;
1444 case TR_LFT:
1445 curPitSeg = mSeg->lside;
1446 if (curPitSeg->lside) {
1447 offset = curPitSeg->width;
1448 curPitSeg = curPitSeg->lside;
1449 }
1450 break;
1451 }
1452 if (toStart >= mSeg->length) {
1453 toStart -= mSeg->length;
1454 changeSeg = 1;
1455 continue;
1456 }
1457 }
1458 pits->driversPits[i].pos.seg = mSeg;
1459 pits->driversPits[i].pos.toStart = toStart + pits->len / 2.0;
1460 switch (pits->side) {
1461 case TR_RGT:
1462 pits->driversPits[i].pos.toRight = -offset - RtTrackGetWidth(curPitSeg, toStart) + pits->width / 2.0;
1463 pits->driversPits[i].pos.toLeft = mSeg->width - pits->driversPits[i].pos.toRight;
1464 pits->driversPits[i].pos.toMiddle = mSeg->width / 2.0 - pits->driversPits[i].pos.toRight;
1465 break;
1466 case TR_LFT:
1467 pits->driversPits[i].pos.toLeft = -offset - RtTrackGetWidth(curPitSeg, toStart) + pits->width / 2.0;
1468 pits->driversPits[i].pos.toRight = mSeg->width - pits->driversPits[i].pos.toLeft;
1469 pits->driversPits[i].pos.toMiddle = mSeg->width / 2.0 - pits->driversPits[i].pos.toLeft;
1470 break;
1471 }
1472 toStart += pits->len;
1473 if (toStart >= mSeg->length) {
1474 toStart -= mSeg->length;
1475 changeSeg = 1;
1476 }
1477 i++;
1478 }
1479
1480 for (mSeg = pitStart->prev; mSeg != pitEnd->next->next; mSeg = mSeg->next) {
1481 curSeg2 = NULL;
1482 switch(pits->side) {
1483 case TR_RGT:
1484 curSeg = mSeg->rside;
1485 curSeg2 = curSeg->rside;
1486 if ((mSeg != pitStart->prev) && (mSeg != pitEnd->next)) {
1487 mSeg->barrier[0]->style = TR_PITBUILDING;
1488 }
1489 break;
1490 case TR_LFT:
1491 curSeg = mSeg->lside;
1492 curSeg2 = curSeg->lside;
1493 if ((mSeg != pitStart->prev) && (mSeg != pitEnd->next)) {
1494 mSeg->barrier[1]->style = TR_PITBUILDING;
1495 }
1496 break;
1497 }
1498 if ((mSeg != pitStart->prev) && (mSeg != pitEnd->next)) {
1499 curSeg->raceInfo |= TR_PIT | TR_SPEEDLIMIT;
1500 if (curSeg2) {
1501 curSeg2->raceInfo |= TR_PIT | TR_SPEEDLIMIT;
1502 }
1503 } else if (mSeg == pitStart->prev) {
1504 curSeg->raceInfo |= TR_PITSTART;
1505 if (curSeg2) {
1506 curSeg2->raceInfo |= TR_PITSTART;
1507 }
1508 } else if (mSeg == pitEnd->next) {
1509 curSeg->raceInfo |= TR_PITEND;
1510 if (curSeg2) {
1511 curSeg2->raceInfo |= TR_PITEND;
1512 }
1513 }
1514 }
1515
1516 }
1517
1518 /*
1519 * camera definitions
1520 */
1521 snprintf(path, BUFSIZE, "%s/%s", TRK_SECT_CAM, TRK_LST_CAM);
1522 if (GfParmListSeekFirst(TrackHandle, path) == 0) {
1523 do {
1524 curCam = (tRoadCam*)calloc(1, sizeof(tRoadCam));
1525 if (!curCam) {
1526 GfFatal("ReadTrack3: Memory allocation error");
1527 }
1528 if (*camList == NULL) {
1529 *camList = curCam;
1530 curCam->next = curCam;
1531 } else {
1532 curCam->next = (*camList)->next;
1533 (*camList)->next = curCam;
1534 *camList = curCam;
1535 }
1536 curCam->name = GfParmListGetCurEltName(TrackHandle, path);
1537 segName = GfParmGetCurStr(TrackHandle, path, TRK_ATT_SEGMENT, NULL);
1538 if (segName == 0) {
1539 GfFatal("Bad Track Definition: in Camera %s %s is missing\n", curCam->name, TRK_ATT_SEGMENT);
1540 }
1541 snprintf(path2, BUFSIZE, "%s/%s/%s", TRK_SECT_MAIN, TRK_LST_SEG, segName);
1542 segId = (int)GfParmGetNum(TrackHandle, path2, TRK_ATT_ID, (char*)NULL, 0);
1543 curSeg = theTrack->seg;
1544 for(i=0; i<theTrack->nseg; i++) {
1545 if (curSeg->id == segId) {
1546 break;
1547 }
1548 curSeg = curSeg->next;
1549 }
1550
1551 trkPos.seg = curSeg;
1552 trkPos.toRight = GfParmGetCurNum(TrackHandle, path, TRK_ATT_TORIGHT, (char*)NULL, 0);
1553 trkPos.toStart = GfParmGetCurNum(TrackHandle, path, TRK_ATT_TOSTART, (char*)NULL, 0);
1554 TrackLocal2Global(&trkPos, &(curCam->pos.x), &(curCam->pos.y));
1555 curCam->pos.z = TrackHeightL(&trkPos) + GfParmGetCurNum(TrackHandle, path, TRK_ATT_HEIGHT, (char*)NULL, 0);
1556
1557 segName = GfParmGetCurStr(TrackHandle, path, TRK_ATT_CAM_FOV, NULL);
1558 if (segName == 0) {
1559 GfFatal("Bad Track Definition: in Camera %s %s is missing\n", curCam->name, TRK_ATT_CAM_FOV);
1560 }
1561 snprintf(path2, BUFSIZE, "%s/%s/%s", TRK_SECT_MAIN, TRK_LST_SEG, segName);
1562 segId = (int)GfParmGetNum(TrackHandle, path2, TRK_ATT_ID, (char*)NULL, 0);
1563 curSeg = theTrack->seg;
1564 for(i=0; i<theTrack->nseg; i++) {
1565 if (curSeg->id == segId) {
1566 break;
1567 }
1568 curSeg = curSeg->next;
1569 }
1570 segName = GfParmGetCurStr(TrackHandle, path, TRK_ATT_CAM_FOVE, NULL);
1571 if (segName == 0) {
1572 GfFatal("Bad Track Definition: in Camera %s %s is missing\n", curCam->name, TRK_ATT_CAM_FOVE);
1573 }
1574 snprintf(path2, BUFSIZE, "%s/%s/%s", TRK_SECT_MAIN, TRK_LST_SEG, segName);
1575 segId = (int)GfParmGetNum(TrackHandle, path2, TRK_ATT_ID, (char*)NULL, 0);
1576
1577 do {
1578 curSeg->cam = curCam;
1579 curSeg = curSeg->next;
1580 } while (curSeg->id != segId);
1581 } while (GfParmListSeekNext(TrackHandle, path) == 0);
1582 }
1583
1584 /* Update the coord to be positives */
1585 theTrack->min.x = 0;
1586 theTrack->min.y = 0;
1587 theTrack->min.z = 0;
1588 theTrack->max.x = xmax - xmin;
1589 theTrack->max.y = ymax - ymin;
1590 theTrack->max.z = zmax - zmin;
1591
1592 curSeg = theTrack->seg;
1593 for(i=0; i<theTrack->nseg; i++) { /* read the segment data: */
1594 if ((curSeg->lgfromstart + curSeg->length) > (theTrack->length - 50.0)) {
1595 curSeg->raceInfo |= TR_LAST;
1596 } else if (curSeg->lgfromstart < 50.0) {
1597 curSeg->raceInfo |= TR_START;
1598 } else {
1599 curSeg->raceInfo |= TR_NORMAL;
1600 }
1601 normSeg(curSeg);
1602 if (curSeg->lside) {
1603 normSeg(curSeg->lside);
1604 if (curSeg->lside->lside) {
1605 normSeg(curSeg->lside->lside);
1606 }
1607 }
1608 if (curSeg->rside) {
1609 normSeg(curSeg->rside);
1610 if (curSeg->rside->rside) {
1611 normSeg(curSeg->rside->rside);
1612 }
1613 }
1614 curSeg = curSeg->next;
1615 }
1616
1617
1618 if (*camList != NULL) {
1619 curCam = *camList;
1620 do {
1621 curCam = curCam->next;
1622 curCam->pos.x -= xmin;
1623 curCam->pos.y -= ymin;
1624 curCam->pos.z -= zmin;
1625 } while (curCam != *camList);
1626 }
1627}
1628
1629
1630
1631
static Vector y[4]
Definition Convex.cpp:56
static const double PI
Scalar length(const Quaternion &q)
Definition Quaternion.h:193
void normalize(void)
Definition v2_t.h:247
float tdble
Floating point type used in TORCS.
Definition tgf.h:47
const char * GfParmGetStr(void *parmHandle, const char *path, const char *key, const char *deflt)
Get a string parameter from the parameter set handle.
Definition params.cpp:2453
tdble GfParmGetNum(void *handle, const char *path, const char *key, const char *unit, tdble deflt)
Get a numerical parameter from the parameter set handle.
Definition params.cpp:2534
char * GfParmListGetCurEltName(void *handle, const char *path)
Get current subsection name of the parameter set handle during subsection iteration.
Definition params.cpp:2410
int GfParmListSeekNext(void *handle, const char *path)
Advance to the next immediate subsection.
Definition params.cpp:2323
int GfParmListSeekFirst(void *handle, const char *path)
Select the first immediate subsection of a section.
Definition params.cpp:2286
int GfParmSetCurNum(void *handle, const char *path, const char *key, const char *unit, tdble val)
Set a numerical parameter in the parameter set handle based on subsection iteration.
Definition params.cpp:2834
tdble GfParmGetCurNum(void *handle, const char *path, const char *key, const char *unit, tdble deflt)
Get a numerical parameter from the parameter set handle based on subsection iteration.
Definition params.cpp:2578
const char * GfParmGetCurStr(void *handle, const char *path, const char *key, const char *deflt)
Get a string parameter from the parameter set handle based on subsection iteration.
Definition params.cpp:2496
struct trackSeg tTrackSeg
Track segment (tTrackSeg) The segments can be straights (type TR_STR): (the track goes from the right...
tdble RtTrackGetWidth(tTrackSeg *seg, tdble toStart)
Get the track width at the specified point.
Definition rttrack.cpp:59
v2t< float > vec2f
Definition linalg_t.h:36
struct RoadCam * next
Definition track.h:247
char * name
Definition track.h:245
t3Dd pos
Definition track.h:246
int * marks
marks array
Definition track.h:254
int nbMarks
turn marks
Definition track.h:253
tTrkLocPos pos
Center of the pit position.
Definition track.h:457
tdble y
y coordinate
Definition tgf.h:116
tdble z
z coordinate
Definition tgf.h:117
tdble x
x coordinate
Definition tgf.h:115
Track structure.
Definition track.h:533
Pits Info Structure.
Definition track.h:469
tTrackSeg * pitStart
Pit lane segment.
Definition track.h:487
tTrackSeg * pitEntry
Pit lane segment.
Definition track.h:486
int nPitSeg
actual number of pits
Definition track.h:478
tTrackOwnPit * driversPits
List of pits by driver.
Definition track.h:490
tTrackSeg * pitExit
Pit lane segment.
Definition track.h:489
int side
Pits side:
Definition track.h:479
tdble len
Lenght of each pit stop.
Definition track.h:483
tTrackSeg * pitEnd
Pit lane segment.
Definition track.h:488
tdble speedLimit
Speed limit between pitStart and pitEnd.
Definition track.h:485
int type
Type of Pit:
Definition track.h:470
int nMaxPits
number max of pits
Definition track.h:477
tdble width
Width of each pit stop.
Definition track.h:484
Location on the track in local coordinates.
Definition track.h:434
tdble toMiddle
Distance (+ to left, - to right) relative to the middle of segment.
Definition track.h:448
tdble toLeft
Distance (- to left, + to right) relative to left side of segment.
Definition track.h:449
tdble toRight
Distance (+ to left, - to right) relative to the right side of segment.
Definition track.h:447
tTrackSeg * seg
Track segment.
Definition track.h:435
int type
Type of description:
Definition track.h:436
tdble toStart
Distance to start of segment (or arc if turn)
Definition track.h:446
tdble width
Barrier width.
Definition track.h:278
tdble height
Barrier height.
Definition track.h:279
tTrackSurface * surface
Barrier surface.
Definition track.h:280
vec2f normal
Definition track.h:281
int style
Barrier style.
Definition track.h:277
int type
Geometrical type:
Definition track.h:297
tTrackSurface * surface
Segment surface.
Definition track.h:409
tdble height
Max height for curbs.
Definition track.h:380
tSegExt * ext
Definition track.h:407
t3Dd vertex[4]
Coordinates of the 4 corners of the segment.
Definition track.h:342
tdble radiusr
Radius in meters of the right side of the track (>0)
Definition track.h:338
unsigned int raceInfo
Type of segment regarding the race: Mask value in:
Definition track.h:382
int envIndex
Definition track.h:378
tdble radius
Radius in meters of the middle of the track (>0)
Definition track.h:337
tdble arc
Arc in rad of the curve (>0)
Definition track.h:340
tdble angle[7]
Definition track.h:354
tdble lgfromstart
Length of beginning of segment from starting line.
Definition track.h:336
int id
Segment number.
Definition track.h:295
t3Dd center
Center of the curve.
Definition track.h:341
tdble Kyl
Definition track.h:376
const char * name
Segment name.
Definition track.h:294
tdble length
Length in meters of the middle of the track.
Definition track.h:332
tdble radiusl
Radius in meters of the left side of the track (>0)
Definition track.h:339
tdble Kzw
Definition track.h:374
tRoadCam * cam
Definition track.h:411
struct trackSeg * rside
Definition track.h:421
tTrackBarrier * barrier[2]
Segment barriers.
Definition track.h:410
struct trackSeg * next
Next segment.
Definition track.h:412
tdble startWidth
Width of the beginning of the segment.
Definition track.h:334
struct trackSeg * prev
Previous segment.
Definition track.h:413
int style
Border and barrier segments style:
Definition track.h:319
struct trackSeg * side[2]
Definition track.h:422
t3Dd rgtSideNormal
Definition track.h:377
tdble width
Width of the segment (if constant width)
Definition track.h:333
tdble Kzl
Definition track.h:373
int type2
Position type:
Definition track.h:306
struct trackSeg * lside
Definition track.h:421
tdble endWidth
Width of the end of the segment.
Definition track.h:335
tdble kRebound
Coefficient of energy restitution.
Definition track.h:265
tdble kDammage
Dammages in case of collision.
Definition track.h:269
tdble kFriction
Coefficient of friction.
Definition track.h:264
tdble kRollRes
Rolling resistance.
Definition track.h:266
const char * material
Type of material used.
Definition track.h:262
struct trackSurface * next
Next surface in list.
Definition track.h:260
tdble kRoughWaveLen
Wave length in m of the surface.
Definition track.h:268
tdble kRoughness
Roughtness in m of the surface (wave height)
Definition track.h:267
#define MIN(x, y)
Definition tgf.h:56
static void GfFatal(const char *fmt,...)
Definition tgf.h:338
#define MAX(x, y)
Definition tgf.h:52
#define TSTZ(z)
Definition track3.cpp:40
static const char * KeySideSurface[2]
Definition track3.cpp:47
static void AddSides(tTrackSeg *curSeg, void *TrackHandle, tTrack *theTrack, int curStep, int steps)
Definition track3.cpp:176
static void InitSides(void *TrackHandle, tTrack *theTrack)
Definition track3.cpp:128
static int barrierStyle[2]
Definition track3.cpp:83
static tdble borderHeight[2]
Definition track3.cpp:76
static const char * KeySideWidth[2]
Definition track3.cpp:48
#define MAX_TMP_INTS
static const char * KeyBarrierSurface[2]
Definition track3.cpp:58
static tTrackSurface * borderSurface[2]
Definition track3.cpp:79
static const char * KeyBarrierStyle[2]
Definition track3.cpp:60
static const char * barrierMaterial[2]
Definition track3.cpp:84
static tdble borderWidth[2]
Definition track3.cpp:75
static tdble barrierWidth[2]
Definition track3.cpp:81
static tTrackSurface * barrierSurface[2]
Definition track3.cpp:85
static tdble ymin
Definition track3.cpp:30
void ReadTrack3(tTrack *theTrack, void *TrackHandle, tRoadCam **camList, int ext)
Definition track3.cpp:1282
static const char * sideMaterial[2]
Definition track3.cpp:69
static const char * KeySideStartWidth[2]
Definition track3.cpp:49
static const char * ValStyle[4]
Definition track3.cpp:63
static const char * KeyBarrierWidth[2]
Definition track3.cpp:59
static int envIndex
Definition track3.cpp:73
static tTrackSurface * AddTrackSurface(void *TrackHandle, tTrack *theTrack, const char *material)
Definition track3.cpp:90
#define TSTX(x)
Definition track3.cpp:32
static tdble sideStartWidth[2]
Definition track3.cpp:67
static const char * KeyBarrierHeight[2]
Definition track3.cpp:61
static tdble sideEndWidth[2]
Definition track3.cpp:66
static const char * KeyBorderWidth[2]
Definition track3.cpp:54
static const char * KeyBorderStyle[2]
Definition track3.cpp:55
static tdble ymax
Definition track3.cpp:30
static void CreateSegRing3(void *TrackHandle, tTrack *theTrack, tTrackSeg *start, tTrackSeg *end, int ext)
Definition track3.cpp:775
static tdble zmin
Definition track3.cpp:30
static const char * KeySideEndWidth[2]
Definition track3.cpp:50
static int sideBankType[2]
Definition track3.cpp:68
static tdble barrierHeight[2]
Definition track3.cpp:82
static tTrackSurface * sideSurface[2]
Definition track3.cpp:70
static const char * KeyBorderSurface[2]
Definition track3.cpp:53
static tdble zmax
Definition track3.cpp:30
static tdble GlobalStepLen
Definition track3.cpp:87
static tdble xmin
Definition track3.cpp:30
static const char * borderMaterial[2]
Definition track3.cpp:78
static int borderStyle[2]
Definition track3.cpp:77
static void normSeg(tTrackSeg *curSeg)
Definition track3.cpp:756
static const char * KeyBorderHeight[2]
Definition track3.cpp:56
static tdble xmax
Definition track3.cpp:30
static const char * KeySideBankType[2]
Definition track3.cpp:51
#define TSTY(y)
Definition track3.cpp:36
static void * TrackHandle
Definition track.cpp:33
static tTrack * theTrack
Definition track.cpp:31
#define TRK_ATT_RSSURF
Definition track.h:673
#define TRK_ATT_RBAH
Definition track.h:692
#define TRK_VAL_SPLINE
Definition track.h:237
#define TRK_ATT_CAM_FOV
Definition track.h:222
#define TRK_ATT_RSWE
Definition track.h:672
#define TRK_ATT_DAMMAGE
Definition track.h:126
#define TRK_VAL_STR
Definition track.h:157
#define TRK_ATT_PIT_ENTRY
Definition track.h:651
#define TRK_ATT_LBS
Definition track.h:674
#define TRK_ATT_ID
Definition track.h:174
#define TRK_VAL_PIT_TYPE_NONE
Definition track.h:696
#define TR_XS
X Start angle.
Definition track.h:368
#define TRK_ATT_BKS
Definition track.h:172
#define TRK_ATT_PIT_LEN
Definition track.h:657
#define TRK_ATT_PROFTGTEL
Definition track.h:181
#define TRK_ATT_ZSR
Definition track.h:168
#define TRK_ATT_WIDTH
Definition track.h:45
#define TR_START
Segment after start line.
Definition track.h:395
struct TrackOwnPit tTrackOwnPit
Driver's pit.
#define TRK_VAL_GRASS
Definition track.h:231
#define TR_RSIDE
Right side segment (outer segment)
Definition track.h:315
#define TRK_ATT_PROFTGTER
Definition track.h:183
#define TRK_ATT_PROFSTEPS
Definition track.h:176
#define TR_CS
Center start angle.
Definition track.h:370
#define TR_LAST
Segment before start line.
Definition track.h:394
#define TRK_ATT_PROFTGTSL
Definition track.h:180
#define TR_PITEND
Car pit End.
Definition track.h:402
#define TRK_VAL_BARRIER
Definition track.h:234
#define TRK_VAL_WALL
Definition track.h:211
#define TRK_VAL_CURB
Definition track.h:212
#define TR_PITSTART
Car pit Star.
Definition track.h:401
#define TRK_ATT_RSWS
Definition track.h:671
#define TRK_ATT_RBSURF
Definition track.h:681
#define TRK_VAL_RGT
Definition track.h:159
#define TRK_LST_CAM
Definition track.h:650
#define TR_YR
Y Right angle.
Definition track.h:367
#define TRK_ATT_SURF
Definition track.h:46
#define TRK_LST_SURF
Definition track.h:649
#define TR_MAIN
Main track segment (ie road part)
Definition track.h:313
#define TRK_ATT_PROFTGTS
Definition track.h:178
struct trackSurface tTrackSurface
Surface.
#define TRK_ATT_ENVIND
Definition track.h:661
#define TRK_ATT_LG
Definition track.h:161
#define TR_FENCE
Fence (no width) (barrier only)
Definition track.h:329
#define TRK_ATT_RADIUSEND
Definition track.h:163
#define TRK_ATT_RBS
Definition track.h:678
#define TRK_SECT_MAIN
Definition track.h:150
#define TR_SPEEDLIMIT
Segment where the speed is limited.
Definition track.h:397
#define TRK_ATT_ROUGHTWL
Definition track.h:125
#define TR_LFT
Left curve.
Definition track.h:303
#define TRK_ATT_PIT_WIDTH
Definition track.h:658
#define TRK_VAL_LEVEL
Definition track.h:240
#define TRK_ATT_SPD_LIM
Definition track.h:195
#define TRK_SECT_SURFACES
Definition track.h:119
#define TRK_ATT_LBH
Definition track.h:676
#define TRK_ATT_ROLLRES
Definition track.h:123
#define TRK_ATT_ROUGHT
Definition track.h:124
#define TR_XE
X End angle.
Definition track.h:369
#define TRK_ATT_LST
Definition track.h:664
#define TR_EL
End-Left corner.
Definition track.h:351
#define TRK_ATT_REBOUND
Definition track.h:127
#define TRK_ATT_PROFSTEPSLEN
Definition track.h:177
#define TRK_ATT_PIT_TYPE
Definition track.h:655
#define TRK_ATT_LBAH
Definition track.h:687
#define TR_ZE
Z End angle.
Definition track.h:365
#define TRK_ATT_ZE
Definition track.h:166
#define TRK_ATT_RSW
Definition track.h:670
#define TRK_ATT_ZS
Definition track.h:165
#define TRK_VAL_FENCE
Definition track.h:213
struct RoadCam tRoadCam
road camera
#define TRK_LST_SEG
Definition track.h:660
#define TR_RBORDER
Right border segment (inner segment)
Definition track.h:317
#define TRK_ATT_LSWS
Definition track.h:666
#define TRK_ATT_PROFIL
Definition track.h:175
#define TRK_ATT_PIT_SIDE
Definition track.h:656
#define TRK_VAL_LFT
Definition track.h:158
#define TRK_ATT_LBW
Definition track.h:675
#define TRK_ATT_LSWE
Definition track.h:667
#define TR_NORMAL
Normal segment.
Definition track.h:393
#define TRK_ATT_HEIGHT
Definition track.h:207
#define TR_YL
Y Left angle.
Definition track.h:366
#define TRK_ATT_RADIUS
Definition track.h:162
#define TRK_ATT_LSSURF
Definition track.h:668
#define TRK_ATT_LBASURF
Definition track.h:689
#define TRK_ATT_RBAW
Definition track.h:691
#define TRK_ATT_FRICTION
Definition track.h:122
#define TRK_ATT_LBAS
Definition track.h:685
#define TRK_ATT_ZEL
Definition track.h:169
#define TRK_ATT_ZSL
Definition track.h:167
#define TR_PITEXIT
Segment where the pit lane cross the main track.
Definition track.h:399
#define TR_LBORDER
Left border segment (inner segment)
Definition track.h:316
#define TRK_ATT_ZER
Definition track.h:170
struct SegExt tSegExt
Extended track segment.
#define TR_LPOS_MAIN
Relative to the main segment, mostly used for racing on the main track.
Definition track.h:442
#define TRK_VAL_ASPHALT
Definition track.h:225
#define TRK_ATT_PROFTGTSR
Definition track.h:182
#define TR_PIT_ON_TRACK_SIDE
The pits are on the track side.
Definition track.h:475
#define TRK_ATT_MARKS
Definition track.h:184
#define TRK_ATT_TORIGHT
Definition track.h:219
#define TRK_ATT_RBASURF
Definition track.h:694
struct trackBarrier tTrackBarrier
Barrier.
#define TRK_ATT_PIT_EXIT
Definition track.h:652
#define TRK_ATT_LBAW
Definition track.h:686
#define TR_PITENTRY
Segment where the pit lane cross the main track.
Definition track.h:398
#define TRK_ATT_RBW
Definition track.h:679
#define TRK_ATT_RBH
Definition track.h:680
#define TRK_ATT_RST
Definition track.h:669
#define TRK_VAL_PIT_TYPE_SIDE
Definition track.h:697
#define TRK_ATT_PROFTGTE
Definition track.h:179
#define TRK_ATT_SEGMENT
Definition track.h:218
#define TRK_ATT_LBSURF
Definition track.h:677
#define TRK_ATT_TOSTART
Definition track.h:220
#define TR_SIDE_LFT
Definition track.h:418
#define TR_STR
Straight.
Definition track.h:304
#define TRK_ATT_RBAS
Definition track.h:690
#define TRK_ATT_PIT_START
Definition track.h:653
#define TR_ER
End_Right corner.
Definition track.h:352
#define TRK_ATT_PIT_END
Definition track.h:654
#define TR_PLAN
Flat (border only)
Definition track.h:326
#define TR_LSIDE
Left side segment (outer segment)
Definition track.h:314
#define TRK_SECT_CAM
Definition track.h:216
#define TR_CURB
Curb (border only)
Definition track.h:327
#define TR_SL
Start-Left corner.
Definition track.h:349
#define TRK_ATT_LSW
Definition track.h:665
#define TRK_ATT_TYPE
Definition track.h:152
#define TRK_ATT_BKE
Definition track.h:173
#define TRK_ATT_CAM_FOVE
Definition track.h:223
#define TR_PIT
Car pit.
Definition track.h:400
#define TR_RGT
Right curve.
Definition track.h:302
#define TRK_VAL_PLAN
Definition track.h:210
#define TR_PITBUILDING
Pit building wall (barrier only)
Definition track.h:330
#define TR_ZS
Rotation angles of the track in rad anti-clockwise: Index in:
Definition track.h:364
#define TRK_ATT_GRADE
Definition track.h:171
#define TRK_ATT_ARC
Definition track.h:164
#define TR_WALL
Wall (barrier only)
Definition track.h:328
#define TR_SR
Start-Right corner.
Definition track.h:350
tdble TrackSpline(tdble p0, tdble p1, tdble t0, tdble t1, tdble t)
Definition trackutil.cpp:79
void TrackLocal2Global(tTrkLocPos *p, tdble *X, tdble *Y)
Definition trackutil.cpp:29
tdble TrackHeightL(tTrkLocPos *p)
Definition trackutil.cpp:55