doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
tr_deform.cpp
Go to the documentation of this file.
1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
8 
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
21 
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
23 
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25 
26 ===========================================================================
27 */
28 
29 #include "../idlib/precompiled.h"
30 #pragma hdrstop
31 
32 #include "tr_local.h"
33 
34 
35 /*
36 =================
37 R_FinishDeform
38 
39 The ambientCache is on the stack, so we don't want to leave a reference
40 to it that would try to be freed later. Create the ambientCache immediately.
41 =================
42 */
43 static void R_FinishDeform( drawSurf_t *drawSurf, srfTriangles_t *newTri, idDrawVert *ac ) {
44  if ( !newTri ) {
45  return;
46  }
47 
48  // generate current normals, tangents, and bitangents
49  // We might want to support the possibility of deform functions generating
50  // explicit normals, and we might also want to allow the cached deformInfo
51  // optimization for these.
52  // FIXME: this doesn't work, because the deformed surface is just the
53  // ambient one, and there isn't an opportunity to generate light interactions
54  if ( drawSurf->material->ReceivesLighting() ) {
55  newTri->verts = ac;
56  R_DeriveTangents( newTri, false );
57  newTri->verts = NULL;
58  }
59 
60  newTri->ambientCache = vertexCache.AllocFrameTemp( ac, newTri->numVerts * sizeof( idDrawVert ) );
61  // if we are out of vertex cache, leave it the way it is
62  if ( newTri->ambientCache ) {
63  drawSurf->geo = newTri;
64  }
65 }
66 
67 /*
68 =====================
69 R_AutospriteDeform
70 
71 Assuming all the triangles for this shader are independant
72 quads, rebuild them as forward facing sprites
73 =====================
74 */
75 static void R_AutospriteDeform( drawSurf_t *surf ) {
76  int i;
77  const idDrawVert *v;
78  idVec3 mid, delta;
79  float radius;
80  idVec3 left, up;
81  idVec3 leftDir, upDir;
82  const srfTriangles_t *tri;
83  srfTriangles_t *newTri;
84 
85  tri = surf->geo;
86 
87  if ( tri->numVerts & 3 ) {
88  common->Warning( "R_AutospriteDeform: shader had odd vertex count" );
89  return;
90  }
91  if ( tri->numIndexes != ( tri->numVerts >> 2 ) * 6 ) {
92  common->Warning( "R_AutospriteDeform: autosprite had odd index count" );
93  return;
94  }
95 
98 
99  if ( tr.viewDef->isMirror ) {
100  leftDir = vec3_origin - leftDir;
101  }
102 
103  // this srfTriangles_t and all its indexes and caches are in frame
104  // memory, and will be automatically disposed of
105  newTri = (srfTriangles_t *)R_ClearedFrameAlloc( sizeof( *newTri ) );
106  newTri->numVerts = tri->numVerts;
107  newTri->numIndexes = tri->numIndexes;
108  newTri->indexes = (glIndex_t *)R_FrameAlloc( newTri->numIndexes * sizeof( newTri->indexes[0] ) );
109 
110  idDrawVert *ac = (idDrawVert *)_alloca16( newTri->numVerts * sizeof( idDrawVert ) );
111 
112  for ( i = 0 ; i < tri->numVerts ; i+=4 ) {
113  // find the midpoint
114  v = &tri->verts[i];
115 
116  mid[0] = 0.25 * (v->xyz[0] + (v+1)->xyz[0] + (v+2)->xyz[0] + (v+3)->xyz[0]);
117  mid[1] = 0.25 * (v->xyz[1] + (v+1)->xyz[1] + (v+2)->xyz[1] + (v+3)->xyz[1]);
118  mid[2] = 0.25 * (v->xyz[2] + (v+1)->xyz[2] + (v+2)->xyz[2] + (v+3)->xyz[2]);
119 
120  delta = v->xyz - mid;
121  radius = delta.Length() * 0.707; // / sqrt(2)
122 
123  left = leftDir * radius;
124  up = upDir * radius;
125 
126  ac[i+0].xyz = mid + left + up;
127  ac[i+0].st[0] = 0;
128  ac[i+0].st[1] = 0;
129  ac[i+1].xyz = mid - left + up;
130  ac[i+1].st[0] = 1;
131  ac[i+1].st[1] = 0;
132  ac[i+2].xyz = mid - left - up;
133  ac[i+2].st[0] = 1;
134  ac[i+2].st[1] = 1;
135  ac[i+3].xyz = mid + left - up;
136  ac[i+3].st[0] = 0;
137  ac[i+3].st[1] = 1;
138 
139  newTri->indexes[6*(i>>2)+0] = i;
140  newTri->indexes[6*(i>>2)+1] = i+1;
141  newTri->indexes[6*(i>>2)+2] = i+2;
142 
143  newTri->indexes[6*(i>>2)+3] = i;
144  newTri->indexes[6*(i>>2)+4] = i+2;
145  newTri->indexes[6*(i>>2)+5] = i+3;
146  }
147 
148  R_FinishDeform( surf, newTri, ac );
149 }
150 
151 /*
152 =====================
153 R_TubeDeform
154 
155 will pivot a rectangular quad along the center of its long axis
156 
157 Note that a geometric tube with even quite a few sides tube will almost certainly render much faster
158 than this, so this should only be for faked volumetric tubes.
159 Make sure this is used with twosided translucent shaders, because the exact side
160 order may not be correct.
161 =====================
162 */
163 static void R_TubeDeform( drawSurf_t *surf ) {
164  int i, j;
165  int indexes;
166  const srfTriangles_t *tri;
167 static int edgeVerts[6][2] = {
168  { 0, 1 },
169  { 1, 2 },
170  { 2, 0 },
171  { 3, 4 },
172  { 4, 5 },
173  { 5, 3 }
174 };
175 
176  tri = surf->geo;
177 
178  if ( tri->numVerts & 3 ) {
179  common->Error( "R_AutospriteDeform: shader had odd vertex count" );
180  }
181  if ( tri->numIndexes != ( tri->numVerts >> 2 ) * 6 ) {
182  common->Error( "R_AutospriteDeform: autosprite had odd index count" );
183  }
184 
185  // we need the view direction to project the minor axis of the tube
186  // as the view changes
187  idVec3 localView;
189 
190  // this srfTriangles_t and all its indexes and caches are in frame
191  // memory, and will be automatically disposed of
192  srfTriangles_t *newTri = (srfTriangles_t *)R_ClearedFrameAlloc( sizeof( *newTri ) );
193  newTri->numVerts = tri->numVerts;
194  newTri->numIndexes = tri->numIndexes;
195  newTri->indexes = (glIndex_t *)R_FrameAlloc( newTri->numIndexes * sizeof( newTri->indexes[0] ) );
196  memcpy( newTri->indexes, tri->indexes, newTri->numIndexes * sizeof( newTri->indexes[0] ) );
197 
198  idDrawVert *ac = (idDrawVert *)_alloca16( newTri->numVerts * sizeof( idDrawVert ) );
199  memset( ac, 0, sizeof( idDrawVert ) * newTri->numVerts );
200 
201  // this is a lot of work for two triangles...
202  // we could precalculate a lot if it is an issue, but it would mess up
203  // the shader abstraction
204  for ( i = 0, indexes = 0 ; i < tri->numVerts ; i+=4, indexes+=6 ) {
205  float lengths[2];
206  int nums[2];
207  idVec3 mid[2];
208  idVec3 major, minor;
209  const idDrawVert *v1, *v2;
210 
211  // identify the two shortest edges out of the six defined by the indexes
212  nums[0] = nums[1] = 0;
213  lengths[0] = lengths[1] = 999999;
214 
215  for ( j = 0 ; j < 6 ; j++ ) {
216  float l;
217 
218  v1 = &tri->verts[tri->indexes[i+edgeVerts[j][0]]];
219  v2 = &tri->verts[tri->indexes[i+edgeVerts[j][1]]];
220 
221  l = ( v1->xyz - v2->xyz ).Length();
222  if ( l < lengths[0] ) {
223  nums[1] = nums[0];
224  lengths[1] = lengths[0];
225  nums[0] = j;
226  lengths[0] = l;
227  } else if ( l < lengths[1] ) {
228  nums[1] = j;
229  lengths[1] = l;
230  }
231  }
232 
233  // find the midpoints of the two short edges, which
234  // will give us the major axis in object coordinates
235  for ( j = 0 ; j < 2 ; j++ ) {
236  v1 = &tri->verts[tri->indexes[i+edgeVerts[nums[j]][0]]];
237  v2 = &tri->verts[tri->indexes[i+edgeVerts[nums[j]][1]]];
238 
239  mid[j][0] = 0.5 * (v1->xyz[0] + v2->xyz[0]);
240  mid[j][1] = 0.5 * (v1->xyz[1] + v2->xyz[1]);
241  mid[j][2] = 0.5 * (v1->xyz[2] + v2->xyz[2]);
242  }
243 
244  // find the vector of the major axis
245  major = mid[1] - mid[0];
246 
247  // re-project the points
248  for ( j = 0 ; j < 2 ; j++ ) {
249  float l;
250  int i1 = tri->indexes[i+edgeVerts[nums[j]][0]];
251  int i2 = tri->indexes[i+edgeVerts[nums[j]][1]];
252 
253  idDrawVert *av1 = &ac[i1];
254  idDrawVert *av2 = &ac[i2];
255 
256  *av1 = *(idDrawVert *)&tri->verts[i1];
257  *av2 = *(idDrawVert *)&tri->verts[i2];
258 
259  l = 0.5 * lengths[j];
260 
261  // cross this with the view direction to get minor axis
262  idVec3 dir = mid[j] - localView;
263  minor.Cross( major, dir );
264  minor.Normalize();
265 
266  if ( j ) {
267  av1->xyz = mid[j] - l * minor;
268  av2->xyz = mid[j] + l * minor;
269  } else {
270  av1->xyz = mid[j] + l * minor;
271  av2->xyz = mid[j] - l * minor;
272  }
273  }
274  }
275 
276  R_FinishDeform( surf, newTri, ac );
277 }
278 
279 /*
280 =====================
281 R_WindingFromTriangles
282 
283 =====================
284 */
285 #define MAX_TRI_WINDING_INDEXES 16
287  int i, j, k, l;
288 
289  indexes[0] = tri->indexes[0];
290  int numIndexes = 1;
291  int numTris = tri->numIndexes / 3;
292 
293  do {
294  // find an edge that goes from the current index to another
295  // index that isn't already used, and isn't an internal edge
296  for ( i = 0 ; i < numTris ; i++ ) {
297  for ( j = 0 ; j < 3 ; j++ ) {
298  if ( tri->indexes[i*3+j] != indexes[numIndexes-1] ) {
299  continue;
300  }
301  int next = tri->indexes[i*3+(j+1)%3];
302 
303  // make sure it isn't already used
304  if ( numIndexes == 1 ) {
305  if ( next == indexes[0] ) {
306  continue;
307  }
308  } else {
309  for ( k = 1 ; k < numIndexes ; k++ ) {
310  if ( indexes[k] == next ) {
311  break;
312  }
313  }
314  if ( k != numIndexes ) {
315  continue;
316  }
317  }
318 
319  // make sure it isn't an interior edge
320  for ( k = 0 ; k < numTris ; k++ ) {
321  if ( k == i ) {
322  continue;
323  }
324  for ( l = 0 ; l < 3 ; l++ ) {
325  int a, b;
326 
327  a = tri->indexes[k*3+l];
328  if ( a != next ) {
329  continue;
330  }
331  b = tri->indexes[k*3+(l+1)%3];
332  if ( b != indexes[numIndexes-1] ) {
333  continue;
334  }
335 
336  // this is an interior edge
337  break;
338  }
339  if ( l != 3 ) {
340  break;
341  }
342  }
343  if ( k != numTris ) {
344  continue;
345  }
346 
347  // add this to the list
348  indexes[numIndexes] = next;
349  numIndexes++;
350  break;
351  }
352  if ( j != 3 ) {
353  break;
354  }
355  }
356  if ( numIndexes == tri->numVerts ) {
357  break;
358  }
359  } while ( i != numTris );
360 
361  return numIndexes;
362 }
363 
364 /*
365 =====================
366 R_FlareDeform
367 
368 =====================
369 */
370 /*
371 static void R_FlareDeform( drawSurf_t *surf ) {
372  const srfTriangles_t *tri;
373  srfTriangles_t *newTri;
374  idPlane plane;
375  float dot;
376  idVec3 localViewer;
377  int j;
378 
379  tri = surf->geo;
380 
381  if ( tri->numVerts != 4 || tri->numIndexes != 6 ) {
382  //FIXME: temp hack for flares on tripleted models
383  common->Warning( "R_FlareDeform: not a single quad" );
384  return;
385  }
386 
387  // this srfTriangles_t and all its indexes and caches are in frame
388  // memory, and will be automatically disposed of
389  newTri = (srfTriangles_t *)R_ClearedFrameAlloc( sizeof( *newTri ) );
390  newTri->numVerts = 4;
391  newTri->numIndexes = 2*3;
392  newTri->indexes = (glIndex_t *)R_FrameAlloc( newTri->numIndexes * sizeof( newTri->indexes[0] ) );
393 
394  idDrawVert *ac = (idDrawVert *)_alloca16( newTri->numVerts * sizeof( idDrawVert ) );
395 
396  // find the plane
397  plane.FromPoints( tri->verts[tri->indexes[0]].xyz, tri->verts[tri->indexes[1]].xyz, tri->verts[tri->indexes[2]].xyz );
398 
399  // if viewer is behind the plane, draw nothing
400  R_GlobalPointToLocal( surf->space->modelMatrix, tr.viewDef->renderView.vieworg, localViewer );
401  float distFromPlane = localViewer * plane.Normal() + plane[3];
402  if ( distFromPlane <= 0 ) {
403  newTri->numIndexes = 0;
404  surf->geo = newTri;
405  return;
406  }
407 
408  idVec3 center;
409  center = tri->verts[0].xyz;
410  for ( j = 1 ; j < tri->numVerts ; j++ ) {
411  center += tri->verts[j].xyz;
412  }
413  center *= 1.0/tri->numVerts;
414 
415  idVec3 dir = localViewer - center;
416  dir.Normalize();
417 
418  dot = dir * plane.Normal();
419 
420  // set vertex colors based on plane angle
421  int color = (int)(dot * 8 * 256);
422  if ( color > 255 ) {
423  color = 255;
424  }
425  for ( j = 0 ; j < newTri->numVerts ; j++ ) {
426  ac[j].color[0] =
427  ac[j].color[1] =
428  ac[j].color[2] = color;
429  ac[j].color[3] = 255;
430  }
431 
432  float spread = surf->shaderRegisters[ surf->material->GetDeformRegister(0) ] * r_flareSize.GetFloat();
433  idVec3 edgeDir[4][3];
434  glIndex_t indexes[MAX_TRI_WINDING_INDEXES];
435  int numIndexes = R_WindingFromTriangles( tri, indexes );
436 
437  surf->material = declManager->FindMaterial( "textures/smf/anamorphicFlare" );
438 
439  // only deal with quads
440  if ( numIndexes != 4 ) {
441  return;
442  }
443 
444  // compute centroid
445  idVec3 centroid, toeye, forward, up, left;
446  centroid.Set( 0, 0, 0 );
447  for ( int i = 0; i < 4; i++ ) {
448  centroid += tri->verts[ indexes[i] ].xyz;
449  }
450  centroid /= 4;
451 
452  // compute basis vectors
453  up.Set( 0, 0, 1 );
454 
455  toeye = centroid - localViewer;
456  toeye.Normalize();
457  left = toeye.Cross( up );
458  up = left.Cross( toeye );
459 
460  left = left * 40 * 6;
461  up = up * 40;
462 
463  // compute flares
464  struct flare_t {
465  float angle;
466  float length;
467  };
468 
469  static flare_t flares[] = {
470  { 0, 100 },
471  { 90, 100 }
472  };
473 
474  for ( int i = 0; i < 4; i++ ) {
475  memset( ac + i, 0, sizeof( ac[i] ) );
476  }
477 
478  ac[0].xyz = centroid - left;
479  ac[0].st[0] = 0; ac[0].st[1] = 0;
480 
481  ac[1].xyz = centroid + up;
482  ac[1].st[0] = 1; ac[1].st[1] = 0;
483 
484  ac[2].xyz = centroid + left;
485  ac[2].st[0] = 1; ac[2].st[1] = 1;
486 
487  ac[3].xyz = centroid - up;
488  ac[3].st[0] = 0; ac[3].st[1] = 1;
489 
490  // setup colors
491  for ( j = 0 ; j < newTri->numVerts ; j++ ) {
492  ac[j].color[0] =
493  ac[j].color[1] =
494  ac[j].color[2] = 255;
495  ac[j].color[3] = 255;
496  }
497 
498  // setup indexes
499  static glIndex_t triIndexes[2*3] = {
500  0,1,2, 0,2,3
501  };
502 
503  memcpy( newTri->indexes, triIndexes, sizeof( triIndexes ) );
504 
505  R_FinishDeform( surf, newTri, ac );
506 }
507 */
508 
509 static void R_FlareDeform( drawSurf_t *surf ) {
510  const srfTriangles_t *tri;
511  srfTriangles_t *newTri;
512  idPlane plane;
513  float dot;
514  idVec3 localViewer;
515  int j;
516 
517  tri = surf->geo;
518 
519  if ( tri->numVerts != 4 || tri->numIndexes != 6 ) {
520  //FIXME: temp hack for flares on tripleted models
521  common->Warning( "R_FlareDeform: not a single quad" );
522  return;
523  }
524 
525  // this srfTriangles_t and all its indexes and caches are in frame
526  // memory, and will be automatically disposed of
527  newTri = (srfTriangles_t *)R_ClearedFrameAlloc( sizeof( *newTri ) );
528  newTri->numVerts = 16;
529  newTri->numIndexes = 18*3;
530  newTri->indexes = (glIndex_t *)R_FrameAlloc( newTri->numIndexes * sizeof( newTri->indexes[0] ) );
531 
532  idDrawVert *ac = (idDrawVert *)_alloca16( newTri->numVerts * sizeof( idDrawVert ) );
533 
534  // find the plane
535  plane.FromPoints( tri->verts[tri->indexes[0]].xyz, tri->verts[tri->indexes[1]].xyz, tri->verts[tri->indexes[2]].xyz );
536 
537  // if viewer is behind the plane, draw nothing
539  float distFromPlane = localViewer * plane.Normal() + plane[3];
540  if ( distFromPlane <= 0 ) {
541  newTri->numIndexes = 0;
542  surf->geo = newTri;
543  return;
544  }
545 
546  idVec3 center;
547  center = tri->verts[0].xyz;
548  for ( j = 1 ; j < tri->numVerts ; j++ ) {
549  center += tri->verts[j].xyz;
550  }
551  center *= 1.0/tri->numVerts;
552 
553  idVec3 dir = localViewer - center;
554  dir.Normalize();
555 
556  dot = dir * plane.Normal();
557 
558  // set vertex colors based on plane angle
559  int color = (int)(dot * 8 * 256);
560  if ( color > 255 ) {
561  color = 255;
562  }
563  for ( j = 0 ; j < newTri->numVerts ; j++ ) {
564  ac[j].color[0] =
565  ac[j].color[1] =
566  ac[j].color[2] = color;
567  ac[j].color[3] = 255;
568  }
569 
570  float spread = surf->shaderRegisters[ surf->material->GetDeformRegister(0) ] * r_flareSize.GetFloat();
571  idVec3 edgeDir[4][3];
573  int numIndexes = R_WindingFromTriangles( tri, indexes );
574 
575 
576  // only deal with quads
577  if ( numIndexes != 4 ) {
578  return;
579  }
580  int i;
581  // calculate vector directions
582  for ( i = 0 ; i < 4 ; i++ ) {
583  ac[i].xyz = tri->verts[ indexes[i] ].xyz;
584  ac[i].st[0] =
585  ac[i].st[1] = 0.5;
586 
587  idVec3 toEye = tri->verts[ indexes[i] ].xyz - localViewer;
588  toEye.Normalize();
589 
590  idVec3 d1 = tri->verts[ indexes[(i+1)%4] ].xyz - localViewer;
591  d1.Normalize();
592  edgeDir[i][1].Cross( toEye, d1 );
593  edgeDir[i][1].Normalize();
594  edgeDir[i][1] = vec3_origin - edgeDir[i][1];
595 
596  idVec3 d2 = tri->verts[ indexes[(i+3)%4] ].xyz - localViewer;
597  d2.Normalize();
598  edgeDir[i][0].Cross( toEye, d2 );
599  edgeDir[i][0].Normalize();
600 
601  edgeDir[i][2] = edgeDir[i][0] + edgeDir[i][1];
602  edgeDir[i][2].Normalize();
603  }
604 
605  // build all the points
606  ac[4].xyz = tri->verts[ indexes[0] ].xyz + spread * edgeDir[0][0];
607  ac[4].st[0] = 0;
608  ac[4].st[1] = 0.5;
609 
610  ac[5].xyz = tri->verts[ indexes[0] ].xyz + spread * edgeDir[0][2];
611  ac[5].st[0] = 0;
612  ac[5].st[1] = 0;
613 
614  ac[6].xyz = tri->verts[ indexes[0] ].xyz + spread * edgeDir[0][1];
615  ac[6].st[0] = 0.5;
616  ac[6].st[1] = 0;
617 
618 
619  ac[7].xyz = tri->verts[ indexes[1] ].xyz + spread * edgeDir[1][0];
620  ac[7].st[0] = 0.5;
621  ac[7].st[1] = 0;
622 
623  ac[8].xyz = tri->verts[ indexes[1] ].xyz + spread * edgeDir[1][2];
624  ac[8].st[0] = 1;
625  ac[8].st[1] = 0;
626 
627  ac[9].xyz = tri->verts[ indexes[1] ].xyz + spread * edgeDir[1][1];
628  ac[9].st[0] = 1;
629  ac[9].st[1] = 0.5;
630 
631 
632  ac[10].xyz = tri->verts[ indexes[2] ].xyz + spread * edgeDir[2][0];
633  ac[10].st[0] = 1;
634  ac[10].st[1] = 0.5;
635 
636  ac[11].xyz = tri->verts[ indexes[2] ].xyz + spread * edgeDir[2][2];
637  ac[11].st[0] = 1;
638  ac[11].st[1] = 1;
639 
640  ac[12].xyz = tri->verts[ indexes[2] ].xyz + spread * edgeDir[2][1];
641  ac[12].st[0] = 0.5;
642  ac[12].st[1] = 1;
643 
644 
645  ac[13].xyz = tri->verts[ indexes[3] ].xyz + spread * edgeDir[3][0];
646  ac[13].st[0] = 0.5;
647  ac[13].st[1] = 1;
648 
649  ac[14].xyz = tri->verts[ indexes[3] ].xyz + spread * edgeDir[3][2];
650  ac[14].st[0] = 0;
651  ac[14].st[1] = 1;
652 
653  ac[15].xyz = tri->verts[ indexes[3] ].xyz + spread * edgeDir[3][1];
654  ac[15].st[0] = 0;
655  ac[15].st[1] = 0.5;
656 
657  for ( i = 4 ; i < 16 ; i++ ) {
658  idVec3 dir = ac[i].xyz - localViewer;
659  float len = dir.Normalize();
660 
661  float ang = dir * plane.Normal();
662 
663 // ac[i].xyz -= dir * spread * 2;
664  float newLen = -( distFromPlane / ang );
665 
666  if ( newLen > 0 && newLen < len ) {
667  ac[i].xyz = localViewer + dir * newLen;
668  }
669 
670  ac[i].st[0] = 0;
671  ac[i].st[1] = 0.5;
672  }
673 
674 #if 1
675  static glIndex_t triIndexes[18*3] = {
676  0,4,5, 0,5,6, 0,6,7, 0,7,1, 1,7,8, 1,8,9,
677  15,4,0, 15,0,3, 3,0,1, 3,1,2, 2,1,9, 2,9,10,
678  14,15,3, 14,3,13, 13,3,2, 13,2,12, 12,2,11, 11,2,10
679  };
680 #else
681  newTri->numIndexes = 12;
682  static glIndex_t triIndexes[4*3] = {
683  0,1,2, 0,2,3, 0,4,5,0,5,6
684  };
685 #endif
686 
687  memcpy( newTri->indexes, triIndexes, sizeof( triIndexes ) );
688 
689  R_FinishDeform( surf, newTri, ac );
690 }
691 
692 
693 
694 /*
695 =====================
696 R_ExpandDeform
697 
698 Expands the surface along it's normals by a shader amount
699 =====================
700 */
701 static void R_ExpandDeform( drawSurf_t *surf ) {
702  int i;
703  const srfTriangles_t *tri;
704  srfTriangles_t *newTri;
705 
706  tri = surf->geo;
707 
708  // this srfTriangles_t and all its indexes and caches are in frame
709  // memory, and will be automatically disposed of
710  newTri = (srfTriangles_t *)R_ClearedFrameAlloc( sizeof( *newTri ) );
711  newTri->numVerts = tri->numVerts;
712  newTri->numIndexes = tri->numIndexes;
713  newTri->indexes = tri->indexes;
714 
715  idDrawVert *ac = (idDrawVert *)_alloca16( newTri->numVerts * sizeof( idDrawVert ) );
716 
717  float dist = surf->shaderRegisters[ surf->material->GetDeformRegister(0) ];
718  for ( i = 0 ; i < tri->numVerts ; i++ ) {
719  ac[i] = *(idDrawVert *)&tri->verts[i];
720  ac[i].xyz = tri->verts[i].xyz + tri->verts[i].normal * dist;
721  }
722 
723  R_FinishDeform( surf, newTri, ac );
724 }
725 
726 /*
727 =====================
728 R_MoveDeform
729 
730 Moves the surface along the X axis, mostly just for demoing the deforms
731 =====================
732 */
733 static void R_MoveDeform( drawSurf_t *surf ) {
734  int i;
735  const srfTriangles_t *tri;
736  srfTriangles_t *newTri;
737 
738  tri = surf->geo;
739 
740  // this srfTriangles_t and all its indexes and caches are in frame
741  // memory, and will be automatically disposed of
742  newTri = (srfTriangles_t *)R_ClearedFrameAlloc( sizeof( *newTri ) );
743  newTri->numVerts = tri->numVerts;
744  newTri->numIndexes = tri->numIndexes;
745  newTri->indexes = tri->indexes;
746 
747  idDrawVert *ac = (idDrawVert *)_alloca16( newTri->numVerts * sizeof( idDrawVert ) );
748 
749  float dist = surf->shaderRegisters[ surf->material->GetDeformRegister(0) ];
750  for ( i = 0 ; i < tri->numVerts ; i++ ) {
751  ac[i] = *(idDrawVert *)&tri->verts[i];
752  ac[i].xyz[0] += dist;
753  }
754 
755  R_FinishDeform( surf, newTri, ac );
756 }
757 
758 //=====================================================================================
759 
760 /*
761 =====================
762 R_TurbulentDeform
763 
764 Turbulently deforms the XYZ, S, and T values
765 =====================
766 */
767 static void R_TurbulentDeform( drawSurf_t *surf ) {
768  int i;
769  const srfTriangles_t *tri;
770  srfTriangles_t *newTri;
771 
772  tri = surf->geo;
773 
774  // this srfTriangles_t and all its indexes and caches are in frame
775  // memory, and will be automatically disposed of
776  newTri = (srfTriangles_t *)R_ClearedFrameAlloc( sizeof( *newTri ) );
777  newTri->numVerts = tri->numVerts;
778  newTri->numIndexes = tri->numIndexes;
779  newTri->indexes = tri->indexes;
780 
781  idDrawVert *ac = (idDrawVert *)_alloca16( newTri->numVerts * sizeof( idDrawVert ) );
782 
784  float range = surf->shaderRegisters[ surf->material->GetDeformRegister(0) ];
785  float timeOfs = surf->shaderRegisters[ surf->material->GetDeformRegister(1) ];
786  float domain = surf->shaderRegisters[ surf->material->GetDeformRegister(2) ];
787  float tOfs = 0.5;
788 
789  for ( i = 0 ; i < tri->numVerts ; i++ ) {
790  float f = tri->verts[i].xyz[0] * 0.003 + tri->verts[i].xyz[1] * 0.007 + tri->verts[i].xyz[2] * 0.011;
791 
792  f = timeOfs + domain * f;
793  f += timeOfs;
794 
795  ac[i] = *(idDrawVert *)&tri->verts[i];
796 
797  ac[i].st[0] += range * table->TableLookup( f );
798  ac[i].st[1] += range * table->TableLookup( f + tOfs );
799  }
800 
801  R_FinishDeform( surf, newTri, ac );
802 }
803 
804 //=====================================================================================
805 
806 /*
807 =====================
808 AddTriangleToIsland_r
809 
810 =====================
811 */
812 #define MAX_EYEBALL_TRIS 10
813 #define MAX_EYEBALL_ISLANDS 6
814 
815 typedef struct {
816  int tris[MAX_EYEBALL_TRIS];
817  int numTris;
820 } eyeIsland_t;
821 
822 static void AddTriangleToIsland_r( const srfTriangles_t *tri, int triangleNum, bool *usedList, eyeIsland_t *island ) {
823  int a, b, c;
824 
825  usedList[triangleNum] = true;
826 
827  // add to the current island
828  if ( island->numTris == MAX_EYEBALL_TRIS ) {
829  common->Error( "MAX_EYEBALL_TRIS" );
830  }
831  island->tris[island->numTris] = triangleNum;
832  island->numTris++;
833 
834  // recurse into all neighbors
835  a = tri->indexes[triangleNum*3];
836  b = tri->indexes[triangleNum*3+1];
837  c = tri->indexes[triangleNum*3+2];
838 
839  island->bounds.AddPoint( tri->verts[a].xyz );
840  island->bounds.AddPoint( tri->verts[b].xyz );
841  island->bounds.AddPoint( tri->verts[c].xyz );
842 
843  int numTri = tri->numIndexes / 3;
844  for ( int i = 0 ; i < numTri ; i++ ) {
845  if ( usedList[i] ) {
846  continue;
847  }
848  if ( tri->indexes[i*3+0] == a
849  || tri->indexes[i*3+1] == a
850  || tri->indexes[i*3+2] == a
851  || tri->indexes[i*3+0] == b
852  || tri->indexes[i*3+1] == b
853  || tri->indexes[i*3+2] == b
854  || tri->indexes[i*3+0] == c
855  || tri->indexes[i*3+1] == c
856  || tri->indexes[i*3+2] == c ) {
857  AddTriangleToIsland_r( tri, i, usedList, island );
858  }
859  }
860 }
861 
862 /*
863 =====================
864 R_EyeballDeform
865 
866 Each eyeball surface should have an separate upright triangle behind it, long end
867 pointing out the eye, and another single triangle in front of the eye for the focus point.
868 =====================
869 */
870 static void R_EyeballDeform( drawSurf_t *surf ) {
871  int i, j, k;
872  const srfTriangles_t *tri;
873  srfTriangles_t *newTri;
875  int numIslands;
877 
878  tri = surf->geo;
879 
880  // separate all the triangles into islands
881  int numTri = tri->numIndexes / 3;
882  if ( numTri > MAX_EYEBALL_ISLANDS*MAX_EYEBALL_TRIS ) {
883  common->Printf( "R_EyeballDeform: too many triangles in surface" );
884  return;
885  }
886  memset( triUsed, 0, sizeof( triUsed ) );
887 
888  for ( numIslands = 0 ; numIslands < MAX_EYEBALL_ISLANDS ; numIslands++ ) {
889  islands[numIslands].numTris = 0;
890  islands[numIslands].bounds.Clear();
891  for ( i = 0 ; i < numTri ; i++ ) {
892  if ( !triUsed[i] ) {
893  AddTriangleToIsland_r( tri, i, triUsed, &islands[numIslands] );
894  break;
895  }
896  }
897  if ( i == numTri ) {
898  break;
899  }
900  }
901 
902  // assume we always have two eyes, two origins, and two targets
903  if ( numIslands != 3 ) {
904  common->Printf( "R_EyeballDeform: %i triangle islands\n", numIslands );
905  return;
906  }
907 
908  // this srfTriangles_t and all its indexes and caches are in frame
909  // memory, and will be automatically disposed of
910 
911  // the surface cannot have more indexes or verts than the original
912  newTri = (srfTriangles_t *)R_ClearedFrameAlloc( sizeof( *newTri ) );
913  memset( newTri, 0, sizeof( *newTri ) );
914  newTri->numVerts = tri->numVerts;
915  newTri->numIndexes = tri->numIndexes;
916  newTri->indexes = (glIndex_t *)R_FrameAlloc( tri->numIndexes * sizeof( newTri->indexes[0] ) );
917  idDrawVert *ac = (idDrawVert *)_alloca16( tri->numVerts * sizeof( idDrawVert ) );
918 
919  newTri->numIndexes = 0;
920 
921  // decide which islands are the eyes and points
922  for ( i = 0 ; i < numIslands ; i++ ) {
923  islands[i].mid = islands[i].bounds.GetCenter();
924  }
925 
926  for ( i = 0 ; i < numIslands ; i++ ) {
927  eyeIsland_t *island = &islands[i];
928 
929  if ( island->numTris == 1 ) {
930  continue;
931  }
932 
933  // the closest single triangle point will be the eye origin
934  // and the next-to-farthest will be the focal point
935  idVec3 origin, focus;
936  int originIsland = 0;
937  float dist[MAX_EYEBALL_ISLANDS];
938  int sortOrder[MAX_EYEBALL_ISLANDS];
939 
940  for ( j = 0 ; j < numIslands ; j++ ) {
941  idVec3 dir = islands[j].mid - island->mid;
942  dist[j] = dir.Length();
943  sortOrder[j] = j;
944  for ( k = j-1 ; k >= 0 ; k-- ) {
945  if ( dist[k] > dist[k+1] ) {
946  int temp = sortOrder[k];
947  sortOrder[k] = sortOrder[k+1];
948  sortOrder[k+1] = temp;
949  float ftemp = dist[k];
950  dist[k] = dist[k+1];
951  dist[k+1] = ftemp;
952  }
953  }
954  }
955 
956  originIsland = sortOrder[1];
957  origin = islands[originIsland].mid;
958 
959  focus = islands[sortOrder[2]].mid;
960 
961  // determine the projection directions based on the origin island triangle
962  idVec3 dir = focus - origin;
963  dir.Normalize();
964 
965  const idVec3 &p1 = tri->verts[tri->indexes[islands[originIsland].tris[0]+0]].xyz;
966  const idVec3 &p2 = tri->verts[tri->indexes[islands[originIsland].tris[0]+1]].xyz;
967  const idVec3 &p3 = tri->verts[tri->indexes[islands[originIsland].tris[0]+2]].xyz;
968 
969  idVec3 v1 = p2 - p1;
970  v1.Normalize();
971  idVec3 v2 = p3 - p1;
972  v2.Normalize();
973 
974  // texVec[0] will be the normal to the origin triangle
975  idVec3 texVec[2];
976 
977  texVec[0].Cross( v1, v2 );
978 
979  texVec[1].Cross( texVec[0], dir );
980 
981  for ( j = 0 ; j < 2 ; j++ ) {
982  texVec[j] -= dir * ( texVec[j] * dir );
983  texVec[j].Normalize();
984  }
985 
986  // emit these triangles, generating the projected texcoords
987 
988  for ( j = 0 ; j < islands[i].numTris ; j++ ) {
989  for ( k = 0 ; k < 3 ; k++ ) {
990  int index = islands[i].tris[j] * 3;
991 
992  index = tri->indexes[index+k];
993  newTri->indexes[newTri->numIndexes++] = index;
994 
995  ac[index].xyz = tri->verts[index].xyz;
996 
997  idVec3 local = tri->verts[index].xyz - origin;
998 
999  ac[index].st[0] = 0.5 + local * texVec[0];
1000  ac[index].st[1] = 0.5 + local * texVec[1];
1001  }
1002  }
1003  }
1004 
1005  R_FinishDeform( surf, newTri, ac );
1006 }
1007 
1008 //==========================================================================================
1009 
1010 
1011 /*
1012 =====================
1013 R_ParticleDeform
1014 
1015 Emit particles from the surface instead of drawing it
1016 =====================
1017 */
1018 static void R_ParticleDeform( drawSurf_t *surf, bool useArea ) {
1019  const struct renderEntity_s *renderEntity = &surf->space->entityDef->parms;
1020  const struct viewDef_s *viewDef = tr.viewDef;
1021  const idDeclParticle *particleSystem = (idDeclParticle *)surf->material->GetDeformDecl();
1022 
1023  if ( r_skipParticles.GetBool() ) {
1024  return;
1025  }
1026 
1027 #if 0
1028  if ( renderEntity->shaderParms[SHADERPARM_PARTICLE_STOPTIME] &&
1029  viewDef->renderView.time*0.001 >= renderEntity->shaderParms[SHADERPARM_PARTICLE_STOPTIME] ) {
1030  // the entire system has faded out
1031  return NULL;
1032  }
1033 #endif
1034 
1035  //
1036  // calculate the area of all the triangles
1037  //
1038  int numSourceTris = surf->geo->numIndexes / 3;
1039  float totalArea = 0;
1040  float *sourceTriAreas = NULL;
1041  const srfTriangles_t *srcTri = surf->geo;
1042 
1043  if ( useArea ) {
1044  sourceTriAreas = (float *)_alloca( sizeof( *sourceTriAreas ) * numSourceTris );
1045  int triNum = 0;
1046  for ( int i = 0 ; i < srcTri->numIndexes ; i += 3, triNum++ ) {
1047  float area;
1048  area = idWinding::TriangleArea( srcTri->verts[srcTri->indexes[i]].xyz, srcTri->verts[srcTri->indexes[i+1]].xyz, srcTri->verts[srcTri->indexes[i+2]].xyz );
1049  sourceTriAreas[triNum] = totalArea;
1050  totalArea += area;
1051  }
1052  }
1053 
1054  //
1055  // create the particles almost exactly the way idRenderModelPrt does
1056  //
1057  particleGen_t g;
1058 
1059  g.renderEnt = renderEntity;
1060  g.renderView = &viewDef->renderView;
1061  g.origin.Zero();
1062  g.axis = mat3_identity;
1063 
1064  for ( int currentTri = 0; currentTri < ( ( useArea ) ? 1 : numSourceTris ); currentTri++ ) {
1065 
1066  for ( int stageNum = 0 ; stageNum < particleSystem->stages.Num() ; stageNum++ ) {
1067  idParticleStage *stage = particleSystem->stages[stageNum];
1068 
1069  if ( !stage->material ) {
1070  continue;
1071  }
1072  if ( !stage->cycleMsec ) {
1073  continue;
1074  }
1075  if ( stage->hidden ) { // just for gui particle editor use
1076  continue;
1077  }
1078 
1079  // we interpret stage->totalParticles as "particles per map square area"
1080  // so the systems look the same on different size surfaces
1081  int totalParticles = ( useArea ) ? stage->totalParticles * totalArea / 4096.0 : ( stage->totalParticles );
1082 
1083  int count = totalParticles * stage->NumQuadsPerParticle();
1084 
1085  // allocate a srfTriangles in temp memory that can hold all the particles
1086  srfTriangles_t *tri;
1087 
1088  tri = (srfTriangles_t *)R_ClearedFrameAlloc( sizeof( *tri ) );
1089  tri->numVerts = 4 * count;
1090  tri->numIndexes = 6 * count;
1091  tri->verts = (idDrawVert *)R_FrameAlloc( tri->numVerts * sizeof( tri->verts[0] ) );
1092  tri->indexes = (glIndex_t *)R_FrameAlloc( tri->numIndexes * sizeof( tri->indexes[0] ) );
1093 
1094  // just always draw the particles
1095  tri->bounds = stage->bounds;
1096 
1097  tri->numVerts = 0;
1098 
1099  idRandom steppingRandom, steppingRandom2;
1100 
1101  int stageAge = g.renderView->time + renderEntity->shaderParms[SHADERPARM_TIMEOFFSET] * 1000 - stage->timeOffset * 1000;
1102  int stageCycle = stageAge / stage->cycleMsec;
1103  int inCycleTime = stageAge - stageCycle * stage->cycleMsec;
1104 
1105  // some particles will be in this cycle, some will be in the previous cycle
1106  steppingRandom.SetSeed( (( stageCycle << 10 ) & idRandom::MAX_RAND) ^ (int)( renderEntity->shaderParms[SHADERPARM_DIVERSITY] * idRandom::MAX_RAND ) );
1107  steppingRandom2.SetSeed( (( (stageCycle-1) << 10 ) & idRandom::MAX_RAND) ^ (int)( renderEntity->shaderParms[SHADERPARM_DIVERSITY] * idRandom::MAX_RAND ) );
1108 
1109  for ( int index = 0 ; index < totalParticles ; index++ ) {
1110  g.index = index;
1111 
1112  // bump the random
1113  steppingRandom.RandomInt();
1114  steppingRandom2.RandomInt();
1115 
1116  // calculate local age for this index
1117  int bunchOffset = stage->particleLife * 1000 * stage->spawnBunching * index / totalParticles;
1118 
1119  int particleAge = stageAge - bunchOffset;
1120  int particleCycle = particleAge / stage->cycleMsec;
1121  if ( particleCycle < 0 ) {
1122  // before the particleSystem spawned
1123  continue;
1124  }
1125  if ( stage->cycles && particleCycle >= stage->cycles ) {
1126  // cycled systems will only run cycle times
1127  continue;
1128  }
1129 
1130  if ( particleCycle == stageCycle ) {
1131  g.random = steppingRandom;
1132  } else {
1133  g.random = steppingRandom2;
1134  }
1135 
1136  int inCycleTime = particleAge - particleCycle * stage->cycleMsec;
1137 
1138  if ( renderEntity->shaderParms[SHADERPARM_PARTICLE_STOPTIME] &&
1139  g.renderView->time - inCycleTime >= renderEntity->shaderParms[SHADERPARM_PARTICLE_STOPTIME]*1000 ) {
1140  // don't fire any more particles
1141  continue;
1142  }
1143 
1144  // supress particles before or after the age clamp
1145  g.frac = (float)inCycleTime / ( stage->particleLife * 1000 );
1146  if ( g.frac < 0 ) {
1147  // yet to be spawned
1148  continue;
1149  }
1150  if ( g.frac > 1.0 ) {
1151  // this particle is in the deadTime band
1152  continue;
1153  }
1154 
1155  //---------------
1156  // locate the particle origin and axis somewhere on the surface
1157  //---------------
1158 
1159  int pointTri = currentTri;
1160 
1161  if ( useArea ) {
1162  // select a triangle based on an even area distribution
1163  pointTri = idBinSearch_LessEqual<float>( sourceTriAreas, numSourceTris, g.random.RandomFloat() * totalArea );
1164  }
1165 
1166  // now pick a random point inside pointTri
1167  const idDrawVert *v1 = &srcTri->verts[ srcTri->indexes[ pointTri * 3 + 0 ] ];
1168  const idDrawVert *v2 = &srcTri->verts[ srcTri->indexes[ pointTri * 3 + 1 ] ];
1169  const idDrawVert *v3 = &srcTri->verts[ srcTri->indexes[ pointTri * 3 + 2 ] ];
1170 
1171  float f1 = g.random.RandomFloat();
1172  float f2 = g.random.RandomFloat();
1173  float f3 = g.random.RandomFloat();
1174 
1175  float ft = 1.0f / ( f1 + f2 + f3 + 0.0001f );
1176 
1177  f1 *= ft;
1178  f2 *= ft;
1179  f3 *= ft;
1180 
1181  g.origin = v1->xyz * f1 + v2->xyz * f2 + v3->xyz * f3;
1182  g.axis[0] = v1->tangents[0] * f1 + v2->tangents[0] * f2 + v3->tangents[0] * f3;
1183  g.axis[1] = v1->tangents[1] * f1 + v2->tangents[1] * f2 + v3->tangents[1] * f3;
1184  g.axis[2] = v1->normal * f1 + v2->normal * f2 + v3->normal * f3;
1185 
1186  //-----------------------
1187 
1188  // this is needed so aimed particles can calculate origins at different times
1189  g.originalRandom = g.random;
1190 
1191  g.age = g.frac * stage->particleLife;
1192 
1193  // if the particle doesn't get drawn because it is faded out or beyond a kill region,
1194  // don't increment the verts
1195  tri->numVerts += stage->CreateParticle( &g, tri->verts + tri->numVerts );
1196  }
1197 
1198  if ( tri->numVerts > 0 ) {
1199  // build the index list
1200  int indexes = 0;
1201  for ( int i = 0 ; i < tri->numVerts ; i += 4 ) {
1202  tri->indexes[indexes+0] = i;
1203  tri->indexes[indexes+1] = i+2;
1204  tri->indexes[indexes+2] = i+3;
1205  tri->indexes[indexes+3] = i;
1206  tri->indexes[indexes+4] = i+3;
1207  tri->indexes[indexes+5] = i+1;
1208  indexes += 6;
1209  }
1210  tri->numIndexes = indexes;
1211  tri->ambientCache = vertexCache.AllocFrameTemp( tri->verts, tri->numVerts * sizeof( idDrawVert ) );
1212  if ( tri->ambientCache ) {
1213  // add the drawsurf
1214  R_AddDrawSurf( tri, surf->space, renderEntity, stage->material, surf->scissorRect );
1215  }
1216  }
1217  }
1218  }
1219 }
1220 
1221 //========================================================================================
1222 
1223 /*
1224 =================
1225 R_DeformDrawSurf
1226 =================
1227 */
1228 void R_DeformDrawSurf( drawSurf_t *drawSurf ) {
1229  if ( !drawSurf->material ) {
1230  return;
1231  }
1232 
1233  if ( r_skipDeforms.GetBool() ) {
1234  return;
1235  }
1236  switch ( drawSurf->material->Deform() ) {
1237  case DFRM_NONE:
1238  return;
1239  case DFRM_SPRITE:
1240  R_AutospriteDeform( drawSurf );
1241  break;
1242  case DFRM_TUBE:
1243  R_TubeDeform( drawSurf );
1244  break;
1245  case DFRM_FLARE:
1246  R_FlareDeform( drawSurf );
1247  break;
1248  case DFRM_EXPAND:
1249  R_ExpandDeform( drawSurf );
1250  break;
1251  case DFRM_MOVE:
1252  R_MoveDeform( drawSurf );
1253  break;
1254  case DFRM_TURB:
1255  R_TurbulentDeform( drawSurf );
1256  break;
1257  case DFRM_EYEBALL:
1258  R_EyeballDeform( drawSurf );
1259  break;
1260  case DFRM_PARTICLE:
1261  R_ParticleDeform( drawSurf, true );
1262  break;
1263  case DFRM_PARTICLE2:
1264  R_ParticleDeform( drawSurf, false );
1265  break;
1266  }
1267 }
GLubyte g
Definition: glext.h:4662
byte color[4]
Definition: MegaTexture.cpp:54
idCVar r_skipParticles("r_skipParticles","0", CVAR_RENDERER|CVAR_INTEGER,"1 = skip all particle systems", 0, 1, idCmdSystem::ArgCompletion_Integer< 0, 1 >)
const srfTriangles_t * geo
Definition: tr_local.h:112
float Normalize(void)
Definition: Vector.h:646
bool FromPoints(const idVec3 &p1, const idVec3 &p2, const idVec3 &p3, bool fixDegenerate=true)
Definition: Plane.h:279
const idVec3 & Normal(void) const
Definition: Plane.h:239
const int SHADERPARM_DIVERSITY
Definition: RenderWorld.h:52
idMat3 mat3_identity(idVec3(1, 0, 0), idVec3(0, 1, 0), idVec3(0, 0, 1))
idVec3 GetCenter(void) const
Definition: Bounds.h:211
int numVerts
Definition: Model.h:98
void R_AddDrawSurf(const srfTriangles_t *tri, const viewEntity_t *space, const renderEntity_t *renderEntity, const idMaterial *shader, const idScreenRect &scissor)
Definition: tr_light.cpp:1183
bool ReceivesLighting(void) const
Definition: Material.h:401
float GetFloat(void) const
Definition: CVarSystem.h:144
const GLdouble * v
Definition: glext.h:2936
#define MAX_EYEBALL_TRIS
Definition: tr_deform.cpp:812
idVec3 xyz
Definition: DrawVert.h:42
case const int
Definition: Callbacks.cpp:52
idVec3 tangents[2]
Definition: DrawVert.h:45
GLenum GLsizei GLenum GLenum const GLvoid * table
Definition: glext.h:2846
deform_t Deform(void) const
Definition: Material.h:516
idScreenRect scissorRect
Definition: tr_local.h:118
Definition: Vector.h:316
case const float
Definition: Callbacks.cpp:62
int R_WindingFromTriangles(const srfTriangles_t *tri, glIndex_t indexes[MAX_TRI_WINDING_INDEXES])
Definition: tr_deform.cpp:286
const renderEntity_t * renderEnt
Definition: DeclParticle.h:86
int tris[MAX_EYEBALL_TRIS]
Definition: tr_deform.cpp:816
void Clear(void)
Definition: Bounds.h:201
static const int MAX_RAND
Definition: Random.h:52
void R_DeriveTangents(srfTriangles_t *tri, bool allocFacePlanes=true)
GLenum GLsizei len
Definition: glext.h:3472
idVec3 Cross(const idVec3 &a) const
Definition: Vector.h:619
const struct viewEntity_s * space
Definition: tr_local.h:113
idVec3 mid
Definition: tr_deform.cpp:819
struct vertCache_s * ambientCache
Definition: Model.h:137
int i
Definition: process.py:33
const idMaterial * material
Definition: tr_local.h:114
GLsizei range
Definition: glext.h:4368
void * R_ClearedFrameAlloc(int bytes)
Definition: tr_main.cpp:417
list l
Definition: prepare.py:17
idRandom originalRandom
Definition: DeclParticle.h:96
bool AddPoint(const idVec3 &v)
Definition: Bounds.h:226
GLfloat GLfloat GLfloat v2
Definition: glext.h:3608
idVec2 st
Definition: DrawVert.h:43
int RandomInt(void)
Definition: Random.h:70
GLuint GLuint GLsizei count
Definition: glext.h:2845
void SetSeed(int seed)
Definition: Random.h:62
GLuint index
Definition: glext.h:3476
const GLubyte * c
Definition: glext.h:4677
float Length(void) const
Definition: Vector.h:631
float RandomFloat(void)
Definition: Random.h:82
idVec3 vec3_origin(0.0f, 0.0f, 0.0f)
idBounds bounds
Definition: Model.h:87
renderView_t renderView
Definition: tr_local.h:370
idCommon * common
Definition: Common.cpp:206
static float TriangleArea(const idVec3 &a, const idVec3 &b, const idVec3 &c)
Definition: Winding.cpp:1446
#define NULL
Definition: Lib.h:88
virtual int CreateParticle(particleGen_t *g, idDrawVert *verts) const
int glIndex_t
Definition: Model.h:52
const renderView_t * renderView
Definition: DeclParticle.h:87
idCVar r_flareSize("r_flareSize","1", CVAR_RENDERER|CVAR_FLOAT,"scale the flare deforms from the material def")
Definition: Plane.h:71
const struct portalStack_s * next
const idMaterial * material
Definition: DeclParticle.h:128
idVec3 normal
Definition: DrawVert.h:44
bool isMirror
Definition: tr_local.h:390
void R_GlobalVectorToLocal(const float modelMatrix[16], const idVec3 &in, idVec3 &out)
Definition: tr_main.cpp:541
idRenderEntityLocal * entityDef
Definition: tr_local.h:348
const int SHADERPARM_TIMEOFFSET
Definition: RenderWorld.h:51
GLubyte GLubyte GLubyte a
Definition: glext.h:4662
virtual void Printf(const char *fmt,...) id_attribute((format(printf
idList< idParticleStage * > stages
Definition: DeclParticle.h:204
float modelMatrix[16]
Definition: tr_local.h:360
vertCache_t * AllocFrameTemp(void *data, int bytes)
#define MAX_EYEBALL_ISLANDS
Definition: tr_deform.cpp:813
GLfloat GLfloat v1
Definition: glext.h:3607
GLubyte GLubyte b
Definition: glext.h:4662
idRandom random
Definition: DeclParticle.h:90
void R_GlobalPointToLocal(const float modelMatrix[16], const idVec3 &in, idVec3 &out)
Definition: tr_main.cpp:522
idVec3 vieworg
Definition: RenderWorld.h:215
viewDef_t * viewDef
Definition: tr_local.h:786
GLfloat GLfloat GLfloat GLfloat v3
Definition: glext.h:3609
#define MAX_TRI_WINDING_INDEXES
Definition: tr_deform.cpp:285
bool GetBool(void) const
Definition: CVarSystem.h:142
tuple f
Definition: idal.py:89
GLint GLint i2
Definition: qgl.h:261
int Num(void) const
Definition: List.h:265
idCVar r_skipDeforms("r_skipDeforms","0", CVAR_RENDERER|CVAR_BOOL,"leave all deform materials in their original state")
byte color[4]
Definition: DrawVert.h:46
const int GetDeformRegister(int index) const
Definition: Material.h:519
GLint i1
Definition: qgl.h:261
void * R_FrameAlloc(int bytes)
Definition: tr_main.cpp:365
glIndex_t * indexes
Definition: Model.h:102
idVertexCache vertexCache
Definition: VertexCache.cpp:41
idRenderSystemLocal tr
const idDecl * GetDeformDecl(void) const
Definition: Material.h:522
GLint j
Definition: qgl.h:264
float dot(float a[], float b[])
Definition: Model_lwo.cpp:3883
int numIndexes
Definition: Model.h:101
renderEntity_t parms
Definition: tr_local.h:251
virtual void Error(const char *fmt,...) id_attribute((format(printf
idMat3 viewaxis
Definition: RenderWorld.h:216
void R_DeformDrawSurf(drawSurf_t *drawSurf)
Definition: tr_deform.cpp:1228
void Zero(void)
Definition: Vector.h:415
virtual void virtual void Warning(const char *fmt,...) id_attribute((format(printf
float shaderParms[MAX_ENTITY_SHADER_PARMS]
Definition: RenderWorld.h:127
idBounds bounds
Definition: tr_deform.cpp:818
const float * shaderRegisters
Definition: tr_local.h:116
virtual int NumQuadsPerParticle() const
idDrawVert * verts
Definition: Model.h:99
const int SHADERPARM_PARTICLE_STOPTIME
Definition: RenderWorld.h:71
float TableLookup(float index) const
Definition: DeclTable.cpp:38