1 /*
2 * Tux Racer
3 * Copyright (C) 1999-2001 Jasmin F. Patry
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20 #include "track_marks.h"
21 #include "gl_util.h"
22 #include "tux.h"
23 #include "hier.h"
24 #include "phys_sim.h"
25 #include "textures.h"
26 #include "alglib.h"
27 #include "course_render.h"
28 #include "render_util.h"
29
30 #undef TRACK_TRIANGLES
31
32 #define TRACK_WIDTH 0.7
33 #define MAX_TRACK_MARKS 1000
34 #define MAX_CONTINUE_TRACK_DIST TRACK_WIDTH*4
35 #define MAX_CONTINUE_TRACK_TIME .1
36 #define SPEED_TO_START_TRENCH 0.0
37 #define SPEED_OF_DEEPEST_TRENCH 10
38
39 #ifdef TRACK_TRIANGLES
40 #define TRACK_HEIGHT 0.1
41 #define MAX_TRACK_DEPTH 10
42 #define MAX_TRIS MAX_TRACK_MARKS
43 #else
44 #define TRACK_HEIGHT 0.08
45 #define MAX_TRACK_DEPTH 0.7
46 #endif
47
48 typedef enum track_types_t {
49 TRACK_HEAD,
50 TRACK_MARK,
51 TRACK_TAIL,
52 NUM_TRACK_TYPES
53 } track_types_t;
54
55 typedef struct track_quad_t {
56 point_t v1, v2, v3, v4;
57 point2d_t t1, t2, t3, t4;
58 vector_t n1, n2, n3, n4;
59 track_types_t track_type;
60 scalar_t alpha;
61 } track_quad_t;
62
63 typedef struct track_marks_t {
64 track_quad_t quads[MAX_TRACK_MARKS];
65 int current_mark;
66 int next_mark;
67 scalar_t last_mark_time;
68 point_t last_mark_pos;
69 } track_marks_t;
70
71 static track_marks_t track_marks;
72 static bool_t continuing_track;
73
74
75
76 #ifdef TRACK_TRIANGLES
77 typedef struct track_tris_t {
78 triangle_t tri[MAX_TRIS];
79 track_types_t *track_type[MAX_TRIS];
80 scalar_t *alpha[MAX_TRIS];
81 int first_mark;
82 int next_mark;
83 int current_start;
84 int current_end;
85 int num_tris;
86 } track_tris_t;
87
88 typedef struct track_tri_t {
89 point_t v1, v2, v3;
90 } track_tri_t;
91
92 static track_tris_t track_tris;
93
draw_tri(triangle_t * tri,scalar_t alpha)94 static void draw_tri( triangle_t *tri, scalar_t alpha )
95 {
96 vector_t nml;
97 GLfloat c[4] = {1.0, 0.0, 0.0, 1.0};
98
99 /* set_material_alpha( white, black, 1.0, alpha ); */
100 set_material_alpha( white, black, 1.0, 1.0 );
101
102 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, c);
103
104 glBegin(GL_TRIANGLES);
105
106 nml = find_course_normal( tri->p[0].x, tri->p[0].z );
107 glNormal3f( nml.x, nml.y, nml.z );
108 glTexCoord2f( tri->t[0].x, tri->t[0].y );
109 glVertex3f( tri->p[0].x, tri->p[0].y, tri->p[0].z );
110
111 nml = find_course_normal( tri->p[1].x, tri->p[1].z );
112 glNormal3f( nml.x, nml.y, nml.z );
113 glTexCoord2f( tri->t[1].x, tri->t[1].y );
114 glVertex3f( tri->p[1].x, tri->p[1].y, tri->p[1].z );
115
116 nml = find_course_normal( tri->p[2].x, tri->p[2].z );
117 glNormal3f( nml.x, nml.y, nml.z );
118 glTexCoord2f( tri->t[2].x, tri->t[2].y );
119 glVertex3f( tri->p[2].x, tri->p[2].y, tri->p[2].z );
120
121 glEnd();
122 }
123
draw_tri_tracks(void)124 static void draw_tri_tracks( void )
125 {
126 GLuint texid[NUM_TRACK_TYPES];
127 int i;
128
129 set_gl_options( TRACK_MARKS );
130
131 glColor4f( 0, 0, 0, 1);
132
133 get_texture_binding( "track_head", &texid[TRACK_HEAD] );
134 get_texture_binding( "track_mark", &texid[TRACK_MARK] );
135 get_texture_binding( "track_tail", &texid[TRACK_TAIL] );
136
137 glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
138 set_material( white, black, 1.0 );
139 setup_course_lighting();
140
141 for( i = 0; i < track_tris.num_tris; i++ ) {
142 glBindTexture( GL_TEXTURE_2D,
143 texid[*track_tris.track_type[(track_tris.first_mark+i)%MAX_TRIS]] );
144 draw_tri( &track_tris.tri[(track_tris.first_mark+i)%MAX_TRIS],
145 *track_tris.alpha[(track_tris.first_mark+i)%MAX_TRIS] );
146 }
147 }
148
add_tri_tracks_from_tri(point_t p1,point_t p2,point_t p3,point2d_t t1,point2d_t t2,point2d_t t3,track_types_t * track_type,scalar_t * alpha)149 static void add_tri_tracks_from_tri( point_t p1, point_t p2, point_t p3,
150 point2d_t t1, point2d_t t2, point2d_t t3,
151 track_types_t *track_type, scalar_t *alpha )
152 {
153 scalar_t minx, maxx;
154 scalar_t minz, maxz;
155 int nx, nz;
156 scalar_t width, length;
157 int i, j, k;
158 scalar_t xstep, zstep;
159 line_t cut;
160 int num_tris;
161 int this_set_end;
162 int num_new;
163
164 /* Make 'em planar. Calculate y later anyway */
165 p1.y = p2.y = p3.y = 0;
166
167 get_course_divisions( &nx, &nz );
168 get_course_dimensions( &width, &length );
169 xstep = width/(nx-1);
170 zstep = length/(nz-1);
171
172 minx = min(min(p1.x, p2.x), p3.x);
173 minz = min(min(p1.z, p2.z), p3.z);
174 maxx = max(max(p1.x, p2.x), p3.x);
175 maxz = max(max(p1.z, p2.z), p3.z);
176
177 track_tris.current_start = track_tris.next_mark;
178 track_tris.current_end = track_tris.next_mark;
179
180 track_tris.tri[track_tris.next_mark].p[0] = p1;
181 track_tris.tri[track_tris.next_mark].p[1] = p2;
182 track_tris.tri[track_tris.next_mark].p[2] = p3;
183 track_tris.tri[track_tris.next_mark].t[0] = t1;
184 track_tris.tri[track_tris.next_mark].t[1] = t2;
185 track_tris.tri[track_tris.next_mark].t[2] = t3;
186
187 /*
188 * Make lengthwise cuts
189 */
190 for( i = (int)((minx/xstep)+0.9999); i < (int)(maxx/xstep); i++ ) {
191 cut.pt = make_point( i*xstep, 0, 0 );
192 cut.nml = make_vector( 1, 0, 0 );
193 this_set_end = track_tris.current_end;
194 for ( j = track_tris.current_start; j <= this_set_end; j++ ) {
195 num_tris = cut_triangle( &track_tris.tri[j%MAX_TRIS],
196 &track_tris.tri[(track_tris.current_end+1)%MAX_TRIS],
197 &track_tris.tri[(track_tris.current_end+2)%MAX_TRIS],
198 cut );
199 track_tris.current_end = (track_tris.current_end + num_tris - 1)%MAX_TRIS;
200 }
201 }
202
203 /*
204 * Make cross cuts
205 */
206 for( i = (int)((minz/zstep)+0.9999); i < (int)(maxz/zstep); i++ ) {
207 cut.pt = make_point( 0, 0, i*zstep );
208 cut.nml = make_vector( 0, 0, 1 );
209 this_set_end = track_tris.current_end;
210 for ( j = track_tris.current_start; j <= this_set_end; j++ ) {
211 num_tris = cut_triangle( &track_tris.tri[j%MAX_TRIS],
212 &track_tris.tri[(track_tris.current_end+1)%MAX_TRIS],
213 &track_tris.tri[(track_tris.current_end+2)%MAX_TRIS],
214 cut );
215 track_tris.current_end = (track_tris.current_end + num_tris - 1)%MAX_TRIS;
216 }
217 }
218
219 /*
220 * Make diagonal cuts
221 */
222 for( i = (int)((minx/xstep)+0.9999), j = (int)((minz/zstep)+0.9999);
223 (i < (int)(maxx/xstep)) && (j < (int)(maxz/zstep));
224 i++, j++) {
225 if ( (i+j)%2 != 0 ) {
226 i--;
227 }
228 cut.pt = make_point( i*xstep, 0, j*zstep );
229 cut.nml = make_vector( 1, 0, 1 );
230 normalize_vector(&cut.nml);
231 for ( k = track_tris.current_start; k <= this_set_end; k++ ) {
232 num_tris = cut_triangle( &track_tris.tri[k%MAX_TRIS],
233 &track_tris.tri[(track_tris.current_end+1)%MAX_TRIS],
234 &track_tris.tri[(track_tris.current_end+2)%MAX_TRIS],
235 cut );
236 track_tris.current_end = (track_tris.current_end + num_tris - 1)%MAX_TRIS;
237 }
238 }
239
240 /*
241 * Make other diagonal cuts
242 */
243 for( i = (int)((minx/xstep)+0.9999), j = (int)(maxz/zstep);
244 (i < (int)(maxx/xstep)) && (j > (int)((minz/zstep) + 0.9999));
245 i++, j--) {
246 if ( (i+j)%2 != 0 ) {
247 i--;
248 }
249 cut.pt = make_point( i*xstep, 0, j*zstep );
250 cut.nml = make_vector( 1, 0, 1 );
251 normalize_vector(&cut.nml);
252 for ( k = track_tris.current_start; k <= this_set_end; k++ ) {
253 num_tris = cut_triangle( &track_tris.tri[k%MAX_TRIS],
254 &track_tris.tri[(track_tris.current_end+1)%MAX_TRIS],
255 &track_tris.tri[(track_tris.current_end+2)%MAX_TRIS],
256 cut );
257 track_tris.current_end = (track_tris.current_end + num_tris - 1)%MAX_TRIS;
258 }
259 }
260
261
262 /* Reset first, next and num_tris */
263 if (track_tris.current_start <= track_tris.current_end) {
264 num_new = track_tris.current_end - track_tris.current_start + 1;
265 track_tris.num_tris = track_tris.num_tris + num_new;
266 track_tris.next_mark = (track_tris.current_end+1)%MAX_TRIS;
267 if ( ((track_tris.num_tris - num_new) > 0) &&
268 (track_tris.first_mark >= track_tris.current_start) &&
269 (track_tris.first_mark <= track_tris.current_end) ) {
270 track_tris.num_tris = track_tris.num_tris - (track_tris.current_end - track_tris.first_mark + 1);
271 track_tris.first_mark = track_tris.next_mark;
272 }
273
274 } else {
275 num_new = (track_tris.current_end + 1) + (MAX_TRIS - track_tris.current_start);
276 track_tris.num_tris = track_tris.num_tris + num_new;
277 track_tris.next_mark = (track_tris.current_end+1)%MAX_TRIS;
278 if (track_tris.first_mark >= track_tris.current_start) {
279 track_tris.num_tris = track_tris.num_tris - (track_tris.current_end + 1) -
280 (MAX_TRIS - track_tris.first_mark);
281 track_tris.first_mark = track_tris.next_mark;
282 } else if (track_tris.first_mark <= track_tris.current_end) {
283 track_tris.num_tris = track_tris.num_tris - (track_tris.current_end - track_tris.first_mark + 1);
284 track_tris.first_mark = track_tris.next_mark;
285 }
286
287 }
288
289 for ( i = 0; i < num_new; i++ ) {
290 track_tris.alpha[(track_tris.current_start+i)%MAX_TRIS] = alpha;
291 track_tris.track_type[(track_tris.current_start+i)%MAX_TRIS] = track_type;
292 track_tris.tri[(track_tris.current_start+i)%MAX_TRIS].p[0].y =
293 find_y_coord( track_tris.tri[(track_tris.current_start+i)%MAX_TRIS].p[0].x,
294 track_tris.tri[(track_tris.current_start+i)%MAX_TRIS].p[0].z ) +
295 TRACK_HEIGHT;
296 track_tris.tri[(track_tris.current_start+i)%MAX_TRIS].p[1].y =
297 find_y_coord( track_tris.tri[(track_tris.current_start+i)%MAX_TRIS].p[1].x,
298 track_tris.tri[(track_tris.current_start+i)%MAX_TRIS].p[1].z ) +
299 TRACK_HEIGHT;
300 track_tris.tri[(track_tris.current_start+i)%MAX_TRIS].p[2].y =
301 find_y_coord( track_tris.tri[(track_tris.current_start+i)%MAX_TRIS].p[2].x,
302 track_tris.tri[(track_tris.current_start+i)%MAX_TRIS].p[2].z ) +
303 TRACK_HEIGHT;
304 }
305
306 }
307
add_tri_tracks_from_quad(track_quad_t * q)308 static void add_tri_tracks_from_quad( track_quad_t *q )
309 {
310 add_tri_tracks_from_tri( q->v1, q->v2, q->v3, q->t1, q->t2, q->t3,
311 &q->track_type, &q->alpha );
312 add_tri_tracks_from_tri( q->v2, q->v4, q->v3, q->t2, q->t4, q->t3,
313 &q->track_type, &q->alpha );
314 }
315
316 #endif
317
318
319
init_track_marks(void)320 void init_track_marks(void)
321 {
322 track_marks.current_mark = 0;
323 track_marks.next_mark = 0;
324 track_marks.last_mark_time = -99999;
325 track_marks.last_mark_pos = make_point(-9999, -9999, -9999);
326 continuing_track = False;
327 #ifdef TRACK_TRIANGLES
328 track_tris.first_mark = 0;
329 track_tris.next_mark = 0;
330 track_tris.num_tris = 0;
331 #endif
332 }
333
334
335
draw_track_marks(void)336 void draw_track_marks(void)
337 {
338 #ifdef TRACK_TRIANGLES
339 draw_tri_tracks();
340 #else
341 GLuint texid[NUM_TRACK_TYPES];
342 int current_quad, num_quads;
343 int first_quad;
344 track_quad_t *q, *qnext;
345 colour_t track_colour;
346
347 track_colour = white;
348
349 if (getparam_track_marks() == False) {
350 return;
351 }
352
353 set_gl_options( TRACK_MARKS );
354
355 glColor4f( 0, 0, 0, 1);
356
357 get_texture_binding( "track_head", &texid[TRACK_HEAD] );
358 get_texture_binding( "track_mark", &texid[TRACK_MARK] );
359 get_texture_binding( "track_tail", &texid[TRACK_TAIL] );
360
361 glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
362 set_material( white, black, 1.0 );
363 setup_course_lighting();
364
365 num_quads = min( track_marks.current_mark, MAX_TRACK_MARKS -
366 track_marks.next_mark + track_marks.current_mark );
367 first_quad = track_marks.current_mark - num_quads;
368
369 for ( current_quad = 0;
370 current_quad < num_quads;
371 current_quad++ )
372 {
373 q = &track_marks.quads[(first_quad + current_quad)%MAX_TRACK_MARKS];
374
375 track_colour.a = q->alpha;
376 set_material( track_colour, black, 1.0 );
377
378 glBindTexture( GL_TEXTURE_2D, texid[q->track_type] );
379
380 if ((q->track_type == TRACK_HEAD) || (q->track_type == TRACK_TAIL)) {
381 glBegin(GL_QUADS);
382
383 glNormal3f( q->n1.x, q->n1.y, q->n1.z );
384 glTexCoord2f( q->t1.x, q->t1.y );
385 glVertex3f( q->v1.x, q->v1.y, q->v1.z );
386
387 glNormal3f( q->n2.x, q->n2.y, q->n2.z );
388 glTexCoord2f( q->t2.x, q->t2.y );
389 glVertex3f( q->v2.x, q->v2.y, q->v2.z );
390
391 glNormal3f( q->n4.x, q->n4.y, q->n4.z );
392 glTexCoord2f( q->t4.x, q->t4.y );
393 glVertex3f( q->v4.x, q->v4.y, q->v4.z );
394
395 glNormal3f( q->n3.x, q->n3.y, q->n3.z );
396 glTexCoord2f( q->t3.x, q->t3.y );
397 glVertex3f( q->v3.x, q->v3.y, q->v3.z );
398
399 glEnd();
400
401 } else {
402
403 glBegin(GL_QUAD_STRIP);
404
405 glNormal3f( q->n2.x, q->n2.y, q->n2.z );
406 glTexCoord2f( q->t2.x, q->t2.y );
407 glVertex3f( q->v2.x, q->v2.y, q->v2.z );
408
409 glNormal3f( q->n1.x, q->n1.y, q->n1.z );
410 glTexCoord2f( q->t1.x, q->t1.y );
411 glVertex3f( q->v1.x, q->v1.y, q->v1.z );
412
413 glNormal3f( q->n4.x, q->n4.y, q->n4.z );
414 glTexCoord2f( q->t4.x, q->t4.y );
415 glVertex3f( q->v4.x, q->v4.y, q->v4.z );
416
417 glNormal3f( q->n3.x, q->n3.y, q->n3.z );
418 glTexCoord2f( q->t3.x, q->t3.y );
419 glVertex3f( q->v3.x, q->v3.y, q->v3.z );
420
421
422 qnext = &track_marks.quads[(first_quad+current_quad+1)%MAX_TRACK_MARKS];
423 while (( qnext->track_type == TRACK_MARK ) && (current_quad+1 < num_quads)) {
424 current_quad++;
425 q = &track_marks.quads[(first_quad+current_quad)%MAX_TRACK_MARKS];
426 track_colour.a = qnext->alpha;
427 set_material( track_colour, black, 1.0 );
428
429 glNormal3f( q->n4.x, q->n4.y, q->n4.z );
430 glTexCoord2f( q->t4.x, q->t4.y );
431 glVertex3f( q->v4.x, q->v4.y, q->v4.z );
432
433 glNormal3f( q->n3.x, q->n3.y, q->n3.z );
434 glTexCoord2f( q->t3.x, q->t3.y );
435 glVertex3f( q->v3.x, q->v3.y, q->v3.z );
436
437 qnext = &track_marks.quads[(first_quad+current_quad+1)%MAX_TRACK_MARKS];
438 }
439 glEnd();
440 }
441
442 }
443 #endif
444
445 }
446
break_track_marks(void)447 void break_track_marks( void )
448 {
449 track_quad_t *qprev, *qprevprev;
450 qprev = &track_marks.quads[(track_marks.current_mark-1)%MAX_TRACK_MARKS];
451 qprevprev = &track_marks.quads[(track_marks.current_mark-2)%MAX_TRACK_MARKS];
452
453 if (track_marks.current_mark > 0) {
454 qprev->track_type = TRACK_TAIL;
455 qprev->t1 = make_point2d(0.0, 0.0);
456 qprev->t2 = make_point2d(1.0, 0.0);
457 qprev->t3 = make_point2d(0.0, 1.0);
458 qprev->t4 = make_point2d(1.0, 1.0);
459 qprevprev->t3.y = max((int)(qprevprev->t3.y+0.5), (int)(qprevprev->t1.y+1));
460 qprevprev->t4.y = max((int)(qprevprev->t3.y+0.5), (int)(qprevprev->t1.y+1));
461 }
462 track_marks.last_mark_time = -99999;
463 track_marks.last_mark_pos = make_point(-9999, -9999, -9999);
464 continuing_track = False;
465 }
466
add_track_mark(player_data_t * plyr)467 void add_track_mark( player_data_t *plyr )
468 {
469 vector_t width_vector;
470 vector_t left_vector;
471 vector_t right_vector;
472 scalar_t magnitude;
473 track_quad_t *q, *qprev, *qprevprev;
474 vector_t vel;
475 scalar_t speed;
476 point_t left_wing, right_wing;
477 scalar_t left_y, right_y;
478 scalar_t dist_from_surface;
479 plane_t surf_plane;
480 scalar_t comp_depth;
481 scalar_t tex_end;
482 scalar_t terrain_weights[NumTerrains];
483 scalar_t dist_from_last_mark;
484 vector_t vector_from_last_mark;
485
486 if (getparam_track_marks() == False) {
487 return;
488 }
489
490 q = &track_marks.quads[track_marks.current_mark%MAX_TRACK_MARKS];
491 qprev = &track_marks.quads[(track_marks.current_mark-1)%MAX_TRACK_MARKS];
492 qprevprev = &track_marks.quads[(track_marks.current_mark-2)%MAX_TRACK_MARKS];
493
494 vector_from_last_mark = subtract_points( plyr->pos, track_marks.last_mark_pos );
495 dist_from_last_mark = normalize_vector( &vector_from_last_mark );
496
497
498 get_surface_type(plyr->pos.x, plyr->pos.z, terrain_weights);
499 if (terrain_weights[Snow] < 0.5) {
500 break_track_marks();
501 return;
502 }
503
504 vel = plyr->vel;
505 speed = normalize_vector( &vel );
506 if (speed < SPEED_TO_START_TRENCH) {
507 break_track_marks();
508 return;
509 }
510
511 width_vector = cross_product( plyr->direction, make_vector( 0, 1, 0 ) );
512 magnitude = normalize_vector( &width_vector );
513 if ( magnitude == 0 ) {
514 break_track_marks();
515 return;
516 }
517
518 left_vector = scale_vector( TRACK_WIDTH/2.0, width_vector );
519 right_vector = scale_vector( -TRACK_WIDTH/2.0, width_vector );
520 left_wing = point_minus_vector( plyr->pos, left_vector );
521 right_wing = point_minus_vector( plyr->pos, right_vector );
522 left_y = find_y_coord( left_wing.x, left_wing.z );
523 right_y = find_y_coord( right_wing.x, right_wing.z );
524 if (fabs(left_y-right_y) > MAX_TRACK_DEPTH) {
525 break_track_marks();
526 return;
527 }
528
529 surf_plane = get_local_course_plane( plyr->pos );
530 dist_from_surface = distance_to_plane( surf_plane, plyr->pos );
531 comp_depth = get_compression_depth(Snow);
532 if ( dist_from_surface >= (2*comp_depth) ) {
533 break_track_marks();
534 return;
535 }
536
537
538 if (!continuing_track) {
539 break_track_marks();
540 q->track_type = TRACK_HEAD;
541 q->v1 = make_point( left_wing.x, left_y + TRACK_HEIGHT, left_wing.z );
542 q->v2 = make_point( right_wing.x, right_y + TRACK_HEIGHT, right_wing.z );
543 q->n1 = find_course_normal( q->v1.x, q->v1.z);
544 q->n2 = find_course_normal( q->v2.x, q->v2.z);
545 q->t1 = make_point2d(0.0, 0.0);
546 q->t2 = make_point2d(1.0, 0.0);
547 track_marks.next_mark = track_marks.current_mark + 1;
548 } else {
549 if ( track_marks.next_mark == track_marks.current_mark ) {
550 q->v1 = qprev->v3;
551 q->v2 = qprev->v4;
552 q->n1 = qprev->n3;
553 q->n2 = qprev->n4;
554 q->t1 = qprev->t3;
555 q->t2 = qprev->t4;
556 if ( qprev->track_type != TRACK_HEAD ) {
557 qprev->track_type = TRACK_MARK;
558 }
559 q->track_type = TRACK_MARK;
560 }
561 q->v3 = make_point( left_wing.x, left_y + TRACK_HEIGHT, left_wing.z );
562 q->v4 = make_point( right_wing.x, right_y + TRACK_HEIGHT, right_wing.z );
563 q->n3 = find_course_normal( q->v3.x, q->v3.z);
564 q->n4 = find_course_normal( q->v4.x, q->v4.z);
565 tex_end = speed*g_game.time_step/TRACK_WIDTH;
566 if (q->track_type == TRACK_HEAD) {
567 q->t3= make_point2d(0.0, 1.0);
568 q->t4= make_point2d(1.0, 1.0);
569 } else {
570 q->t3 = make_point2d(0.0, q->t1.y + tex_end);
571 q->t4 = make_point2d(1.0, q->t2.y + tex_end);
572 }
573
574 #ifdef TRACK_TRIANGLES
575 add_tri_tracks_from_quad(q);
576 #endif
577 track_marks.current_mark++;
578 track_marks.next_mark = track_marks.current_mark;
579 }
580
581 q->alpha = min( (2*comp_depth-dist_from_surface)/(4*comp_depth), 1.0 );
582
583 track_marks.last_mark_time = g_game.time;
584 continuing_track = True;
585
586 }
587