TORCS  1.3.9
The Open Racing Car Simulator
grsmoke.cpp
Go to the documentation of this file.
1 /***************************************************************************
2 
3  file : grsmoke.cpp
4  created : Fri Mar 22 23:17:54 CET 2002
5  copyright : (C) 2001-2014 by Christophe Guionneau, Bernhard Wymann
6  version : $Id$
7 
8 ***************************************************************************/
9 
10 /***************************************************************************
11  * *
12  * This program is free software; you can redistribute it and/or modify *
13  * it under the terms of the GNU General Public License as published by *
14  * the Free Software Foundation; either version 2 of the License, or *
15  * (at your option) any later version. *
16  * *
17  ***************************************************************************/
18 
19 #include <math.h>
20 #include <stdlib.h>
21 #include <sys/types.h>
22 #include <stdio.h>
23 #include <ctype.h>
24 #ifdef WIN32
25 #include <windows.h>
26 #endif
27 #include <GL/glut.h>
28 #include <plib/ssg.h>
29 
30 #include <tgfclient.h>
31 #include <track.h>
32 #include <car.h>
33 #include <graphic.h>
34 #include <robottools.h>
35 #include <portability.h>
36 
37 #include "grmain.h"
38 #include "grshadow.h"
39 #include "grskidmarks.h"
40 #include "grsmoke.h"
41 #include "grcar.h"
42 #include "grcam.h"
43 #include "grscene.h"
44 #include "grboard.h"
45 #include "grssgext.h"
46 #include "grutil.h"
47 
48 #ifdef DMALLOC
49 #include "dmalloc.h"
50 #endif
51 
54 double grFireDeltaT;
55 double grSmokeLife;
56 
57 
60 ssgSimpleState *mst = NULL;
61 ssgSimpleState *mstf0 = NULL;
62 ssgSimpleState *mstf1 = NULL;
63 double * timeSmoke = 0;
64 double * timeFire = 0;
65 
66 
67 
68 void grInitSmoke(int index)
69 {
70  const int BUFSIZE = 256;
71  char buf[BUFSIZE];
72 
74  (char*)NULL, MAX_SMOKE_NUMBER);
76  (char*)NULL, DELTAT);
78  (char*)NULL, MAX_SMOKE_LIFE);
79 
80  if (!grSmokeMaxNumber) {
81  return;
82  }
83 
85 
86  if (!timeSmoke) {
87  timeSmoke = (double *) malloc(sizeof(double)*index*4);
88  memset(timeSmoke,0,sizeof(double)*index*4);
89  }
90 
91  if (!timeFire) {
92  timeFire = (double *) malloc(sizeof(double)*index);
93  memset(timeFire,0,sizeof(double)*index);
94  }
95 
96  if (!smokeManager) {
97  smokeManager = (tgrSmokeManager*) malloc(sizeof(tgrSmokeManager));
98  smokeManager->smokeList = NULL;
99  smokeManager->number = 0;
100  }
101 
102  // add temp object to get a reference on the states
103  if (!mst) {
104  snprintf(buf, BUFSIZE, "data/textures;data/img;.");
105  mst = (ssgSimpleState*)grSsgLoadTexStateEx("smoke.rgb", buf, FALSE, FALSE);
106  if (mst!=NULL) {
107  mst->disable(GL_LIGHTING);
108  mst->enable(GL_BLEND);
109  mst->disable(GL_CULL_FACE);
110  mst->setTranslucent();
111  mst->setColourMaterial(GL_AMBIENT_AND_DIFFUSE);
112  // Reference material to keep it,must be delete manually later
113  mst->ref();
114  }
115  }
116 
117  if (!mstf0) {
118  snprintf(buf, BUFSIZE, "data/textures;data/img;.");
119  mstf0 = (ssgSimpleState*)grSsgLoadTexStateEx("fire0.rgb", buf, FALSE, FALSE);
120  if (mst!=NULL) {
121  mstf0->disable(GL_LIGHTING);
122  mstf0->enable(GL_BLEND);
123  mstf0->disable(GL_CULL_FACE);
124  mstf0->setTranslucent();
125  mstf0->setColourMaterial(GL_AMBIENT_AND_DIFFUSE);
126  // Reference material to keep it,must be delete manually later
127  mstf0->ref();
128  }
129  }
130 
131  if (!mstf1) {
132  snprintf(buf, BUFSIZE, "data/textures;data/img;.");
133  mstf1 = (ssgSimpleState*)grSsgLoadTexStateEx("fire1.rgb", buf, FALSE, FALSE);
134  if (mst!=NULL) {
135  mstf1->disable(GL_LIGHTING);
136  mstf1->enable(GL_BLEND);
137  mstf1->disable(GL_CULL_FACE);
138  mstf1->setTranslucent();
139  mstf1->setColourMaterial(GL_AMBIENT_AND_DIFFUSE);
140  // Reference material to keep it,must be delete manually later
141  mstf1->ref();
142  }
143  }
144 }
145 
146 
148 void grUpdateSmoke(double t)
149 {
150  tgrSmoke * tmp, *tmp2;
151  tgrSmoke * prev;
152 
153  if (!grSmokeMaxNumber) {
154  return;
155  }
156 
157  prev = NULL;
158  tmp = smokeManager->smokeList;
159  while( tmp != NULL) {
160  if (tmp->smoke->cur_life >= tmp->smoke->max_life) {
161  if (prev) {
162  prev->next = tmp->next;
163  } else {
164  smokeManager->smokeList = tmp->next;
165  }
166 
167  smokeManager->number--;
168 
169  SmokeAnchor->removeKid(tmp->smoke);
170  tmp2 = tmp;
171  tmp = tmp->next;
172  free(tmp2);
173  continue;
174  }
175 
176  // update the smoke
177  tmp->smoke->dt = t-tmp->smoke->lastTime;
178  // expand the Y value
179  tmp->smoke->sizey += tmp->smoke->dt*tmp->smoke->vexp*2.0f;
180  tmp->smoke->sizez += tmp->smoke->dt*tmp->smoke->vexp*0.25f;
181  tmp->smoke->sizex += tmp->smoke->dt*tmp->smoke->vexp*2.0f;
182 
183  if (tmp->smoke->smokeType == SMOKE_TYPE_ENGINE) {
184  if (tmp->smoke->smokeTypeStep == 0) {
185  if (tmp->smoke->cur_life >= tmp->smoke->step0_max_life) {
186  // changing from fire to smoke
187  tmp->smoke->smokeTypeStep = 1;
188  tmp->smoke->setState(mstf1);
189  } else if (tmp->smoke->smokeTypeStep == 1) {
190  if (tmp->smoke->cur_life >= tmp->smoke->step1_max_life) {
191  // changing from fire to smoke
192  tmp->smoke->smokeTypeStep = 2;
193  tmp->smoke->setState(mst);
194  }
195  }
196  }
197  }
198 
199  sgVec3 *vx = (sgVec3 *) tmp->smoke->getVertices()->get(0) ;
200 
201  tdble dt = tmp->smoke->dt;
202 
203  tdble damp = 0.2f;
204  tmp->smoke->vvx -= damp*tmp->smoke->vvx*fabs(tmp->smoke->vvx) * dt;
205  tmp->smoke->vvy -= damp*tmp->smoke->vvy*fabs(tmp->smoke->vvy) * dt;
206  tmp->smoke->vvz -= damp*tmp->smoke->vvz*fabs(tmp->smoke->vvz) * dt;
207  tmp->smoke->vvz += 0.0001f;
208 
209  vx[0][0] += tmp->smoke->vvx * dt;
210  vx[0][1] += tmp->smoke->vvy * dt;
211  vx[0][2] += tmp->smoke->vvz * dt;
212 
213  tmp->smoke->lastTime = t;
214  tmp->smoke->cur_life += tmp->smoke->dt;
215  prev = tmp;
216  tmp = tmp->next;
217  }
218 }
219 
220 
221 void grAddSmoke(tCarElt *car, double t)
222 {
223  int i = 0;
224  tgrSmoke * tmp;
225  sgVec3 vtx;
226  ssgVertexArray *shd_vtx ;
227  tgrCarInstrument *curInst;
228  tdble val;
229  int index;
230 
231  if (!grSmokeMaxNumber) {
232  return;
233  }
234 
235  for (i = 0; i < 4; i++) {
236  if (car->pub.speed > 0.03f) { // 0.03 -> sqrt(0.001)
238  if ((t - timeSmoke[car->index*4+i]) < grSmokeDeltaT) {
239  continue;
240  } else {
241  timeSmoke[car->index*4+i] = t;
242  }
243 
244  sgVec3 cur_clr;
245  tdble init_speed;
246  tdble threshold = 0.1f;
247  tdble smoke_life_coefficient = 30.0f;
248  tdble smoke_speed_coefficient = 0.0f;
249 
250  cur_clr[0] = 0.8f;
251  cur_clr[1] = 0.8f;
252  cur_clr[2] = 0.8f;
253  init_speed = 0.01f;
254 
255  if (car->priv.wheel[i].seg) { // sanity check
256  const char* surface = car->priv.wheel[i].seg->surface->material;
257  if (strstr(surface, "sand")) {
258  cur_clr[0] = 0.8f;
259  cur_clr[1] = 0.7f + urandom()*0.1f;
260  cur_clr[2] = 0.4f + urandom()*0.2f;
261  init_speed = 0.5f;
262  threshold = 0.05f;
263  smoke_life_coefficient = 12.5f;
264  smoke_speed_coefficient = 0.25f;
265  } else if (strstr(surface, "dirt")) {
266  cur_clr[0] = 0.7f + urandom()*0.1f;
267  cur_clr[1] = 0.6f + urandom()*0.1f;
268  cur_clr[2] = 0.5f + urandom()*0.1f;
269  init_speed = 0.45f;
270  threshold=0.0f;
271  smoke_life_coefficient = 10.0f;
272  smoke_speed_coefficient = 0.5f;
273  } else if (strstr(surface,"mud")) {
274  cur_clr[0] = 0.65f;
275  cur_clr[1] = 0.4f + urandom()*0.2f;
276  cur_clr[2] = 0.3f + urandom()*0.2f;
277  init_speed = 0.4f;
278  threshold = 0.2f;
279  smoke_speed_coefficient = 0.05f;
280  } else if (strstr(surface,"gravel")) {
281  cur_clr[0] = 0.6f;
282  cur_clr[1] = 0.6f;
283  cur_clr[2] = 0.6f;
284  init_speed = 0.35f;
285  smoke_life_coefficient = 20.0f;
286  smoke_speed_coefficient = 0.1f;
287  } else if (strstr(surface,"grass")) {
288  cur_clr[0] = 0.4f + urandom()*0.2f;
289  cur_clr[1] = 0.5f + urandom()*0.1f;
290  cur_clr[2] = 0.3f + urandom()*0.1f;
291  init_speed = 0.3f;
292  smoke_life_coefficient = 25.0f;
293  } else {
294  cur_clr[0] = 0.8f;
295  cur_clr[1] = 0.8f;
296  cur_clr[2] = 0.8f;
297  init_speed = 0.01f;
298  }
299  }
300 
301  smoke_life_coefficient = smoke_life_coefficient * (1.0f - urandom()*urandom());
302  tdble spd_fx=tanh(0.001f*car->_reaction[i])*smoke_speed_coefficient*car->pub.speed;
303  if (car->_skid[i] + 0.025f*urandom()*spd_fx>urandom() + threshold) {// instead of 0.3, to randomize
304 
305  float init_speed_z = 0.1f;
306  float stretch_factor = 0.5f;
307  tdble sinCarYaw = sin(car->_yaw);
308  tdble cosCarYaw = cos(car->_yaw);
309 
310  shd_vtx = new ssgVertexArray(1);
311  //shd_clr = new ssgColourArray(1);
312 
313  tmp = (tgrSmoke *) malloc(sizeof(tgrSmoke));
314  vtx[0] = car->priv.wheel[i].relPos.x;
315  vtx[1] = car->priv.wheel[i].relPos.y;
316  vtx[2] = car->priv.wheel[i].relPos.z-car->_wheelRadius(i)*1.0f+ 0.5f * SMOKE_INIT_SIZE;
317  tdble stretchX = 0.1f * (spd_fx + stretch_factor * fabs(car->_speed_X));
318  tdble stretchY = 0.1f * (spd_fx + stretch_factor * fabs(car->_speed_Y));
319  vtx[0] -= 0.05f*car->_speed_x;
320 
321  shd_vtx->add(vtx);
323  init_speed = urandom()*init_speed;
324 
325  tmp->smoke->vvx = -sinCarYaw * car->_wheelSlipSide(i);
326  tmp->smoke->vvy = cosCarYaw * car->_wheelSlipSide(i);
327  tmp->smoke->vvx += cosCarYaw * car->_wheelSlipAccel(i);
328  tmp->smoke->vvy += sinCarYaw * car->_wheelSlipAccel(i);
329 
330  tmp->smoke->vvz = init_speed_z;
331 
332  tmp->smoke->vvx *= init_speed;
333  tmp->smoke->vvy *= init_speed;
334  tmp->smoke->setState(mst);
335  tmp->smoke->setCullFace(0);
336 
337  //printf("%f\n", car->_reaction[i]);
338  tmp->smoke->max_life = grSmokeLife *
339  (car->_skid[i]*car->pub.speed+urandom()*spd_fx)/ smoke_life_coefficient;
340  for (int c = 0; c < 3; c++) {
341  tmp->smoke->cur_col[c] = cur_clr[c];
342  }
343 
344  tmp->smoke->cur_life = 0;
345  tmp->smoke->sizex = VX_INIT + stretchX;
346  tmp->smoke->sizey = VY_INIT + stretchY;
347  tmp->smoke->sizez = VZ_INIT + 0.1f * spd_fx;
348 
349  tmp->smoke->init_alpha = 1.0/(1.0+0.1*spd_fx);
350  tmp->smoke->vexp = V_EXPANSION+(car->_skid[i]+.1*spd_fx)*(((float)rand()/(float)RAND_MAX));
352  tmp->smoke->smokeTypeStep = 0;
353  tmp->next = NULL;
354  tmp->smoke->lastTime = t;
355  tmp->smoke->transform(grCarInfo[car->index].carPos);
356  SmokeAnchor->addKid(tmp->smoke);
357  smokeManager->number++;
358  if (smokeManager->smokeList==NULL) {
359  smokeManager->smokeList = tmp;
360  } else {
361  tmp->next = smokeManager->smokeList;
362  smokeManager->smokeList = tmp;
363  }
364  }
365  }
366  }
367  }
368 
369  if (car->_exhaustNb && (car->pub.speed > 3.0f)) {
371  index = car->index; /* current car's index */
372  if ((t - timeFire[index]) > grFireDeltaT) {
373  timeFire[index] = t;
374  curInst = &(grCarInfo[index].instrument[0]);
375  val = ((curInst->rawPrev - curInst->minValue) / curInst->maxValue) - ((*(curInst->monitored) - curInst->minValue) / curInst->maxValue);
376  curInst->rawPrev = *(curInst->monitored);
377  if (val > 0.1) {
378  grCarInfo[index].fireCount = (int)(10.0 * val * car->_exhaustPower);
379  }
380 
381  if (grCarInfo[index].fireCount) {
382  grCarInfo[index].fireCount--;
383  //if (car->priv.smoke>urandom()) {
384 
385  //car->priv.smoke = val * car->_exhaustPower;
386  for (i = 0; i < car->_exhaustNb; i++) {
387  shd_vtx = new ssgVertexArray(1);
388  tmp = (tgrSmoke *) malloc(sizeof(tgrSmoke));
389  vtx[0] = car->_exhaustPos[i].x;
390  vtx[1] = car->_exhaustPos[i].y;
391  vtx[2] = car->_exhaustPos[i].z;
392 
393  shd_vtx->add(vtx);
395 
396  tmp->smoke->setState(mstf0);
397  tmp->smoke->setCullFace(0);
398  tmp->smoke->max_life = grSmokeLife/8;
399  tmp->smoke->step0_max_life = (grSmokeLife)/50.0;
400  tmp->smoke->step1_max_life = (grSmokeLife)/50.0+ tmp->smoke->max_life/2.0;
401  tmp->smoke->cur_life = 0;
402  //tmp->smoke->init_alpha = 0.9;
403  tmp->smoke->sizex = VX_INIT*4;
404  tmp->smoke->sizey = VY_INIT*4;
405  tmp->smoke->sizez = VZ_INIT*4;
406  tmp->smoke->vexp = V_EXPANSION+5.0*rand()/(RAND_MAX+1.0) * car->_exhaustPower / 2.0;
407  //tmp->smoke->vexp = V_EXPANSION+5.0*(((float)rand()/(float)RAND_MAX)) * car->_exhaustPower / 2.0;
409  tmp->smoke->smokeTypeStep = 0;
410  tmp->next = NULL;
411  tmp->smoke->lastTime = t;
412  tmp->smoke->transform(grCarInfo[index].carPos);
413  SmokeAnchor->addKid(tmp->smoke);
414  smokeManager->number++;
415  if (smokeManager->smokeList==NULL) {
416  smokeManager->smokeList = tmp;
417  } else {
418  tmp->next = smokeManager->smokeList;
419  smokeManager->smokeList = tmp;
420  }
421  }
422  }
423  }
424  }
425  }
426 }
427 
430 {
431  tgrSmoke *tmp, *tmp2;
432 
433  GfOut("-- grShutdownSmoke\n");
434 
435  if (!grSmokeMaxNumber) {
436  return;
437  }
438 
439  SmokeAnchor->removeAllKids();
440  if (smokeManager) {
441  tmp = smokeManager->smokeList;
442  while( tmp!=NULL)
443  {
444  tmp2 = tmp->next;
445  /* SmokeAnchor->removeKid(tmp->smoke); */
446  free(tmp);
447  tmp = tmp2;
448  }
449  smokeManager->smokeList = NULL;
450  free(timeSmoke);
451  free(timeFire);
452  free(smokeManager);
453  smokeManager = 0;
454  smokeManager = NULL;
455  timeSmoke = NULL;
456  timeFire=NULL;
457  }
458 
459  if (mst != NULL) {
460  ssgDeRefDelete(mst);
461  mst = NULL;
462  }
463 
464  if (mstf0 != NULL) {
465  ssgDeRefDelete(mstf0);
466  mstf0 = NULL;
467  }
468 
469  if (mstf1 != NULL) {
470  ssgDeRefDelete(mstf1);
471  mstf1 = NULL;
472  }
473 }
474 
475 void ssgVtxTableSmoke::copy_from ( ssgVtxTableSmoke *src, int clone_flags )
476 {
477  ssgVtxTable::copy_from ( src, clone_flags ) ;
478 }
479 ssgBase *ssgVtxTableSmoke::clone ( int clone_flags )
480 {
482  b -> copy_from ( this, clone_flags ) ;
483  return b ;
484 }
486 {
487  ssgVtxTable();
488 }
489 ssgVtxTableSmoke:: ssgVtxTableSmoke (ssgVertexArray *shd_vtx , float initsize, int typ)
490 {
491  sizex = sizey = sizez = initsize;
492 
493  gltype = GL_TRIANGLE_STRIP;
494  type = ssgTypeVtxTable () ;
495  stype = typ;
496  vertices = (shd_vtx!=NULL) ? shd_vtx : new ssgVertexArray () ;
497  normals = new ssgNormalArray () ;
498  texcoords = new ssgTexCoordArray () ;
499  colours = new ssgColourArray () ;
500 
501  vertices -> ref () ;
502  normals -> ref () ;
503  texcoords -> ref () ;
504  colours -> ref () ;
505  cur_col[0] = cur_col[1] = cur_col[2] = 0.8;
506  vvx = vvy = vvz = 0.0;
507  init_alpha = 0.9;
508  recalcBSphere () ;
509 }
510 
512 {
513 }
514 
516 {
517  int num_colours = getNumColours();
518  int num_normals = getNumNormals();
519  float alpha;
520  GLfloat modelView[16];
521  sgVec3 A, B, C, D;
522  sgVec3 right, up, offset;
523 
524  sgVec3 *vx = (sgVec3 *) vertices->get(0);
525  sgVec3 *nm = (sgVec3 *) normals->get(0);
526  sgVec4 *cl = (sgVec4 *) colours->get(0);
527  alpha = 0.9f - ((float)(cur_life/max_life));
528  glDepthMask(GL_FALSE);
529  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
530 
531  /*glPolygonOffset(-5.0f, +10.0f);*/
532  /*glEnable(GL_POLYGON_OFFSET_FILL);*/
533 
534  // the principle is to have a right and up vector
535  // to determine how the points of the quadri should be placed
536  // orthogonaly to the view, parallel to the screen.
537 
538  /* get the matrix */
539  // TODO: replace that, glGet stalls rendering pipeline (forces flush).
540  glGetFloatv(GL_MODELVIEW_MATRIX, modelView);
541 
542  // get the up and right vector from the matrice view
543 
544  offset[0] = offset[1] = offset[2] = 0.0f;
545 
546  int i;
547  for (i = 0; i < 3; i++) {
548  int j = i;
549  int k;
550  for (k = 0; k < 4; k++, j+=4) {
551  if (k != 3) {
552  offset[i] += modelView[j] * vx[0][k];
553  } else {
554  offset[i] += modelView[j];
555  }
556  }
557  }
558  //printf ("%f %f %f\n", offset[0], offset[1], offset[2]);
559 
560  tdble dist = sqrt(offset[0]*offset[0]
561  + offset[1]*offset[1]
562  + offset[2]*offset[2]);
563 
564  up[0] = modelView[1];
565  up[1] = modelView[5];
566  up[2] = modelView[9];
567 
568  right[0] = modelView[0];
569  right[1] = modelView[4];
570  right[2] = modelView[8];
571 
572  // compute the coordinates of the four points of the quadri.
573 
574  // up and right points
575  C[0] = right[0]+up[0];
576  C[1] = right[1]+up[1];
577  C[2] = right[2]+up[2];
578 
579  // left and up
580  D[0] = -right[0]+up[0];
581  D[1] = -right[1]+up[1];
582  D[2] = -right[2]+up[2];
583 
584  // down and left
585  A[0] = -right[0]-up[0];
586  A[1] = -right[1]-up[1];
587  A[2] = -right[2]-up[2];
588 
589  // right and down
590  B[0] = right[0]-up[0];
591  B[1] = right[1]-up[1];
592  B[2] = right[2]-up[2];
593 
594  glBegin ( gltype ) ;
595 
596  if (dist < 50.0f) {
597  alpha *= (1.0f - exp(-0.1f * dist));
598  }
599 
600  glColor4f(cur_col[0],cur_col[1],cur_col[2],alpha);
601  if (num_colours == 1) {
602  glColor4fv(cl[0]);
603  }
604  if (num_normals == 1) {
605  glNormal3fv(nm[0]);
606  }
607 
608  // the computed coordinates are translated from the smoke position with the x, y, z speed
609  glTexCoord2f(0,0);
610  glVertex3f(vx[0][0]+sizex*A[0],vx[0][1]+sizey*A[1], vx[0][2]+sizez*A[2]);
611  glTexCoord2f(0,1);
612  glVertex3f(vx[0][0]+sizex*B[0],vx[0][1]+sizey*B[1], vx[0][2]+sizez*B[2]);
613  glTexCoord2f(1,0);
614  glVertex3f(vx[0][0]+sizex*D[0],vx[0][1]+sizey*D[1], vx[0][2]+sizez*D[2]);
615  glTexCoord2f(1,1);
616  glVertex3f(vx[0][0]+sizex*C[0],vx[0][1]+sizey*C[1], vx[0][2]+sizez*C[2]);
617  glEnd();
618 
619  glDisable(GL_POLYGON_OFFSET_FILL);
620  glDepthMask(GL_TRUE);
621  glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
622 }
double grSmokeDeltaT
Definition: grsmoke.cpp:53
#define SMOKE_INIT_SIZE
Definition: grsmoke.h:4
double grFireDeltaT
Definition: grsmoke.cpp:54
void grAddSmoke(tCarElt *car, double t)
Definition: grsmoke.cpp:221
double lastTime
Definition: grsmoke.h:32
tdble y
y coordinate
Definition: tgf.h:132
double max_life
Definition: grsmoke.h:21
#define MAX_SMOKE_LIFE
Definition: grsmoke.h:5
#define GR_ATT_SMOKEDELTAT
Definition: graphic.h:84
Car structure (tCarElt).
Definition: car.h:455
tdble * monitored
Definition: grcar.h:34
Robots Tools.
virtual void copy_from(ssgVtxTableSmoke *src, int clone_flags)
Definition: grsmoke.cpp:475
double * timeFire
Definition: grsmoke.cpp:64
tdble rawPrev
Definition: grcar.h:36
#define SMOKE_TYPE_TIRE
Definition: grsmoke.h:12
tgrSmoke_st * next
Definition: grsmoke.h:76
virtual void transform(const sgMat4 m)
Definition: grsmoke.h:47
#define VZ_INIT
Definition: grsmoke.h:8
int grSmokeMaxNumber
Definition: grsmoke.cpp:52
tdble minValue
Definition: grcar.h:32
The Gaming Framework API (client part).
#define SMOKE_TYPE_ENGINE
Definition: grsmoke.h:13
void grInitSmoke(int index)
Definition: grsmoke.cpp:68
int getNumColours()
Definition: grsmoke.h:56
const char * material
Type of material used.
Definition: track.h:245
tPosd relPos
position relative to GC
Definition: car.h:250
void grShutdownSmoke()
remove the smoke information for a car
Definition: grsmoke.cpp:429
void grUpdateSmoke(double t)
update if necessary the smoke for a car
Definition: grsmoke.cpp:148
#define GR_ATT_SMOKENB
Definition: graphic.h:83
ssgSimpleState * mst
initialize the smoke structure
Definition: grsmoke.cpp:60
ssgBranch * SmokeAnchor
Definition: grscene.cpp:75
virtual ssgBase * clone(int clone_flags=0)
Definition: grsmoke.cpp:479
tgrCarInstrument instrument[2]
Definition: grcar.h:62
float tdble
Floating point type used in TORCS.
Definition: tgf.h:48
#define VX_INIT
Definition: grsmoke.h:10
#define GfOut
Definition: tgf.h:373
tdble x
x coordinate
Definition: tgf.h:131
tWheelState wheel[4]
Definition: car.h:290
float init_alpha
Definition: grsmoke.h:36
int smokeTypeStep
Definition: grsmoke.h:30
tPublicCar pub
public
Definition: car.h:459
ssgSimpleState * mstf0
Definition: grsmoke.cpp:61
#define MAX_SMOKE_NUMBER
Definition: grsmoke.h:6
Graphic Module Interface Definition.
#define GR_SCT_GRAPHIC
Definition: graphic.h:82
double grSmokeLife
Definition: grsmoke.cpp:55
tgrSmoke * smokeList
Definition: grsmoke.h:81
ssgSimpleState * mstf1
Definition: grsmoke.cpp:62
tPrivCar priv
private
Definition: car.h:461
#define V_EXPANSION
Definition: grsmoke.h:11
void draw_geometry()
Definition: grsmoke.cpp:515
This is the car structure.
int index
car index
Definition: car.h:457
sgMat4 carPos
Definition: grcar.h:61
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
double * timeSmoke
Definition: grsmoke.cpp:63
tTrackSeg * seg
Track segment where the wheel is.
Definition: car.h:254
tgrCarInfo * grCarInfo
Definition: grmain.cpp:66
ssgVtxTableSmoke * smoke
Definition: grsmoke.h:75
#define DELTAT
Definition: grsmoke.h:7
double cur_life
Definition: grsmoke.h:25
tdble speed
Definition: car.h:194
tTrackSurface * surface
Segment surface.
Definition: track.h:394
#define VY_INIT
Definition: grsmoke.h:9
ssgState * grSsgLoadTexStateEx(const char *img, char *filepath, int wrap, int mipmap)
Definition: grutil.cpp:284
int getNumNormals()
Definition: grsmoke.h:55
void * grHandle
Definition: grmain.cpp:59
sgVec3 cur_col
Definition: grsmoke.h:27
virtual ~ssgVtxTableSmoke(void)
Definition: grsmoke.cpp:511
real urandom()
Track Structure and Track Loader Module Definition.
This file contains the divergences from PLIB.
int fireCount
Definition: grcar.h:65
double step1_max_life
Definition: grsmoke.h:23
static tgrSmokeManager * smokeManager
Definition: grsmoke.cpp:58
tdble maxValue
Definition: grcar.h:32
#define GR_ATT_SMOKEDLIFE
Definition: graphic.h:85
double step0_max_life
Definition: grsmoke.h:22
tdble z
z coordinate
Definition: tgf.h:133