TORCS  1.3.9
The Open Racing Car Simulator
track4.cpp
Go to the documentation of this file.
1 /***************************************************************************
2 
3  file : track4.cpp
4  created : Sat May 18 12:46:26 CEST 2002
5  copyright : (C) 2002-2015 by Eric Espie, Bernhard Wymann
6  email : berniw@bluewin.ch
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 
26 #include <stdlib.h>
27 #include <math.h>
28 #include <stdio.h>
29 
30 #include <tgf.h>
31 #include <robottools.h>
32 #include <track.h>
33 #include <portability.h>
34 #include "trackinc.h"
35 
37 
38 #define TSTX(x) do { \
39  if (xmin > (x)) xmin = (x); \
40  if (xmax < (x)) xmax = (x); \
41  } while (0)
42 
43 #define TSTY(y) do { \
44  if (ymin > (y)) ymin = (y); \
45  if (ymax < (y)) ymax = (y); \
46  } while (0)
47 
48 #define TSTZ(z) do { \
49  if (zmin > (z)) zmin = (z); \
50  if (zmax < (z)) zmax = (z); \
51  } while (0)
52 
53 /*
54  * Sides global variables
55  */
56 static const char *SectSide[2] = {TRK_SECT_RSIDE, TRK_SECT_LSIDE};
57 static const char *SectBorder[2] = {TRK_SECT_RBORDER, TRK_SECT_LBORDER};
58 static const char *SectBarrier[2] = {TRK_SECT_RBARRIER, TRK_SECT_LBARRIER};
59 
60 static const char *ValStyle[] = {TRK_VAL_PLAN, TRK_VAL_CURB, TRK_VAL_WALL, TRK_VAL_FENCE, TRK_VAL_FENCE}; // TODO: TRK_VAL_FENCE 2 times, remove?
61 
62 static tdble sideEndWidth[2];
64 static int sideBankType[2];
65 static const char *sideMaterial[2];
67 
68 static int envIndex;
69 static tdble DoVfactor=1.0;
70 
71 static tdble borderWidth[2];
72 static tdble borderHeight[2];
73 static int borderStyle[2];
74 static const char *borderMaterial[2];
76 
77 static tdble barrierWidth[2];
78 static tdble barrierHeight[2];
79 static int barrierStyle[2];
80 static const char *barrierMaterial[2];
82 
83 static tdble GlobalStepLen = 0;
84 
85 // Function prototypes
86 static void initSideForTurn(
87  const int turntype,
88  tTrackSeg* const curBorder,
89  const tTrackSeg* const curSeg,
90  const int side,
91  const int bankingtype,
92  const tdble startwidth,
93  const tdble endwidth,
94  const tdble maxwidth
95 );
96 
97 static void initSideForStraight(
98  tTrackSeg* const curBorder,
99  const tTrackSeg* const curSeg,
100  const int side,
101  const int bankingtype,
102  const tdble startwidth,
103  const tdble endwidth
104 );
105 
106 static tTrackSeg* commonSideInit(
107  tTrackSeg* const curSeg,
108  const int side,
109  const int lefttype,
110  const int righttype,
111  const int bankingtype,
112  const tdble startwidth,
113  const tdble endwidth,
114  tTrackSurface* surface,
115  const tdble borderheight,
116  const int borderstyle
117 );
118 
119 
130 static tTrackSurface* getTrackSurface(void *trackHandle, tTrack *theTrack, const char *material)
131 {
132  const int BUFSIZE = 256;
133  char path[BUFSIZE];
134  tTrackSurface *curSurf;
135 
136  // Search within existing surfaces
137  curSurf = theTrack->surfaces;
138  while (curSurf) {
139  if (strcmp(curSurf->material, material) == 0) {
140  return curSurf;
141  }
142  curSurf = curSurf->next;
143  }
144 
145  // Create a new surface
146  curSurf = (tTrackSurface*)malloc(sizeof(tTrackSurface));
147  if (!curSurf) {
148  GfFatal("AddTrackSurface: Memory allocation failed\n");
149  }
150 
151  curSurf->material = material;
152  snprintf(path, BUFSIZE, "%s/%s", TRK_SECT_SURFACES, material);
153  curSurf->kFriction = GfParmGetNum(trackHandle, path, TRK_ATT_FRICTION, (char*)NULL, 0.8f);
154  curSurf->kRollRes = GfParmGetNum(trackHandle, path, TRK_ATT_ROLLRES, (char*)NULL, 0.001f);
155  curSurf->kRoughness = GfParmGetNum(trackHandle, path, TRK_ATT_ROUGHT, (char*)NULL, 0.0f) / 2.0f;
156  curSurf->kRoughWaveLen = 2.0 * PI / GfParmGetNum(trackHandle, path, TRK_ATT_ROUGHTWL, (char*)NULL, 1.0f);
157  curSurf->kDammage = GfParmGetNum(trackHandle, path, TRK_ATT_DAMMAGE, (char*)NULL, 10.0f);
158  curSurf->kRebound = GfParmGetNum(trackHandle, path, TRK_ATT_REBOUND, (char*)NULL, 0.5f);
159 
160  curSurf->next = theTrack->surfaces;
161  theTrack->surfaces = curSurf;
162 
163  return curSurf;
164 }
165 
166 
172 static void readDefaultSideParameters(void *trackHandle, tTrack *theTrack)
173 {
174  int side;
175  const char *style;
176  const int BUFSIZE = 256;
177  char path[BUFSIZE];
178 
179  // Side: right and left (see SectSide, SectBorder, SectBarrier)
180  for (side = 0; side < 2; side++) {
181  // Side parameters
182  snprintf(path, BUFSIZE, "%s/%s", TRK_SECT_MAIN, SectSide[side]);
183  sideMaterial[side] = GfParmGetStr(trackHandle, path, TRK_ATT_SURF, TRK_VAL_GRASS);
184  sideSurface[side] = getTrackSurface(trackHandle, theTrack, sideMaterial[side]);
185  sideEndWidth[side] = GfParmGetNum(trackHandle, path, TRK_ATT_WIDTH, (char*)NULL, 0.0);
186 
187  // Banking of sides
188  if (strcmp(TRK_VAL_LEVEL, GfParmGetStr(trackHandle, path, TRK_ATT_BANKTYPE, TRK_VAL_LEVEL)) == 0) {
189  sideBankType[side] = 0;
190  } else {
191  sideBankType[side] = 1;
192  }
193 
194  // Border parameters
195  snprintf(path, BUFSIZE, "%s/%s", TRK_SECT_MAIN, SectBorder[side]);
196  borderMaterial[side] = GfParmGetStr(trackHandle, path, TRK_ATT_SURF, TRK_VAL_GRASS);
197  borderSurface[side] = getTrackSurface(trackHandle, theTrack, borderMaterial[side]);
198  borderWidth[side] = GfParmGetNum(trackHandle, path, TRK_ATT_WIDTH, (char*)NULL, 0.0);
199  borderHeight[side] = GfParmGetNum(trackHandle, path, TRK_ATT_HEIGHT, (char*)NULL, 0.0);
200  style = GfParmGetStr(trackHandle, path, TRK_ATT_STYLE, TRK_VAL_PLAN);
201 
202  if (strcmp(style, TRK_VAL_PLAN) == 0) {
203  borderStyle[side] = TR_PLAN;
204  } else if (strcmp(style, TRK_VAL_CURB) == 0) {
205  borderStyle[side] = TR_CURB;
206  } else {
207  borderStyle[side] = TR_WALL;
208  }
209 
210  // Barrier parameters
211  snprintf(path, BUFSIZE, "%s/%s", TRK_SECT_MAIN, SectBarrier[side]);
212  barrierMaterial[side] = GfParmGetStr(trackHandle, path, TRK_ATT_SURF, TRK_VAL_BARRIER);
213  barrierSurface[side] = getTrackSurface(trackHandle, theTrack, barrierMaterial[side]);
214  barrierHeight[side] = GfParmGetNum(trackHandle, path, TRK_ATT_HEIGHT, (char*)NULL, 0.6f);
215  style = GfParmGetStr(trackHandle, path, TRK_ATT_STYLE, TRK_VAL_FENCE);
216  if (strcmp(style, TRK_VAL_FENCE) == 0) {
217  barrierStyle[side] = TR_FENCE;
218  barrierWidth[side] = 0;
219  } else {
220  barrierStyle[side] = TR_WALL;
221  barrierWidth[side] = GfParmGetNum(trackHandle, path, TRK_ATT_WIDTH, (char*)NULL, 0.5);
222  }
223  }
224 }
225 
226 
235 static void addSides(tTrackSeg *curSeg, void *trackHandle, tTrack *theTrack, int curStep, int steps)
236 {
237  tTrackSeg *mSeg;
238  tTrackBarrier *curBarrier;
239  tdble w, sw, ew, bw;
240  int side;
241  const char *style;
242  tdble Kew;
243  const int BUFSIZE = 256;
244  char path[BUFSIZE];
245  char path2[BUFSIZE];
246  char *segName;
247 
248  mSeg = curSeg;
249 
250  snprintf(path, BUFSIZE, "%s/%s", TRK_SECT_MAIN, TRK_LST_SEGMENTS);
251  segName = GfParmListGetCurEltName(trackHandle, path);
252  snprintf(path, BUFSIZE, "%s/%s/%s", TRK_SECT_MAIN, TRK_LST_SEGMENTS, segName);
253 
254  for (side = 0; side < 2; side++) {
255  curSeg = mSeg;
256 
257  if (curStep == 0) {
258  // Initialize on the first step
259  // Side parameters
260  snprintf(path2, BUFSIZE, "%s/%s", path, SectSide[side]);
261  sw = GfParmGetNum(trackHandle, path2, TRK_ATT_SWIDTH, (char*)NULL, sideEndWidth[side]);
262  w = GfParmGetNum(trackHandle, path2, TRK_ATT_WIDTH, (char*)NULL, sw);
263  ew = GfParmGetNum(trackHandle, path2, TRK_ATT_EWIDTH, (char*)NULL, w);
264 
265  sideStartWidth[side] = sw;
266  sideEndWidth[side] = ew;
267  sideMaterial[side] = GfParmGetStr(trackHandle, path2, TRK_ATT_SURF, sideMaterial[side]);
268  sideSurface[side] = getTrackSurface(trackHandle, theTrack, sideMaterial[side]);
269 
270  // Border parameters
271  snprintf(path2, BUFSIZE, "%s/%s", path, SectBorder[side]);
272  bw = GfParmGetNum(trackHandle, path2, TRK_ATT_WIDTH, (char*)NULL, borderWidth[side]);
273  borderWidth[side] = bw;
274  borderHeight[side] = GfParmGetNum(trackHandle, path2, TRK_ATT_HEIGHT, (char*)NULL, borderHeight[side]);
275  borderMaterial[side] = GfParmGetStr(trackHandle, path2, TRK_ATT_SURF, borderMaterial[side]);
276  borderSurface[side] = getTrackSurface(trackHandle, theTrack, borderMaterial[side]);
277  style = GfParmGetStr(trackHandle, path2, TRK_ATT_STYLE, ValStyle[borderStyle[side]]);
278 
279  if (strcmp(style, TRK_VAL_PLAN) == 0) {
280  borderStyle[side] = TR_PLAN;
281  } else if (strcmp(style, TRK_VAL_CURB) == 0) {
282  borderStyle[side] = TR_CURB;
283  } else {
284  borderStyle[side] = TR_WALL;
285  }
286 
287  // Barrier parameters
288  snprintf(path2, BUFSIZE, "%s/%s", path, SectBarrier[side]);
289  barrierMaterial[side] = GfParmGetStr(trackHandle, path2, TRK_ATT_SURF, barrierMaterial[side]);
290  barrierSurface[side] = getTrackSurface(trackHandle, theTrack, barrierMaterial[side]);
291  barrierHeight[side] = GfParmGetNum(trackHandle, path2, TRK_ATT_HEIGHT, (char*)NULL, barrierHeight[side]);
292  style = GfParmGetStr(trackHandle, path2, TRK_ATT_STYLE, ValStyle[barrierStyle[side]]);
293 
294  if (strcmp(style, TRK_VAL_FENCE) == 0) {
295  barrierStyle[side] = TR_FENCE;
296  barrierWidth[side] = 0;
297  } else {
298  barrierStyle[side] = TR_WALL;
299  barrierWidth[side] = GfParmGetNum(trackHandle, path2, TRK_ATT_WIDTH, (char*)NULL, barrierWidth[side]);
300  }
301  } else {
302  // Reset sw, ew, bw for steps after initialization
303  sw = sideStartWidth[side];
304  ew = sideEndWidth[side];
305  bw = borderWidth[side];
306  }
307 
308  // Calculate parameters considering the current step
309  Kew = (ew - sw) / (tdble)steps;
310  ew = sw + (tdble)(curStep+1) * Kew;
311  sw = sw + (tdble)(curStep) * Kew;
312 
313  // Add borders
314  if (bw > 0.0f) {
315  curSeg = commonSideInit(curSeg, side, TR_LBORDER, TR_RBORDER, sideBankType[side], bw, bw,
316  borderSurface[side], borderHeight[side], borderStyle[side]);
317  }
318 
319  // Add sides
320  if ((sw > 0.0f) || (ew > 0.0f)) {
321  commonSideInit(curSeg, side, TR_LSIDE, TR_RSIDE, sideBankType[side], sw, ew,
322  sideSurface[side], 0.0f, TR_PLAN);
323  }
324 
325  // Add barriers
326  curBarrier = (tTrackBarrier*)malloc(sizeof(tTrackBarrier));
327  if (!curBarrier) {
328  GfFatal("AddSides: memory allocation error");
329  }
330  curBarrier->style = barrierStyle[side];
331  curBarrier->width = barrierWidth[side];
332  curBarrier->height = barrierHeight[side];
333  curBarrier->surface = barrierSurface[side];
334 
335  // Compute normal of barrier for side collisions.
336  tTrackSeg *bseg = mSeg;
337  int bstart, bend;
338  float bsign;
339 
340  if (side == TR_SIDE_LFT) {
341  bstart = TR_SL;
342  bend = TR_EL;
343  bsign = -1.0f;
344  } else {
345  bstart = TR_SR;
346  bend = TR_ER;
347  bsign = 1.0f;
348  }
349 
350  while (bseg->side[side] != NULL) {
351  bseg = bseg->side[side];
352  }
353 
354  vec2f n(
355  -(bseg->vertex[bend].y - bseg->vertex[bstart].y)*bsign,
356  (bseg->vertex[bend].x - bseg->vertex[bstart].x)*bsign
357  );
358 
359  n.normalize();
360  curBarrier->normal = n;
361 
362  mSeg->barrier[side] = curBarrier;
363  }
364 }
365 
366 
371 static void normSeg(tTrackSeg *curSeg)
372 {
373  curSeg->vertex[TR_SR].x -= xmin;
374  curSeg->vertex[TR_SR].y -= ymin;
375  curSeg->vertex[TR_SR].z -= zmin;
376  curSeg->vertex[TR_SL].x -= xmin;
377  curSeg->vertex[TR_SL].y -= ymin;
378  curSeg->vertex[TR_SL].z -= zmin;
379  curSeg->vertex[TR_ER].x -= xmin;
380  curSeg->vertex[TR_ER].y -= ymin;
381  curSeg->vertex[TR_ER].z -= zmin;
382  curSeg->vertex[TR_EL].x -= xmin;
383  curSeg->vertex[TR_EL].y -= ymin;
384  curSeg->vertex[TR_EL].z -= zmin;
385  curSeg->center.x -= xmin;
386  curSeg->center.y -= ymin;
387 }
388 
389 
390 static void CreateSegRing(void *TrackHandle, tTrack *theTrack, int ext)
391 {
392  int j;
393  int segread, curindex;
394  tdble radius, radiusend = 0, dradius;
395  tdble innerradius;
396  tdble arc;
397  tdble length;
398  tTrackSeg *curSeg;
399  tTrackSeg *root;
400  tdble alf;
401  tdble xr, yr, newxr, newyr;
402  tdble xl, yl, newxl, newyl;
403  tdble cenx, ceny;
404  tdble width, wi2;
405  tdble x1, x2, y1, y2;
406  tdble al, alfl;
407  tdble zsl, zsr, zel, zer, zs, ze;
408  tdble bankings, bankinge, dz; //dzl, dzr;
409  tdble etgt, stgt;
410  tdble etgtl, stgtl;
411  tdble etgtr, stgtr;
412  tdble stepslg = 0;
413  int steps, curStep;
414  const char *segtype = (char*)NULL;
415  const char *material;
416  tTrackSurface *surface;
417  const char *segName;
418  int type;
419  const char *profil;
420  tdble totLength;
421 
422  tdble tl, dtl, T1l, T2l;
423  tdble tr, dtr, T1r, T2r;
424  tdble curzel, curzer, curArc, curLength, curzsl, curzsr;
425  tdble grade;
426 
427  void *segNameHash = NULL;
428  const int BUFSIZE = 256;
429  char path[BUFSIZE];
430 
431 #define MAX_TMP_INTS 256
432  int mi[MAX_TMP_INTS];
433  int ind = 0;
434 
435  radius = arc = length = alf = xr = yr = newxr = newyr = xl = yl = 0;
436  zel = zer = etgtl = etgtr = newxl = newyl = 0;
437  type = 0;
438 
439  width = GfParmGetNum(TrackHandle, TRK_SECT_MAIN, TRK_ATT_WIDTH, (char*)NULL, 15.0);
440  wi2 = width / 2.0;
441 
442  grade = -100000.0;
443  root = (tTrackSeg*)NULL;
444  totLength = 0;
445 
446  snprintf(path, BUFSIZE, "%s/%s", TRK_SECT_MAIN, TRK_LST_SEGMENTS);
447  yl = width;
448  zsl = zsr = zel = zer = zs = ze = 0.0;
449  stgt = etgt = 0.0;
450  stgtl = etgtl = 0.0;
451  stgtr = etgtr = 0.0;
452 
453  /* Main Track */
455  surface = getTrackSurface(TrackHandle, theTrack, material);
456  envIndex = 0;
457  DoVfactor =1.0;
459 
460  if (ext) {
461  segNameHash = GfHashCreate(GF_HASH_TYPE_STR);
462  }
463 
464  segread = 0;
465  curindex = 0;
467  do {
468  segtype = GfParmGetCurStr(TrackHandle, path, TRK_ATT_TYPE, NULL);
469  if (segtype == 0) {
470  continue;
471  }
472  segread++;
473 
474  zsl = zel;
475  zsr = zer;
476  TSTZ(zsl);
477  TSTZ(zsr);
478 
479  /* Turn Marks */
480  if (ext) {
481  const char *marks = GfParmGetCurStr(TrackHandle, path, TRK_ATT_MARKS, NULL);
482  ind = 0;
483  if (marks) {
484  char* tmpmarks = strdup(marks);
485  char *s = strtok(tmpmarks, ";");
486  while ((s != NULL) && (ind < MAX_TMP_INTS)) {
487  mi[ind] = (int)strtol(s, NULL, 0);
488  ind++;
489  s = strtok(NULL, ";");
490  }
491  free(tmpmarks);
492  }
493  }
494 
495  /* surface change */
496  material = GfParmGetCurStr(TrackHandle, path, TRK_ATT_SURF, material);
497  surface = getTrackSurface(TrackHandle, theTrack, material);
498  envIndex = (int) GfParmGetCurNum(TrackHandle, path, TRK_ATT_ENVIND, (char*)NULL, (float) (envIndex+1)) - 1;
499  // TODO: is the (int) intended?
500  DoVfactor = (float) ((int) GfParmGetCurNum(TrackHandle, path, TRK_ATT_DOVFACTOR, (char*)NULL, 1.0)) ;
501 
502  /* get segment type and length */
503  if (strcmp(segtype, TRK_VAL_STR) == 0) {
504  /* straight */
505  length = GfParmGetCurNum(TrackHandle, path, TRK_ATT_LG, (char*)NULL, 0);
506  type = TR_STR;
507  radius = radiusend = 0;
508  } else if (strcmp(segtype, TRK_VAL_LFT) == 0) {
509  /* left curve */
510  radius = GfParmGetCurNum(TrackHandle, path, TRK_ATT_RADIUS, (char*)NULL, 0);
511  radiusend = GfParmGetCurNum(TrackHandle, path, TRK_ATT_RADIUSEND, (char*)NULL, radius);
512  arc = GfParmGetCurNum(TrackHandle, path, TRK_ATT_ARC, (char*)NULL, 0);
513  type = TR_LFT;
514  length = (radius + radiusend) / 2.0 * arc;
515  } else if (strcmp(segtype, TRK_VAL_RGT) == 0) {
516  /* right curve */
517  radius = GfParmGetCurNum(TrackHandle, path, TRK_ATT_RADIUS, (char*)NULL, 0);
518  radiusend = GfParmGetCurNum(TrackHandle, path, TRK_ATT_RADIUSEND, (char*)NULL, radius);
519  arc = GfParmGetCurNum(TrackHandle, path, TRK_ATT_ARC, (char*)NULL, 0);
520  type = TR_RGT;
521  length = (radius + radiusend) / 2.0 * arc;
522  }
523  segName = GfParmListGetCurEltName(TrackHandle, path);
524  if (ext) {
525  if (GfHashGetStr(segNameHash, segName)) {
526  printf(">>>>>>>>> DUPLICATED SEGMENT NAME \"%s\" PLEASE CHANGE IT !!!!\n", segName);
527  exit(1);
528  }
529  GfHashAddStr(segNameHash, segName, segName);
530  }
531 
532  /* elevation and banking */
533  zsl = GfParmGetCurNum(TrackHandle, path, TRK_ATT_ZSL, (char*)NULL, zsl);
534  zsr = GfParmGetCurNum(TrackHandle, path, TRK_ATT_ZSR, (char*)NULL, zsr);
535  zel = GfParmGetCurNum(TrackHandle, path, TRK_ATT_ZEL, (char*)NULL, zel);
536  zer = GfParmGetCurNum(TrackHandle, path, TRK_ATT_ZER, (char*)NULL, zer);
537  ze = zs = -100000.0;
538  ze = GfParmGetCurNum(TrackHandle, path, TRK_ATT_ZE, (char*)NULL, ze);
539  zs = GfParmGetCurNum(TrackHandle, path, TRK_ATT_ZS, (char*)NULL, zs);
540  grade = GfParmGetCurNum(TrackHandle, path, TRK_ATT_GRADE, (char*)NULL, grade);
541  if (zs != -100000.0) {
542  zsr = zsl = zs;
543  } else {
544  zs = (zsl + zsr) / 2.0;
545  }
546  if (ze != -100000.0) {
547  zer = zel = ze;
548  } else if (grade != -100000.0) {
549  ze = zs + length * grade;
550  } else {
551  ze = (zel + zer) / 2.0;
552  }
553  bankings = atan2(zsl - zsr, width);
554  bankinge = atan2(zel - zer, width);
555  bankings = GfParmGetCurNum(TrackHandle, path, TRK_ATT_BKS, (char*)NULL, bankings);
556  bankinge = GfParmGetCurNum(TrackHandle, path, TRK_ATT_BKE, (char*)NULL, bankinge);
557  dz = tan(bankings) * width / 2.0;
558  zsl = zs + dz;
559  zsr = zs - dz;
560  dz = tan(bankinge) * width / 2.0;
561  zel = ze + dz;
562  zer = ze - dz;
563 
564  TSTZ(zsl);
565  TSTZ(zsr);
566 
567  /* Get segment profil */
569  stgtl = etgtl;
570  stgtr = etgtr;
571  if (strcmp(profil, TRK_VAL_SPLINE) == 0) {
572  steps = (int)GfParmGetCurNum(TrackHandle, path, TRK_ATT_PROFSTEPS, (char*)NULL, 1.0);
573  if (steps == 1) {
574  stepslg = GfParmGetCurNum(TrackHandle, path, TRK_ATT_PROFSTEPSLEN, (char*)NULL, GlobalStepLen);
575  if (stepslg) {
576  steps = (int)(length / stepslg) + 1;
577  } else {
578  steps = 1;
579  }
580  }
581  stgtl = GfParmGetCurNum(TrackHandle, path, TRK_ATT_PROFTGTSL, (char*)NULL, stgtl);
582  etgtl = GfParmGetCurNum(TrackHandle, path, TRK_ATT_PROFTGTEL, (char*)NULL, etgtl);
583  stgtr = GfParmGetCurNum(TrackHandle, path, TRK_ATT_PROFTGTSR, (char*)NULL, stgtr);
584  etgtr = GfParmGetCurNum(TrackHandle, path, TRK_ATT_PROFTGTER, (char*)NULL, etgtr);
585  stgt = etgt = -100000.0;
586  stgt = GfParmGetCurNum(TrackHandle, path, TRK_ATT_PROFTGTS, (char*)NULL, stgt);
587  etgt = GfParmGetCurNum(TrackHandle, path, TRK_ATT_PROFTGTE, (char*)NULL, etgt);
588  if (stgt != -100000.0) {
589  stgtl = stgtr = stgt;
590  }
591  if (etgt != -100000.0) {
592  etgtl = etgtr = etgt;
593  }
594  } else {
595  steps = 1;
596  stgtl = etgtl = (zel - zsl) / length;
597  stgtr = etgtr = (zer - zsr) / length;
598  }
599  GfParmSetCurNum(TrackHandle, path, TRK_ATT_ID, (char*)NULL, (tdble)curindex);
600 
601  //dzl = zel - zsl;
602  //dzr = zer - zsr;
603  T1l = stgtl * length;
604  T2l = etgtl * length;
605  tl = 0.0;
606  dtl = 1.0 / (tdble)steps;
607  T1r = stgtr * length;
608  T2r = etgtr * length;
609  tr = 0.0;
610  dtr = 1.0 / (tdble)steps;
611 
612  curStep = 0;
613  curzel = zsl;
614  curzer = zsr;
615  curArc = arc / (tdble)steps;
616  curLength = length / (tdble)steps;
617  dradius = (radiusend - radius) / (tdble)steps;
618  if (radiusend != radius) {
619  /* Compute the correct curLength... */
620  if (steps != 1) {
621  dradius = (radiusend - radius) / (tdble)(steps - 1);
622  tdble tmpAngle = 0;
623  tdble tmpRadius = radius;
624  for (curStep = 0; curStep < steps; curStep++) {
625  tmpAngle += curLength / tmpRadius;
626  tmpRadius += dradius;
627  }
628  curLength *= arc / tmpAngle;
629  }
630  }
631  curStep = 0;
632 
633  while (curStep < steps) {
634 
635  tl += dtl;
636  tr += dtr;
637 
638  curzsl = curzel;
639  curzel = TrackSpline(zsl, zel, T1l, T2l, tl);
640 
641  curzsr = curzer;
642  curzer = TrackSpline(zsr, zer, T1r, T2r, tr);
643 
644  if (dradius != 0) {
645  curArc = curLength / radius;
646  }
647 
648  /* allocate a new segment */
649  curSeg = (tTrackSeg*)calloc(1, sizeof(tTrackSeg));
650  if (root == NULL) {
651  root = curSeg;
652  curSeg->next = curSeg;
653  curSeg->prev = curSeg;
654  } else {
655  curSeg->next = root->next;
656  curSeg->next->prev = curSeg;
657  curSeg->prev = root;
658  root->next = curSeg;
659  root = curSeg;
660  }
661  curSeg->type2 = TR_MAIN;
662  curSeg->name = segName;
663  curSeg->id = curindex;
664  curSeg->width = curSeg->startWidth = curSeg->endWidth = width;
665  curSeg->surface = surface;
666  curSeg->envIndex = envIndex;
667  curSeg->DoVfactor = DoVfactor;
668  /*printf("curseg id =%d factor =%f\n",curSeg->id,curSeg->DoVfactor);*/
669  curSeg->lgfromstart = totLength;
670 
671  if (ext && ind) {
672  int *mrks = (int*)calloc(ind, sizeof(int));
673  tSegExt *segExt = (tSegExt*)calloc(1, sizeof(tSegExt));
674 
675  memcpy(mrks, mi, ind*sizeof(int));
676  segExt->nbMarks = ind;
677  segExt->marks = mrks;
678  curSeg->ext = segExt;
679  ind = 0;
680  }
681 
682 
683  switch (type) {
684  case TR_STR:
685  /* straight */
686  curSeg->type = TR_STR;
687  curSeg->length = curLength;
688 
689  newxr = xr + curLength * cos(alf); /* find end coordinates */
690  newyr = yr + curLength * sin(alf);
691  newxl = xl + curLength * cos(alf);
692  newyl = yl + curLength * sin(alf);
693 
694  curSeg->vertex[TR_SR].x = xr;
695  curSeg->vertex[TR_SR].y = yr;
696  curSeg->vertex[TR_SR].z = curzsr;
697 
698  curSeg->vertex[TR_SL].x = xl;
699  curSeg->vertex[TR_SL].y = yl;
700  curSeg->vertex[TR_SL].z = curzsl;
701 
702  curSeg->vertex[TR_ER].x = newxr;
703  curSeg->vertex[TR_ER].y = newyr;
704  curSeg->vertex[TR_ER].z = curzer;
705 
706  curSeg->vertex[TR_EL].x = newxl;
707  curSeg->vertex[TR_EL].y = newyl;
708  curSeg->vertex[TR_EL].z = curzel;
709 
710  curSeg->angle[TR_ZS] = alf;
711  curSeg->angle[TR_ZE] = alf;
712  curSeg->angle[TR_YR] = atan2(curSeg->vertex[TR_ER].z - curSeg->vertex[TR_SR].z, curLength);
713  curSeg->angle[TR_YL] = atan2(curSeg->vertex[TR_EL].z - curSeg->vertex[TR_SL].z, curLength);
714  curSeg->angle[TR_XS] = atan2(curSeg->vertex[TR_SL].z - curSeg->vertex[TR_SR].z, width);
715  curSeg->angle[TR_XE] = atan2(curSeg->vertex[TR_EL].z - curSeg->vertex[TR_ER].z, width);
716 
717  curSeg->Kzl = tan(curSeg->angle[TR_YR]);
718  curSeg->Kzw = (curSeg->angle[TR_XE] - curSeg->angle[TR_XS]) / curLength;
719  curSeg->Kyl = 0;
720 
721  curSeg->rgtSideNormal.x = -sin(alf);
722  curSeg->rgtSideNormal.y = cos(alf);
723 
724  TSTX(newxr); TSTX(newxl);
725  TSTY(newyr); TSTY(newyl);
726 
727  break;
728 
729  case TR_LFT:
730  /* left curve */
731  curSeg->type = TR_LFT;
732  curSeg->radius = radius;
733  curSeg->radiusr = radius + wi2;
734  curSeg->radiusl = radius - wi2;
735  curSeg->arc = curArc;
736  curSeg->length = curLength;
737 
738  innerradius = radius - wi2; /* left side aligned */
739  cenx = xl - innerradius * sin(alf); /* compute center location: */
740  ceny = yl + innerradius * cos(alf);
741  curSeg->center.x = cenx;
742  curSeg->center.y = ceny;
743 
744  curSeg->angle[TR_ZS] = alf;
745  curSeg->angle[TR_CS] = alf - PI / 2.0;
746  alf += curArc;
747  curSeg->angle[TR_ZE] = alf;
748 
749  newxl = cenx + innerradius * sin(alf); /* location of end */
750  newyl = ceny - innerradius * cos(alf);
751  newxr = cenx + (innerradius + width) * sin(alf); /* location of end */
752  newyr = ceny - (innerradius + width) * cos(alf);
753 
754  curSeg->vertex[TR_SR].x = xr;
755  curSeg->vertex[TR_SR].y = yr;
756  curSeg->vertex[TR_SR].z = curzsr;
757 
758  curSeg->vertex[TR_SL].x = xl;
759  curSeg->vertex[TR_SL].y = yl;
760  curSeg->vertex[TR_SL].z = curzsl;
761 
762  curSeg->vertex[TR_ER].x = newxr;
763  curSeg->vertex[TR_ER].y = newyr;
764  curSeg->vertex[TR_ER].z = curzer;
765 
766  curSeg->vertex[TR_EL].x = newxl;
767  curSeg->vertex[TR_EL].y = newyl;
768  curSeg->vertex[TR_EL].z = curzel;
769 
770  curSeg->angle[TR_YR] = atan2(curSeg->vertex[TR_ER].z - curSeg->vertex[TR_SR].z, curArc * (innerradius + width));
771  curSeg->angle[TR_YL] = atan2(curSeg->vertex[TR_EL].z - curSeg->vertex[TR_SL].z, curArc * innerradius);
772  curSeg->angle[TR_XS] = atan2(curSeg->vertex[TR_SL].z - curSeg->vertex[TR_SR].z, width);
773  curSeg->angle[TR_XE] = atan2(curSeg->vertex[TR_EL].z - curSeg->vertex[TR_ER].z, width);
774 
775  curSeg->Kzl = tan(curSeg->angle[TR_YR]) * (innerradius + width);
776  curSeg->Kzw = (curSeg->angle[TR_XE] - curSeg->angle[TR_XS]) / curArc;
777  curSeg->Kyl = 0;
778 
779  /* to find the boundary */
780  al = curArc / 36.0;
781  alfl = curSeg->angle[TR_CS];
782 
783  for (j = 0; j < 36; j++) {
784  alfl += al;
785  x1 = curSeg->center.x + (innerradius) * cos(alfl); /* location of end */
786  y1 = curSeg->center.y + (innerradius) * sin(alfl);
787  x2 = curSeg->center.x + (innerradius + width) * cos(alfl); /* location of end */
788  y2 = curSeg->center.y + (innerradius + width) * sin(alfl);
789  TSTX(x1); TSTX(x2);
790  TSTY(y1); TSTY(y2);
791  }
792 
793  break;
794 
795  case TR_RGT:
796  /* right curve */
797  curSeg->type = TR_RGT;
798  curSeg->radius = radius;
799  curSeg->radiusr = radius - wi2;
800  curSeg->radiusl = radius + wi2;
801  curSeg->arc = curArc;
802  curSeg->length = curLength;
803 
804  innerradius = radius - wi2; /* right side aligned */
805  cenx = xr + innerradius * sin(alf); /* compute center location */
806  ceny = yr - innerradius * cos(alf);
807  curSeg->center.x = cenx;
808  curSeg->center.y = ceny;
809 
810  curSeg->angle[TR_ZS] = alf;
811  curSeg->angle[TR_CS] = alf + PI / 2.0;
812  alf -= curSeg->arc;
813  curSeg->angle[TR_ZE] = alf;
814 
815  newxl = cenx - (innerradius + width) * sin(alf); /* location of end */
816  newyl = ceny + (innerradius + width) * cos(alf);
817  newxr = cenx - innerradius * sin(alf); /* location of end */
818  newyr = ceny + innerradius * cos(alf);
819 
820  curSeg->vertex[TR_SR].x = xr;
821  curSeg->vertex[TR_SR].y = yr;
822  curSeg->vertex[TR_SR].z = curzsr;
823 
824  curSeg->vertex[TR_SL].x = xl;
825  curSeg->vertex[TR_SL].y = yl;
826  curSeg->vertex[TR_SL].z = curzsl;
827 
828  curSeg->vertex[TR_ER].x = newxr;
829  curSeg->vertex[TR_ER].y = newyr;
830  curSeg->vertex[TR_ER].z = curzer;
831 
832  curSeg->vertex[TR_EL].x = newxl;
833  curSeg->vertex[TR_EL].y = newyl;
834  curSeg->vertex[TR_EL].z = curzel;
835 
836  curSeg->angle[TR_YR] = atan2(curSeg->vertex[TR_ER].z - curSeg->vertex[TR_SR].z, curArc * innerradius);
837  curSeg->angle[TR_YL] = atan2(curSeg->vertex[TR_EL].z - curSeg->vertex[TR_SL].z, curArc * (innerradius + width));
838  curSeg->angle[TR_XS] = atan2(curSeg->vertex[TR_SL].z - curSeg->vertex[TR_SR].z, width);
839  curSeg->angle[TR_XE] = atan2(curSeg->vertex[TR_EL].z - curSeg->vertex[TR_ER].z, width);
840 
841  curSeg->Kzl = tan(curSeg->angle[TR_YR]) * innerradius;
842  curSeg->Kzw = (curSeg->angle[TR_XE] - curSeg->angle[TR_XS]) / curArc;
843  curSeg->Kyl = 0;
844 
845  /* to find the boundaries */
846  al = curSeg->arc / 36.0;
847  alfl = curSeg->angle[TR_CS];
848 
849  for (j = 0; j < 36; j++) {
850  alfl -= al;
851  x1 = curSeg->center.x + (innerradius + width) * cos(alfl); /* location of end */
852  y1 = curSeg->center.y + (innerradius + width) * sin(alfl);
853  x2 = curSeg->center.x + innerradius * cos(alfl); /* location of end */
854  y2 = curSeg->center.y + innerradius * sin(alfl);
855  TSTX(x1); TSTX(x2);
856  TSTY(y1); TSTY(y2);
857  }
858  break;
859 
860  }
861 
862  addSides(curSeg, TrackHandle, theTrack, curStep, steps);
863 
864  totLength += curSeg->length;
865  xr = newxr;
866  yr = newyr;
867  xl = newxl;
868  yl = newyl;
869  curindex++;
870  curStep++;
871  if (type != TR_STR) {
872  /* printf("radius = %f arc = %f steps %d, length %f, stepslg %f\n", radius, RAD2DEG(curArc), steps, length, curLength); */
873  radius += dradius;
874  }
875  }
876 
877  } while (GfParmListSeekNext(TrackHandle, path) == 0);
878 
879  if (ext) {
880  GfHashRelease(segNameHash, NULL);
881  }
882 
883  /* printf("\n"); */
884 
885 
886  theTrack->seg = root;
887  theTrack->length = totLength;
888  theTrack->nseg = curindex;
889 }
890 
891 
892 
893 
894 /*
895  * Read version 4 track segments
896  */
897 void
898 ReadTrack4(tTrack *theTrack, void *TrackHandle, tRoadCam **camList, int ext)
899 {
900  int i;
901  tTrackSeg *curSeg = NULL, *mSeg;
902  tTrackSeg *curSeg2;
903  tTrackSeg *pitEntrySeg = NULL;
904  tTrackSeg *pitExitSeg = NULL;
905  tTrackSeg *pitStart = NULL;
906  tTrackSeg *pitEnd = NULL;
907  tTrackSeg *curPitSeg = NULL;
908  tTrackPitInfo *pits;
909  const char *segName;
910  int segId;
911  tRoadCam *curCam;
912  tTrkLocPos trkPos;
913  int found = 0;
914  const char *paramVal;
915  const int BUFSIZE = 256;
916  char path[BUFSIZE];
917  char path2[BUFSIZE];
918  int changeSeg;
919  tdble offset = 0;
920  tdble toStart;
921 
922  xmin = xmax = ymin = ymax = zmin = zmax = 0.0;
923 
925 
927 
928  /* PITS */
929  pits = &(theTrack->pits);
930  snprintf(path2, BUFSIZE, "%s/%s", TRK_SECT_MAIN, TRK_SECT_PITS);
931  segName = GfParmGetStr(TrackHandle, path2, TRK_ATT_ENTRY, NULL);
932 
933  if (segName != 0) {
934  snprintf(path, BUFSIZE, "%s/%s/%s", TRK_SECT_MAIN, TRK_LST_SEGMENTS, segName);
935  segId = (int)GfParmGetNum(TrackHandle, path, TRK_ATT_ID, (char*)NULL, -1);
936  pitEntrySeg = theTrack->seg;
937  found = 0;
938  for(i = 0; i < theTrack->nseg; i++) {
939  if (pitEntrySeg->id == segId) {
940  found = 1;
941  } else if (found) {
942  pitEntrySeg = pitEntrySeg->next;
943  break;
944  }
945  pitEntrySeg = pitEntrySeg->prev;
946  }
947  if (!found) {
948  pitEntrySeg = NULL;
949  }
950 
951  /* Pits Exit */
952  segName = GfParmGetStr(TrackHandle, path2, TRK_ATT_EXIT, NULL);
953  if (segName != 0) {
954  /* Search backward the last segment with that name */
955  pitExitSeg = theTrack->seg; /* last track segment */
956  found = 0;
957  for(i = 0; i < theTrack->nseg; i++) {
958  /* set the flag on the last segment of pit_exit */
959  if (!strcmp(segName, pitExitSeg->name)) {
960  found = 1;
961  break;
962  }
963  pitExitSeg = pitExitSeg->prev;
964  }
965  if (!found) {
966  pitExitSeg = NULL;
967  }
968  }
969 
970  /* Pits Start */
971  segName = GfParmGetStr(TrackHandle, path2, TRK_ATT_START, NULL);
972  if (segName != 0) {
973  pitStart = theTrack->seg;
974  found = 0;
975  for(i = 0; i < theTrack->nseg; i++) {
976  if (!strcmp(segName, pitStart->name)) {
977  found = 1;
978  } else if (found) {
979  pitStart = pitStart->next;
980  break;
981  }
982  pitStart = pitStart->prev;
983  }
984  if (!found) {
985  pitStart = NULL;
986  }
987  }
988 
989  /* Pits End */
990  segName = GfParmGetStr(TrackHandle, path2, TRK_ATT_END, NULL);
991  if (segName != 0) {
992  /* Search backward the last segment with that name */
993  pitEnd = theTrack->seg; /* last track segment */
994  found = 0;
995  for(i = 0; i < theTrack->nseg; i++) {
996  if (!strcmp(segName, pitEnd->name)) {
997  found = 1;
998  break;
999  }
1000  pitEnd = pitEnd->prev;
1001  }
1002  if (!found) {
1003  pitEnd = NULL;
1004  }
1005  }
1006  paramVal = GfParmGetStr(TrackHandle, path2, TRK_ATT_SIDE, "right");
1007  if (strcmp(paramVal, "right") == 0) {
1008  pits->side = TR_RGT;
1009  } else {
1010  pits->side = TR_LFT;
1011  }
1012  pits->speedLimit = GfParmGetNum(TrackHandle, path2, TRK_ATT_SPD_LIM, (char*)NULL, 25.0);
1013  if ((pitEntrySeg != NULL) && (pitExitSeg != NULL) && (pitStart != NULL) && (pitEnd != NULL)) {
1014  pits->pitEntry = pitEntrySeg;
1015  pits->pitExit = pitExitSeg;
1016  pits->pitStart = pitStart;
1017  pits->pitEnd = pitEnd;
1018  pitEntrySeg->raceInfo |= TR_PITENTRY;
1019  pitExitSeg->raceInfo |= TR_PITEXIT;
1020  pits->len = GfParmGetNum(TrackHandle, path2, TRK_ATT_LEN, (char*)NULL, 15.0);
1021  pits->width = GfParmGetNum(TrackHandle, path2, TRK_ATT_WIDTH, (char*)NULL, 5.0);
1022  found = 1;
1023  } else {
1024  found = 0;
1025  }
1026  }
1027 
1028  if (found) {
1029  pits->type = TR_PIT_ON_TRACK_SIDE;
1030  pits->nPitSeg = 0;
1031  if (pitStart->lgfromstart > pitEnd->lgfromstart) {
1032  pits->nMaxPits = (int)((theTrack->length - pitStart->lgfromstart +
1033  pitEnd->lgfromstart + pitEnd->length + pits->len / 2.0) / pits->len);
1034  } else {
1035  pits->nMaxPits = (int)((pitEnd->lgfromstart + pitEnd->length
1036  - pitStart->lgfromstart + pits->len / 2.0) / pits->len);
1037  }
1038  pits->driversPits = (tTrackOwnPit*)calloc(pits->nMaxPits, sizeof(tTrackOwnPit));
1039 
1040  mSeg = pitStart->prev;
1041  changeSeg = 1;
1042  toStart = 0;
1043  i = 0;
1044  while (i < pits->nMaxPits) {
1045  pits->driversPits[i].pos.type = TR_LPOS_MAIN;
1046  if (changeSeg) {
1047  changeSeg = 0;
1048  offset = 0;
1049  mSeg = mSeg->next;
1050  if (toStart >= mSeg->length) {
1051  toStart -= mSeg->length;
1052  changeSeg = 1;
1053  continue;
1054  }
1055  switch (pits->side) {
1056  case TR_RGT:
1057  curPitSeg = mSeg->rside;
1058  if (curPitSeg->rside) {
1059  offset = curPitSeg->width;
1060  curPitSeg = curPitSeg->rside;
1061  }
1062  break;
1063  case TR_LFT:
1064  curPitSeg = mSeg->lside;
1065  if (curPitSeg->lside) {
1066  offset = curPitSeg->width;
1067  curPitSeg = curPitSeg->lside;
1068  }
1069  break;
1070  }
1071  }
1072 
1073  pits->driversPits[i].pos.seg = mSeg;
1074  pits->driversPits[i].pos.toStart = toStart + pits->len / 2.0;
1075  switch (pits->side) {
1076  case TR_RGT:
1077  pits->driversPits[i].pos.toRight = -offset - RtTrackGetWidth(curPitSeg, toStart) + pits->width / 2.0;
1078  pits->driversPits[i].pos.toLeft = mSeg->width - pits->driversPits[i].pos.toRight;
1079  pits->driversPits[i].pos.toMiddle = mSeg->width / 2.0 - pits->driversPits[i].pos.toRight;
1080  break;
1081  case TR_LFT:
1082  pits->driversPits[i].pos.toLeft = -offset - RtTrackGetWidth(curPitSeg, toStart) + pits->width / 2.0;
1083  pits->driversPits[i].pos.toRight = mSeg->width - pits->driversPits[i].pos.toLeft;
1084  pits->driversPits[i].pos.toMiddle = mSeg->width / 2.0 - pits->driversPits[i].pos.toLeft;
1085  break;
1086  }
1087  toStart += pits->len;
1088  if (toStart >= mSeg->length) {
1089  toStart -= mSeg->length;
1090  changeSeg = 1;
1091  }
1092  i++;
1093  }
1094 
1095  for (mSeg = pitStart->prev; mSeg != pitEnd->next->next; mSeg = mSeg->next) {
1096  curSeg2 = NULL;
1097  switch(pits->side) {
1098  case TR_RGT:
1099  curSeg = mSeg->rside;
1100  curSeg2 = curSeg->rside;
1101  if ((mSeg != pitStart->prev) && (mSeg != pitEnd->next)) {
1102  mSeg->barrier[0]->style = TR_PITBUILDING;
1103  }
1104  break;
1105  case TR_LFT:
1106  curSeg = mSeg->lside;
1107  curSeg2 = curSeg->lside;
1108  if ((mSeg != pitStart->prev) && (mSeg != pitEnd->next)) {
1109  mSeg->barrier[1]->style = TR_PITBUILDING;
1110  }
1111  break;
1112  }
1113  if ((mSeg != pitStart->prev) && (mSeg != pitEnd->next)) {
1114  curSeg->raceInfo |= TR_PIT | TR_SPEEDLIMIT;
1115  if (curSeg2) {
1116  curSeg2->raceInfo |= TR_PIT | TR_SPEEDLIMIT;
1117  }
1118  } else if (mSeg == pitStart->prev) {
1119  curSeg->raceInfo |= TR_PITSTART;
1120  if (curSeg2) {
1121  curSeg2->raceInfo |= TR_PITSTART;
1122  }
1123  } else if (mSeg == pitEnd->next) {
1124  curSeg->raceInfo |= TR_PITEND;
1125  if (curSeg2) {
1126  curSeg2->raceInfo |= TR_PITEND;
1127  }
1128  }
1129  }
1130  }
1131 
1132  /*
1133  * camera definitions
1134  */
1136  do {
1137  curCam = (tRoadCam*)calloc(1, sizeof(tRoadCam));
1138  if (!curCam) {
1139  GfFatal("ReadTrack3: Memory allocation error");
1140  }
1141  if (*camList == NULL) {
1142  *camList = curCam;
1143  curCam->next = curCam;
1144  } else {
1145  curCam->next = (*camList)->next;
1146  (*camList)->next = curCam;
1147  *camList = curCam;
1148  }
1151  if (segName == 0) {
1152  GfFatal("Bad Track Definition: in Camera %s %s is missing\n", curCam->name, TRK_ATT_SEGMENT);
1153  }
1154  snprintf(path2, BUFSIZE, "%s/%s/%s", TRK_SECT_MAIN, TRK_LST_SEGMENTS, segName);
1155  segId = (int)GfParmGetNum(TrackHandle, path2, TRK_ATT_ID, (char*)NULL, 0);
1156  curSeg = theTrack->seg;
1157  for(i=0; i<theTrack->nseg; i++) {
1158  if (curSeg->id == segId) {
1159  break;
1160  }
1161  curSeg = curSeg->next;
1162  }
1163 
1164  trkPos.seg = curSeg;
1165  trkPos.toRight = GfParmGetCurNum(TrackHandle, TRK_SECT_CAM, TRK_ATT_TORIGHT, (char*)NULL, 0);
1166  trkPos.toStart = GfParmGetCurNum(TrackHandle, TRK_SECT_CAM, TRK_ATT_TOSTART, (char*)NULL, 0);
1167  TrackLocal2Global(&trkPos, &(curCam->pos.x), &(curCam->pos.y));
1168  curCam->pos.z = TrackHeightL(&trkPos) + GfParmGetCurNum(TrackHandle, TRK_SECT_CAM, TRK_ATT_HEIGHT, (char*)NULL, 0);
1169 
1171  if (segName == 0) {
1172  GfFatal("Bad Track Definition: in Camera %s %s is missing\n", curCam->name, TRK_ATT_CAM_FOV);
1173  }
1174  snprintf(path2, BUFSIZE, "%s/%s/%s", TRK_SECT_MAIN, TRK_LST_SEGMENTS, segName);
1175  segId = (int)GfParmGetNum(TrackHandle, path2, TRK_ATT_ID, (char*)NULL, 0);
1176  curSeg = theTrack->seg;
1177  for(i=0; i<theTrack->nseg; i++) {
1178  if (curSeg->id == segId) {
1179  break;
1180  }
1181  curSeg = curSeg->next;
1182  }
1184  if (segName == 0) {
1185  GfFatal("Bad Track Definition: in Camera %s %s is missing\n", curCam->name, TRK_ATT_CAM_FOVE);
1186  }
1187  snprintf(path2, BUFSIZE, "%s/%s/%s", TRK_SECT_MAIN, TRK_LST_SEGMENTS, segName);
1188  segId = (int)GfParmGetNum(TrackHandle, path2, TRK_ATT_ID, (char*)NULL, 0);
1189 
1190  do {
1191  curSeg->cam = curCam;
1192  curSeg = curSeg->next;
1193  } while (curSeg->id != segId);
1194  } while (GfParmListSeekNext(TrackHandle, TRK_SECT_CAM) == 0);
1195  }
1196 
1197  /* Update the coord to be positives */
1198  theTrack->min.x = 0;
1199  theTrack->min.y = 0;
1200  theTrack->min.z = 0;
1201  theTrack->max.x = xmax - xmin;
1202  theTrack->max.y = ymax - ymin;
1203  theTrack->max.z = zmax - zmin;
1204 
1205  curSeg = theTrack->seg;
1206  for(i=0; i<theTrack->nseg; i++) { /* read the segment data: */
1207  if ((curSeg->lgfromstart + curSeg->length) > (theTrack->length - 50.0)) {
1208  curSeg->raceInfo |= TR_LAST;
1209  } else if (curSeg->lgfromstart < 50.0) {
1210  curSeg->raceInfo |= TR_START;
1211  } else {
1212  curSeg->raceInfo |= TR_NORMAL;
1213  }
1214  normSeg(curSeg);
1215  if (curSeg->lside) {
1216  normSeg(curSeg->lside);
1217  if (curSeg->lside->lside) {
1218  normSeg(curSeg->lside->lside);
1219  }
1220  }
1221  if (curSeg->rside) {
1222  normSeg(curSeg->rside);
1223  if (curSeg->rside->rside) {
1224  normSeg(curSeg->rside->rside);
1225  }
1226  }
1227  curSeg = curSeg->next;
1228  }
1229 
1230 
1231  if (*camList != NULL) {
1232  curCam = *camList;
1233  do {
1234  curCam = curCam->next;
1235  curCam->pos.x -= xmin;
1236  curCam->pos.y -= ymin;
1237  curCam->pos.z -= zmin;
1238  } while (curCam != *camList);
1239  }
1240 }
1241 
1242 
1250 static void updateMinMaxForTurn(const tTrackSeg* const curBorder, const tdble radius, const tdble sign, const tdble z)
1251 {
1252  tdble al, alfl, x, y;
1253  int j;
1254 
1255  // to find the boundary (global min/max, approximation)
1256  al = curBorder->arc / 36.0 * sign;
1257  alfl = curBorder->angle[TR_CS];
1258 
1259  for (j = 0; j < 36; j++) {
1260  alfl += al;
1261  x = curBorder->center.x + radius * cos(alfl); // location of end
1262  y = curBorder->center.y + radius * sin(alfl);
1263  TSTX(x);
1264  TSTY(y);
1265  }
1266  TSTZ(z);
1267 }
1268 
1269 
1276 static void initAnglesAndGradients(tTrackSeg* const curBorder, const tdble startwidth, const tdble endwidth) {
1277  curBorder->angle[TR_YR] = atan2(curBorder->vertex[TR_ER].z - curBorder->vertex[TR_SR].z,
1278  curBorder->arc * curBorder->radiusr);
1279  curBorder->angle[TR_YL] = atan2(curBorder->vertex[TR_EL].z - curBorder->vertex[TR_SL].z,
1280  curBorder->arc * curBorder->radiusl);
1281 
1282  curBorder->Kzl = tan(curBorder->angle[TR_YR]) * curBorder->radiusr;
1283  curBorder->Kzw = (curBorder->angle[TR_XE] - curBorder->angle[TR_XS]) / curBorder->arc;
1284  curBorder->Kyl = (endwidth - startwidth) / curBorder->arc;
1285 }
1286 
1287 
1301 static void initSideForTurn(
1302  const int turntype,
1303  tTrackSeg* const curBorder,
1304  const tTrackSeg* const curSeg,
1305  const int side,
1306  const int bankingtype,
1307  const tdble startwidth,
1308  const tdble endwidth,
1309  const tdble maxwidth
1310 )
1311 {
1312  tdble sign, z;
1313 
1314  if (turntype == TR_LFT) {
1315  sign = 1.0f;
1316  } else {
1317  sign = -1.0f;
1318  }
1319 
1320  curBorder->center.x = curSeg->center.x;
1321  curBorder->center.y = curSeg->center.y;
1322 
1323  // Combining code for case 0 (TRK_SECT_RSIDE) and 1 (TRK_SECT_LSIDE)?
1324  // Tried it, but the setup code is then as long as the copy and less readable because of the additional 8 variables
1325  switch(side) {
1326  case 1:
1327  curBorder->radius = curSeg->radiusl - sign * startwidth / 2.0;
1328  curBorder->radiusr = curSeg->radiusl;
1329  curBorder->radiusl = curSeg->radiusl - sign * maxwidth;
1330  curBorder->arc = curSeg->arc;
1331  curBorder->length = curBorder->radius * curBorder->arc;
1332 
1333  curBorder->vertex[TR_SL].x = curBorder->vertex[TR_SR].x - sign * startwidth * cos(curBorder->angle[TR_CS]);
1334  curBorder->vertex[TR_SL].y = curBorder->vertex[TR_SR].y - sign * startwidth * sin(curBorder->angle[TR_CS]);
1335  curBorder->vertex[TR_SL].z = curBorder->vertex[TR_SR].z + (tdble)bankingtype * startwidth * tan(curSeg->angle[TR_XS]);
1336  curBorder->vertex[TR_EL].x = curBorder->vertex[TR_ER].x - sign * endwidth * cos(curBorder->angle[TR_CS] + sign * curBorder->arc);
1337  curBorder->vertex[TR_EL].y = curBorder->vertex[TR_ER].y - sign * endwidth * sin(curBorder->angle[TR_CS] + sign * curBorder->arc);
1338  z = curBorder->vertex[TR_EL].z = curBorder->vertex[TR_ER].z + (tdble)bankingtype * endwidth * tan(curSeg->angle[TR_XE]);
1339 
1340  initAnglesAndGradients(curBorder, startwidth, endwidth);
1341  updateMinMaxForTurn(curBorder, curBorder->radiusl, sign, z);
1342  break;
1343 
1344  case 0:
1345  curBorder->radius = curSeg->radiusr + sign * startwidth / 2.0;
1346  curBorder->radiusl = curSeg->radiusr;
1347  curBorder->radiusr = curSeg->radiusr + sign * maxwidth;
1348  curBorder->arc = curSeg->arc;
1349  curBorder->length = curBorder->radius * curBorder->arc;
1350 
1351  curBorder->vertex[TR_SR].x = curBorder->vertex[TR_SL].x + sign * startwidth * cos(curBorder->angle[TR_CS]);
1352  curBorder->vertex[TR_SR].y = curBorder->vertex[TR_SL].y + sign * startwidth * sin(curBorder->angle[TR_CS]);
1353  curBorder->vertex[TR_SR].z = curBorder->vertex[TR_SL].z - (tdble)bankingtype * startwidth * tan(curSeg->angle[TR_XS]);
1354  curBorder->vertex[TR_ER].x = curBorder->vertex[TR_EL].x + sign * endwidth * cos(curBorder->angle[TR_CS] + sign * curBorder->arc);
1355  curBorder->vertex[TR_ER].y = curBorder->vertex[TR_EL].y + sign * endwidth * sin(curBorder->angle[TR_CS] + sign * curBorder->arc);
1356  z = curBorder->vertex[TR_ER].z = curBorder->vertex[TR_EL].z - (tdble)bankingtype * endwidth * tan(curSeg->angle[TR_XE]);
1357 
1358  initAnglesAndGradients(curBorder, startwidth, endwidth);
1359  updateMinMaxForTurn(curBorder, curBorder->radiusr, sign, z);
1360  break;
1361  }
1362 }
1363 
1364 
1377  tTrackSeg* const curBorder,
1378  const tTrackSeg* const curSeg,
1379  const int side,
1380  const int bankingtype,
1381  const tdble startwidth,
1382  const tdble endwidth
1383 )
1384 {
1385  tdble z, x, y;
1386  x = y = z = 0.0f;
1387 
1388  switch(side) {
1389  case 1:
1390  curBorder->vertex[TR_SL].x = curBorder->vertex[TR_SR].x + startwidth * curSeg->rgtSideNormal.x;
1391  curBorder->vertex[TR_SL].y = curBorder->vertex[TR_SR].y + startwidth * curSeg->rgtSideNormal.y;
1392  curBorder->vertex[TR_SL].z = curBorder->vertex[TR_SR].z + (tdble) bankingtype * startwidth * tan(curSeg->angle[TR_XS]);
1393  x = curBorder->vertex[TR_EL].x = curBorder->vertex[TR_ER].x + endwidth * curSeg->rgtSideNormal.x;
1394  y = curBorder->vertex[TR_EL].y = curBorder->vertex[TR_ER].y + endwidth * curSeg->rgtSideNormal.y;
1395  z = curBorder->vertex[TR_EL].z = curBorder->vertex[TR_ER].z + (tdble) bankingtype * endwidth * tan(curSeg->angle[TR_XE]);
1396  break;
1397  case 0:
1398  curBorder->vertex[TR_SR].x = curBorder->vertex[TR_SL].x - startwidth * curSeg->rgtSideNormal.x;
1399  curBorder->vertex[TR_SR].y = curBorder->vertex[TR_SL].y - startwidth * curSeg->rgtSideNormal.y;
1400  curBorder->vertex[TR_SR].z = curBorder->vertex[TR_SL].z - (tdble) bankingtype * startwidth * tan(curSeg->angle[TR_XS]);
1401  x = curBorder->vertex[TR_ER].x = curBorder->vertex[TR_EL].x - endwidth * curSeg->rgtSideNormal.x;
1402  y = curBorder->vertex[TR_ER].y = curBorder->vertex[TR_EL].y - endwidth * curSeg->rgtSideNormal.y;
1403  z = curBorder->vertex[TR_ER].z = curBorder->vertex[TR_EL].z - (tdble) bankingtype * endwidth * tan(curSeg->angle[TR_XE]);
1404  break;
1405  }
1406 
1407  curBorder->angle[TR_YR] = atan2(curBorder->vertex[TR_ER].z - curBorder->vertex[TR_SR].z, curBorder->length);
1408  curBorder->angle[TR_YL] = atan2(curBorder->vertex[TR_EL].z - curBorder->vertex[TR_SL].z, curBorder->length);
1409 
1410  curBorder->Kzl = tan(curBorder->angle[TR_YR]);
1411  curBorder->Kzw = (curBorder->angle[TR_XE] - curBorder->angle[TR_XS]) / curBorder->length;
1412  curBorder->Kyl = (endwidth - startwidth) / curBorder->length;
1413 
1414  curBorder->rgtSideNormal.x = curSeg->rgtSideNormal.x;
1415  curBorder->rgtSideNormal.y = curSeg->rgtSideNormal.y;
1416 
1417  TSTX(x);
1418  TSTY(y);
1419  TSTZ(z);
1420 }
1421 
1422 
1439  tTrackSeg* const curSeg,
1440  const int side,
1441  const int lefttype,
1442  const int righttype,
1443  const int bankingtype,
1444  const tdble startwidth,
1445  const tdble endwidth,
1446  tTrackSurface* surface,
1447  const tdble borderheight,
1448  const int borderstyle
1449 )
1450 {
1451  tTrackSeg* curBorder = (tTrackSeg*)calloc(1, sizeof(tTrackSeg));
1452  if (side == 1) {
1453  curSeg->lside = curBorder;
1454  curBorder->vertex[TR_SR] = curSeg->vertex[TR_SL];
1455  curBorder->vertex[TR_ER] = curSeg->vertex[TR_EL];
1456  curBorder->type2 = lefttype;
1457  } else {
1458  curSeg->rside = curBorder;
1459  curBorder->vertex[TR_SL] = curSeg->vertex[TR_SR];
1460  curBorder->vertex[TR_EL] = curSeg->vertex[TR_ER];
1461  curBorder->type2 = righttype;
1462  }
1463 
1464  curBorder->startWidth = startwidth;
1465  curBorder->endWidth = endwidth;
1466  curBorder->width = MIN(startwidth, endwidth);
1467  tdble maxWidth = MAX(startwidth, endwidth);
1468 
1469  curBorder->type = curSeg->type;
1470  curBorder->surface = surface;
1471  curBorder->height = borderheight;
1472  curBorder->style = borderstyle;
1473  curBorder->envIndex = envIndex; // TODO: Global?
1474  curBorder->DoVfactor = DoVfactor; // TODO: Global?
1475  curBorder->angle[TR_XS] = curSeg->angle[TR_XS] * (tdble) bankingtype;
1476  curBorder->angle[TR_XE] = curSeg->angle[TR_XE] * (tdble) bankingtype;
1477  curBorder->angle[TR_ZS] = curSeg->angle[TR_ZS];
1478  curBorder->angle[TR_ZE] = curSeg->angle[TR_ZE];
1479  curBorder->angle[TR_CS] = curSeg->angle[TR_CS];
1480 
1481  switch(curSeg->type) {
1482  case TR_STR:
1483  curBorder->length = curSeg->length;
1484  initSideForStraight(curBorder, curSeg, side, bankingtype, startwidth, endwidth);
1485  break;
1486  case TR_LFT:
1487  initSideForTurn(TR_LFT, curBorder, curSeg, side, bankingtype, startwidth, endwidth, maxWidth);
1488  break;
1489  case TR_RGT:
1490  initSideForTurn(TR_RGT, curBorder, curSeg, side, bankingtype, startwidth, endwidth, maxWidth);
1491  break;
1492  }
1493 
1494  return curBorder;
1495 }
int nMaxPits
number max of pits
Definition: track.h:462
#define GF_HASH_TYPE_STR
String key based hash table.
Definition: tgf.h:606
static int sideBankType[2]
Definition: track4.cpp:64
tdble kRoughness
Roughtness in m of the surface (wave height)
Definition: track.h:250
#define TRK_ATT_LG
Definition: track.h:147
tdble angle[7]
Definition: track.h:337
#define TR_PITBUILDING
Pit building wall (barrier only)
Definition: track.h:313
tdble Kyl
Definition: track.h:359
#define TR_SR
Start-Right corner.
Definition: track.h:333
#define TRK_ATT_RADIUSEND
Definition: track.h:149
tTrackSeg * pitEnd
Pit lane segment.
Definition: track.h:473
#define TRK_ATT_RADIUS
Definition: track.h:148
static void GfFatal(const char *fmt,...)
Definition: tgf.h:339
tTrackOwnPit * driversPits
List of pits by driver.
Definition: track.h:475
tdble DoVfactor
Definition: track.h:387
int type
Geometrical type:
Definition: track.h:280
t3Dd center
Center of the curve.
Definition: track.h:324
#define TRK_ATT_TOSTART
Definition: track.h:207
int * marks
marks array
Definition: track.h:237
#define TRK_SECT_CAM
Definition: track.h:203
#define TR_PIT
Car pit.
Definition: track.h:383
#define TR_ER
End_Right corner.
Definition: track.h:335
#define TRK_ATT_TYPE
Definition: track.h:138
tdble toRight
Distance (+ to left, - to right) relative to the right side of segment.
Definition: track.h:432
#define TRK_VAL_WALL
Definition: track.h:198
#define TR_SPEEDLIMIT
Segment where the speed is limited.
Definition: track.h:380
#define TR_LSIDE
Left side segment (outer segment)
Definition: track.h:297
#define TRK_VAL_PLAN
Definition: track.h:197
int GfParmListSeekNext(void *handle, const char *path)
Go the the next subsection element in the parameter set handle.
Definition: params.cpp:2184
#define TSTY(y)
Definition: track4.cpp:43
#define TR_ZS
Rotation angles of the track in rad anti-clockwise: Index in:
Definition: track.h:347
#define TR_STR
Straight.
Definition: track.h:287
tdble width
Width of the segment (if constant width)
Definition: track.h:316
#define TRK_ATT_SIDE
Definition: track.h:180
struct trackSurface * next
Next surface in list.
Definition: track.h:243
static tTrack * theTrack
Definition: track.cpp:32
Location on the track in local coordinates.
Definition: track.h:418
#define TRK_ATT_ENTRY
Definition: track.h:176
#define TRK_ATT_SPD_LIM
Definition: track.h:182
#define TRK_ATT_ROUGHTWL
Definition: track.h:112
static const char * SectSide[2]
Definition: track4.cpp:56
#define TRK_ATT_PROFTGTS
Definition: track.h:164
int side
Pits side:
Definition: track.h:464
#define TR_PIT_ON_TRACK_SIDE
The pits are on the track side.
Definition: track.h:460
static tdble barrierHeight[2]
Definition: track4.cpp:78
#define TRK_ATT_SWIDTH
Definition: track.h:191
unsigned int raceInfo
Type of segment regarding the race: Mask value in:
Definition: track.h:365
void TrackLocal2Global(tTrkLocPos *p, tdble *X, tdble *Y)
Definition: trackutil.cpp:29
#define TR_NORMAL
Normal segment.
Definition: track.h:376
#define TR_SL
Start-Left corner.
Definition: track.h:332
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:2435
Robots Tools.
#define TRK_ATT_PROFSTEPSLEN
Definition: track.h:163
Track structure.
Definition: track.h:502
t3Dd rgtSideNormal
Definition: track.h:360
#define TRK_ATT_ROUGHT
Definition: track.h:111
#define TRK_ATT_FRICTION
Definition: track.h:109
static tTrackSurface * getTrackSurface(void *trackHandle, tTrack *theTrack, const char *material)
Gets surface properties based on the material.
Definition: track4.cpp:130
#define TR_CS
Center start angle.
Definition: track.h:353
static tdble borderWidth[2]
Definition: track4.cpp:71
tdble Kzw
Definition: track.h:357
#define TRK_ATT_ID
Definition: track.h:160
void GfHashRelease(void *hash, tfHashFree hashFree)
Release a hash table.
Definition: hash.cpp:353
vec2f normal
Definition: track.h:264
#define TRK_VAL_LFT
Definition: track.h:144
static void normSeg(tTrackSeg *curSeg)
Segment coordinate normalization, track is moved to the origin of the coordinate system.
Definition: track4.cpp:371
#define TRK_SECT_LBARRIER
Definition: track.h:188
static const char * SectBorder[2]
Definition: track4.cpp:57
static tTrackSurface * sideSurface[2]
Definition: track4.cpp:66
tdble lgfromstart
Length of beginning of segment from starting line.
Definition: track.h:319
const double PI
PI.
Definition: tgf.h:69
tdble endWidth
Width of the end of the segment.
Definition: track.h:318
#define MAX_TMP_INTS
#define TRK_VAL_BARRIER
Definition: track.h:217
#define TR_YL
Y Left angle.
Definition: track.h:349
static tdble ymax
Definition: track4.cpp:36
#define TR_SIDE_LFT
Definition: track.h:403
tdble length
Length in meters of the middle of the track.
Definition: track.h:315
tdble startWidth
Width of the beginning of the segment.
Definition: track.h:317
#define TRK_ATT_ENVIND
Definition: track.h:630
#define TRK_ATT_STYLE
Definition: track.h:193
const void * GfHashGetStr(void *hash, const char *key)
Get the user data associated with a string key.
Definition: hash.cpp:245
#define TRK_VAL_RGT
Definition: track.h:145
#define TRK_VAL_FENCE
Definition: track.h:200
int nPitSeg
actual number of pits
Definition: track.h:463
tdble kRebound
Coefficient of energy restitution.
Definition: track.h:248
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:2311
#define TRK_ATT_PROFTGTEL
Definition: track.h:167
tTrackSeg * pitEntry
Pit lane segment.
Definition: track.h:471
#define TR_PITENTRY
Segment where the pit lane cross the main track.
Definition: track.h:381
#define TR_FENCE
Fence (no width) (barrier only)
Definition: track.h:312
#define TRK_SECT_RBARRIER
Definition: track.h:189
char * GfParmListGetCurEltName(void *handle, const char *path)
Get current subsection name of the parameter set handle during subsection iteration.
Definition: params.cpp:2268
tdble toMiddle
Distance (+ to left, - to right) relative to the middle of segment.
Definition: track.h:433
char * name
Definition: track.h:228
int envIndex
Definition: track.h:361
static void addSides(tTrackSeg *curSeg, void *trackHandle, tTrack *theTrack, int curStep, int steps)
Adds the specified side/border/barrier segments to given main track segement.
Definition: track4.cpp:235
static const char * barrierMaterial[2]
Definition: track4.cpp:80
tdble length
main track length
Definition: track.h:512
tdble speedLimit
Speed limit between pitStart and pitEnd.
Definition: track.h:470
int type
Type of description:
Definition: track.h:421
#define TRK_ATT_ARC
Definition: track.h:150
tTrkLocPos pos
Center of the pit position.
Definition: track.h:442
#define TR_RBORDER
Right border segment (inner segment)
Definition: track.h:300
int GfParmListSeekFirst(void *handle, const char *path)
Go the the first subsection element in the parameter set handle.
Definition: params.cpp:2148
const char * material
Type of material used.
Definition: track.h:245
#define TRK_ATT_DAMMAGE
Definition: track.h:113
#define TRK_ATT_PROFTGTSL
Definition: track.h:166
#define TR_LPOS_MAIN
Relative to the main segment, mostly used for racing on the main track.
Definition: track.h:427
t3Dd max
Definition: track.h:519
#define TRK_ATT_CAM_FOVE
Definition: track.h:210
tTrackBarrier * barrier[2]
Segment barriers.
Definition: track.h:395
tTrackSurface * surface
Barrier surface.
Definition: track.h:263
const char * name
Segment name.
Definition: track.h:277
#define TRK_SECT_LSIDE
Definition: track.h:184
#define TRK_ATT_PROFTGTER
Definition: track.h:169
#define TR_LAST
Segment before start line.
Definition: track.h:377
#define TRK_ATT_START
Definition: track.h:178
#define TRK_SECT_RSIDE
Definition: track.h:185
#define TRK_ATT_MARKS
Definition: track.h:170
void * GfHashCreate(int type)
Create a new hash table.
Definition: hash.cpp:98
tdble toLeft
Distance (- to left, + to right) relative to left side of segment.
Definition: track.h:434
road camera
Definition: track.h:226
#define TR_LFT
Left curve.
Definition: track.h:286
#define TRK_VAL_STR
Definition: track.h:143
#define TR_PITEXIT
Segment where the pit lane cross the main track.
Definition: track.h:382
#define TRK_ATT_PROFSTEPS
Definition: track.h:162
Scalar length(const Quaternion &q)
Definition: Quaternion.h:193
#define TR_RSIDE
Right side segment (outer segment)
Definition: track.h:298
static tdble xmax
Definition: track4.cpp:36
tdble radiusr
Radius in meters of the right side of the track (>0)
Definition: track.h:321
Driver&#39;s pit.
Definition: track.h:440
#define TRK_ATT_END
Definition: track.h:179
float tdble
Floating point type used in TORCS.
Definition: tgf.h:48
#define TRK_ATT_SEGMENT
Definition: track.h:205
tdble TrackHeightL(tTrkLocPos *p)
Definition: trackutil.cpp:55
tdble radiusl
Radius in meters of the left side of the track (>0)
Definition: track.h:322
int nseg
Number of segments.
Definition: track.h:510
Definition: Endpoint.h:36
#define TR_CURB
Curb (border only)
Definition: track.h:310
#define TR_YR
Y Right angle.
Definition: track.h:350
static void * TrackHandle
Definition: track.cpp:34
struct trackSeg * side[2]
Definition: track.h:407
Barrier.
Definition: track.h:259
The Gaming Framework API.
static tTrackSurface * borderSurface[2]
Definition: track4.cpp:75
#define TRK_SECT_SURFACES
Definition: track.h:106
#define TRK_LST_SEGMENTS
Definition: track.h:137
#define TR_PITEND
Car pit End.
Definition: track.h:385
static tdble zmax
Definition: track4.cpp:36
#define TRK_ATT_DOVFACTOR
Definition: track.h:172
#define TRK_ATT_PROFTGTSR
Definition: track.h:168
#define TRK_VAL_LEVEL
Definition: track.h:223
tdble arc
Arc in rad of the curve (>0)
Definition: track.h:323
#define TR_ZE
Z End angle.
Definition: track.h:348
#define TR_LBORDER
Left border segment (inner segment)
Definition: track.h:299
Surface.
Definition: track.h:242
tTrackSeg * pitExit
Pit lane segment.
Definition: track.h:474
tdble height
Barrier height.
Definition: track.h:262
int style
Barrier style.
Definition: track.h:260
#define TR_XS
X Start angle.
Definition: track.h:351
static tdble ymin
Definition: track4.cpp:36
tdble radius
Radius in meters of the middle of the track (>0)
Definition: track.h:320
#define TRK_VAL_CURB
Definition: track.h:199
tdble y
y coordinate
Definition: tgf.h:117
static tdble borderHeight[2]
Definition: track4.cpp:72
tdble z
z coordinate
Definition: tgf.h:118
t3Dd vertex[4]
Coordinates of the 4 corners of the segment.
Definition: track.h:325
int type2
Position type:
Definition: track.h:289
#define TRK_ATT_ZE
Definition: track.h:152
void normalize(void)
Definition: v2_t.h:247
tdble kRollRes
Rolling resistance.
Definition: track.h:249
#define TRK_ATT_BANKTYPE
Definition: track.h:195
static const char * sideMaterial[2]
Definition: track4.cpp:65
static tdble sideEndWidth[2]
Definition: track4.cpp:62
tdble TrackSpline(tdble p0, tdble p1, tdble t0, tdble t1, tdble t)
Definition: trackutil.cpp:79
static tdble sideStartWidth[2]
Definition: track4.cpp:63
tdble height
Max height for curbs.
Definition: track.h:363
#define TRK_ATT_ZSR
Definition: track.h:154
tTrackSeg * seg
Track segment.
Definition: track.h:420
#define TRK_VAL_ASPHALT
Definition: track.h:212
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:2392
tdble width
Width of each pit stop.
Definition: track.h:469
tdble RtTrackGetWidth(tTrackSeg *seg, tdble toStart)
Get the track width at the specified point.
Definition: rttrack.cpp:58
#define TR_EL
End-Left corner.
Definition: track.h:334
struct trackSeg * lside
Definition: track.h:406
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:2679
static const char * SectBarrier[2]
Definition: track4.cpp:58
Track segment (tTrackSeg) The segments can be straights (type TR_STR): (the track goes from the right...
Definition: track.h:276
static int envIndex
Definition: track4.cpp:68
#define TRK_ATT_ZER
Definition: track.h:156
static Vector y[4]
Definition: Convex.cpp:56
static tTrackSurface * barrierSurface[2]
Definition: track4.cpp:81
tSegExt * ext
Definition: track.h:392
Pits Info Structure.
Definition: track.h:453
t3Dd min
Definition: track.h:518
#define TR_START
Segment after start line.
Definition: track.h:378
static void initSideForStraight(tTrackSeg *const curBorder, const tTrackSeg *const curSeg, const int side, const int bankingtype, const tdble startwidth, const tdble endwidth)
Set up side and border track segments for straight segments.
Definition: track4.cpp:1376
#define TRK_ATT_LEN
Definition: track.h:181
int GfHashAddStr(void *hash, const char *key, const void *data)
Add an element with a string key to a hash table.
Definition: hash.cpp:170
#define TR_RGT
Right curve.
Definition: track.h:285
#define TRK_ATT_EWIDTH
Definition: track.h:192
tdble len
Lenght of each pit stop.
Definition: track.h:468
#define TR_XE
X End angle.
Definition: track.h:352
tdble toStart
Distance to start of segment (or arc if turn)
Definition: track.h:431
static void updateMinMaxForTurn(const tTrackSeg *const curBorder, const tdble radius, const tdble sign, const tdble z)
Update global min/max values for turns (discretized approximation).
Definition: track4.cpp:1250
struct trackSeg * prev
Previous segment.
Definition: track.h:398
#define TRK_ATT_ZS
Definition: track.h:151
tTrackSurface * surface
Segment surface.
Definition: track.h:394
tdble kDammage
Dammages in case of collision.
Definition: track.h:252
tTrackSeg * pitStart
Pit lane segment.
Definition: track.h:472
#define TRK_ATT_HEIGHT
Definition: track.h:208
struct trackSeg * next
Next segment.
Definition: track.h:397
#define TRK_SECT_RBORDER
Definition: track.h:187
static const char * ValStyle[]
Definition: track4.cpp:60
#define TRK_ATT_WIDTH
Definition: track.h:45
void ReadTrack4(tTrack *theTrack, void *TrackHandle, tRoadCam **camList, int ext)
Definition: track4.cpp:898
static tdble zmin
Definition: track4.cpp:36
#define TRK_ATT_TORIGHT
Definition: track.h:206
#define TR_MAIN
Main track segment (ie road part)
Definition: track.h:296
#define TRK_VAL_GRASS
Definition: track.h:214
static void readDefaultSideParameters(void *trackHandle, tTrack *theTrack)
Reads default side/border track segment parameters.
Definition: track4.cpp:172
Definition: Endpoint.h:36
tTrackSurface * surfaces
Segment surface list.
Definition: track.h:516
struct RoadCam * next
Definition: track.h:230
static tdble GlobalStepLen
Definition: track4.cpp:83
t3Dd pos
Definition: track.h:229
#define TRK_ATT_ZEL
Definition: track.h:155
static void initSideForTurn(const int turntype, tTrackSeg *const curBorder, const tTrackSeg *const curSeg, const int side, const int bankingtype, const tdble startwidth, const tdble endwidth, const tdble maxwidth)
Set up side and border track segments for turns.
Definition: track4.cpp:1301
static const char * borderMaterial[2]
Definition: track4.cpp:74
#define TRK_ATT_BKE
Definition: track.h:159
static tdble DoVfactor
Definition: track4.cpp:69
#define TRK_ATT_REBOUND
Definition: track.h:114
struct trackSeg * rside
Definition: track.h:406
static tdble barrierWidth[2]
Definition: track4.cpp:77
#define TRK_VAL_SPLINE
Definition: track.h:220
static void initAnglesAndGradients(tTrackSeg *const curBorder, const tdble startwidth, const tdble endwidth)
Set up border segment angles and gradients.
Definition: track4.cpp:1276
static int borderStyle[2]
Definition: track4.cpp:73
#define TRK_SECT_PITS
Definition: track.h:174
#define TRK_ATT_SURF
Definition: track.h:46
static void CreateSegRing(void *TrackHandle, tTrack *theTrack, int ext)
Definition: track4.cpp:390
int style
Border and barrier segments style:
Definition: track.h:302
#define TRK_ATT_BKS
Definition: track.h:158
Track Structure and Track Loader Module Definition.
const char * GfParmGetCurStr(void *handle, const char *path, const char *key, const char *deflt)
Get a string parameter from the parameter set handle based on subsection iteration.
Definition: params.cpp:2354
Extended track segment.
Definition: track.h:234
static int barrierStyle[2]
Definition: track4.cpp:79
#define TSTZ(z)
Definition: track4.cpp:48
tRoadCam * cam
Definition: track.h:396
static tdble xmin
Definition: track4.cpp:36
#define TR_PLAN
Flat (border only)
Definition: track.h:309
#define TRK_SECT_LBORDER
Definition: track.h:186
tTrackSeg * seg
Main track.
Definition: track.h:515
#define TRK_ATT_EXIT
Definition: track.h:177
#define TRK_ATT_ROLLRES
Definition: track.h:110
#define TRK_ATT_GRADE
Definition: track.h:157
tTrackPitInfo pits
Pits information.
Definition: track.h:514
tdble kFriction
Coefficient of friction.
Definition: track.h:247
tdble Kzl
Definition: track.h:356
tdble kRoughWaveLen
Wave length in m of the surface.
Definition: track.h:251
tdble x
x coordinate
Definition: tgf.h:116
#define TRK_SECT_MAIN
Definition: track.h:136
#define TRK_ATT_PROFTGTE
Definition: track.h:165
int nbMarks
turn marks
Definition: track.h:236
int id
Segment number.
Definition: track.h:278
#define TRK_ATT_ZSL
Definition: track.h:153
#define TR_PITSTART
Car pit Star.
Definition: track.h:384
const T sign(const T &x)
Definition: MathFunctions.h:30
int type
Type of Pit:
Definition: track.h:455
#define TRK_ATT_PROFIL
Definition: track.h:161
#define TRK_ATT_CAM_FOV
Definition: track.h:209
static tTrackSeg * commonSideInit(tTrackSeg *const curSeg, const int side, const int lefttype, const int righttype, const int bankingtype, const tdble startwidth, const tdble endwidth, tTrackSurface *surface, const tdble borderheight, const int borderstyle)
Common side/border allocation and initialization for straights and turns.
Definition: track4.cpp:1438
#define TSTX(x)
Definition: track4.cpp:38
tdble width
Barrier width.
Definition: track.h:261
#define TR_WALL
Wall (barrier only)
Definition: track.h:311