doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
CollisionModel_debug.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 /*
30 ===============================================================================
31 
32  Trace model vs. polygonal model collision detection.
33 
34 ===============================================================================
35 */
36 
37 #include "../idlib/precompiled.h"
38 #pragma hdrstop
39 
40 #include "CollisionModel_local.h"
41 
42 
43 /*
44 ===============================================================================
45 
46 Visualisation code
47 
48 ===============================================================================
49 */
50 
51 const char *cm_contentsNameByIndex[] = {
52  "none", // 0
53  "solid", // 1
54  "opaque", // 2
55  "water", // 3
56  "playerclip", // 4
57  "monsterclip", // 5
58  "moveableclip", // 6
59  "ikclip", // 7
60  "blood", // 8
61  "body", // 9
62  "corpse", // 10
63  "trigger", // 11
64  "aas_solid", // 12
65  "aas_obstacle", // 13
66  "flashlight_trigger", // 14
67  NULL
68 };
69 
71  -1, // 0
72  CONTENTS_SOLID, // 1
73  CONTENTS_OPAQUE, // 2
74  CONTENTS_WATER, // 3
78  CONTENTS_IKCLIP, // 7
79  CONTENTS_BLOOD, // 8
80  CONTENTS_BODY, // 9
81  CONTENTS_CORPSE, // 10
82  CONTENTS_TRIGGER, // 11
83  CONTENTS_AAS_SOLID, // 12
86  0
87 };
88 
89 idCVar cm_drawMask( "cm_drawMask", "none", CVAR_GAME, "collision mask", cm_contentsNameByIndex, idCmdSystem::ArgCompletion_String<cm_contentsNameByIndex> );
90 idCVar cm_drawColor( "cm_drawColor", "1 0 0 .5", CVAR_GAME, "color used to draw the collision models" );
91 idCVar cm_drawFilled( "cm_drawFilled", "0", CVAR_GAME | CVAR_BOOL, "draw filled polygons" );
92 idCVar cm_drawInternal( "cm_drawInternal", "1", CVAR_GAME | CVAR_BOOL, "draw internal edges green" );
93 idCVar cm_drawNormals( "cm_drawNormals", "0", CVAR_GAME | CVAR_BOOL, "draw polygon and edge normals" );
94 idCVar cm_backFaceCull( "cm_backFaceCull", "0", CVAR_GAME | CVAR_BOOL, "cull back facing polygons" );
95 idCVar cm_debugCollision( "cm_debugCollision", "0", CVAR_GAME | CVAR_BOOL, "debug the collision detection" );
96 
97 static idVec4 cm_color;
98 
99 /*
100 ================
101 idCollisionModelManagerLocal::ContentsFromString
102 ================
103 */
104 int idCollisionModelManagerLocal::ContentsFromString( const char *string ) const {
105  int i, contents = 0;
106  idLexer src( string, idStr::Length( string ), "ContentsFromString" );
107  idToken token;
108 
109  while( src.ReadToken( &token ) ) {
110  if ( token == "," ) {
111  continue;
112  }
113  for ( i = 1; cm_contentsNameByIndex[i] != NULL; i++ ) {
114  if ( token.Icmp( cm_contentsNameByIndex[i] ) == 0 ) {
115  contents |= cm_contentsFlagByIndex[i];
116  break;
117  }
118  }
119  }
120 
121  return contents;
122 }
123 
124 /*
125 ================
126 idCollisionModelManagerLocal::StringFromContents
127 ================
128 */
129 const char *idCollisionModelManagerLocal::StringFromContents( const int contents ) const {
130  int i, length = 0;
131  static char contentsString[MAX_STRING_CHARS];
132 
133  contentsString[0] = '\0';
134 
135  for ( i = 1; cm_contentsFlagByIndex[i] != 0; i++ ) {
136  if ( contents & cm_contentsFlagByIndex[i] ) {
137  if ( length != 0 ) {
138  length += idStr::snPrintf( contentsString + length, sizeof( contentsString ) - length, "," );
139  }
140  length += idStr::snPrintf( contentsString + length, sizeof( contentsString ) - length, cm_contentsNameByIndex[i] );
141  }
142  }
143 
144  return contentsString;
145 }
146 
147 /*
148 ================
149 idCollisionModelManagerLocal::DrawEdge
150 ================
151 */
152 void idCollisionModelManagerLocal::DrawEdge( cm_model_t *model, int edgeNum, const idVec3 &origin, const idMat3 &axis ) {
153  int side;
154  cm_edge_t *edge;
155  idVec3 start, end, mid;
156  bool isRotated;
157 
158  isRotated = axis.IsRotated();
159 
160  edge = model->edges + abs(edgeNum);
161  side = edgeNum < 0;
162 
163  start = model->vertices[edge->vertexNum[side]].p;
164  end = model->vertices[edge->vertexNum[!side]].p;
165  if ( isRotated ) {
166  start *= axis;
167  end *= axis;
168  }
169  start += origin;
170  end += origin;
171 
172  if ( edge->internal ) {
173  if ( cm_drawInternal.GetBool() ) {
174  session->rw->DebugArrow( colorGreen, start, end, 1 );
175  }
176  } else {
177  if ( edge->numUsers > 2 ) {
178  session->rw->DebugArrow( colorBlue, start, end, 1 );
179  } else {
180  session->rw->DebugArrow( cm_color, start, end, 1 );
181  }
182  }
183 
184  if ( cm_drawNormals.GetBool() ) {
185  mid = (start + end) * 0.5f;
186  if ( isRotated ) {
187  end = mid + 5 * (axis * edge->normal);
188  } else {
189  end = mid + 5 * edge->normal;
190  }
191  session->rw->DebugArrow( colorCyan, mid, end, 1 );
192  }
193 }
194 
195 /*
196 ================
197 idCollisionModelManagerLocal::DrawPolygon
198 ================
199 */
200 void idCollisionModelManagerLocal::DrawPolygon( cm_model_t *model, cm_polygon_t *p, const idVec3 &origin, const idMat3 &axis, const idVec3 &viewOrigin ) {
201  int i, edgeNum;
202  cm_edge_t *edge;
203  idVec3 center, end, dir;
204 
205  if ( cm_backFaceCull.GetBool() ) {
206  edgeNum = p->edges[0];
207  edge = model->edges + abs(edgeNum);
208  dir = model->vertices[edge->vertexNum[0]].p - viewOrigin;
209  if ( dir * p->plane.Normal() > 0.0f ) {
210  return;
211  }
212  }
213 
214  if ( cm_drawNormals.GetBool() ) {
215  center = vec3_origin;
216  for ( i = 0; i < p->numEdges; i++ ) {
217  edgeNum = p->edges[i];
218  edge = model->edges + abs(edgeNum);
219  center += model->vertices[edge->vertexNum[edgeNum < 0]].p;
220  }
221  center *= (1.0f / p->numEdges);
222  if ( axis.IsRotated() ) {
223  center = center * axis + origin;
224  end = center + 5 * (axis * p->plane.Normal());
225  } else {
226  center += origin;
227  end = center + 5 * p->plane.Normal();
228  }
229  session->rw->DebugArrow( colorMagenta, center, end, 1 );
230  }
231 
232  if ( cm_drawFilled.GetBool() ) {
233  idFixedWinding winding;
234  for ( i = p->numEdges - 1; i >= 0; i-- ) {
235  edgeNum = p->edges[i];
236  edge = model->edges + abs(edgeNum);
237  winding += origin + model->vertices[edge->vertexNum[INTSIGNBITSET(edgeNum)]].p * axis;
238  }
239  session->rw->DebugPolygon( cm_color, winding );
240  } else {
241  for ( i = 0; i < p->numEdges; i++ ) {
242  edgeNum = p->edges[i];
243  edge = model->edges + abs(edgeNum);
244  if ( edge->checkcount == checkCount ) {
245  continue;
246  }
247  edge->checkcount = checkCount;
248  DrawEdge( model, edgeNum, origin, axis );
249  }
250  }
251 }
252 
253 /*
254 ================
255 idCollisionModelManagerLocal::DrawNodePolygons
256 ================
257 */
259  const idVec3 &origin, const idMat3 &axis,
260  const idVec3 &viewOrigin, const float radius ) {
261  int i;
262  cm_polygon_t *p;
263  cm_polygonRef_t *pref;
264 
265  while (1) {
266  for ( pref = node->polygons; pref; pref = pref->next ) {
267  p = pref->p;
268  if ( radius ) {
269  // polygon bounds should overlap with trace bounds
270  for ( i = 0; i < 3; i++ ) {
271  if ( p->bounds[0][i] > viewOrigin[i] + radius ) {
272  break;
273  }
274  if ( p->bounds[1][i] < viewOrigin[i] - radius ) {
275  break;
276  }
277  }
278  if ( i < 3 ) {
279  continue;
280  }
281  }
282  if ( p->checkcount == checkCount ) {
283  continue;
284  }
286  continue;
287  }
288 
289  DrawPolygon( model, p, origin, axis, viewOrigin );
290  p->checkcount = checkCount;
291  }
292  if ( node->planeType == -1 ) {
293  break;
294  }
295  if ( radius && viewOrigin[node->planeType] > node->planeDist + radius ) {
296  node = node->children[0];
297  } else if ( radius && viewOrigin[node->planeType] < node->planeDist - radius ) {
298  node = node->children[1];
299  } else {
300  DrawNodePolygons( model, node->children[1], origin, axis, viewOrigin, radius );
301  node = node->children[0];
302  }
303  }
304 }
305 
306 /*
307 ================
308 idCollisionModelManagerLocal::DrawModel
309 ================
310 */
311 void idCollisionModelManagerLocal::DrawModel( cmHandle_t handle, const idVec3 &modelOrigin, const idMat3 &modelAxis,
312  const idVec3 &viewOrigin, const float radius ) {
313 
314  cm_model_t *model;
315  idVec3 viewPos;
316 
317  if ( handle < 0 && handle >= numModels ) {
318  return;
319  }
320 
321  if ( cm_drawColor.IsModified() ) {
322  sscanf( cm_drawColor.GetString(), "%f %f %f %f", &cm_color.x, &cm_color.y, &cm_color.z, &cm_color.w );
324  }
325 
326  model = models[ handle ];
327  viewPos = (viewOrigin - modelOrigin) * modelAxis.Transpose();
328  checkCount++;
329  DrawNodePolygons( model, model->node, modelOrigin, modelAxis, viewPos, radius );
330 }
331 
332 /*
333 ===============================================================================
334 
335 Speed test code
336 
337 ===============================================================================
338 */
339 
340 static idCVar cm_testCollision( "cm_testCollision", "0", CVAR_GAME | CVAR_BOOL, "" );
341 static idCVar cm_testRotation( "cm_testRotation", "1", CVAR_GAME | CVAR_BOOL, "" );
342 static idCVar cm_testModel( "cm_testModel", "0", CVAR_GAME | CVAR_INTEGER, "" );
343 static idCVar cm_testTimes( "cm_testTimes", "1000", CVAR_GAME | CVAR_INTEGER, "" );
344 static idCVar cm_testRandomMany( "cm_testRandomMany", "0", CVAR_GAME | CVAR_BOOL, "" );
345 static idCVar cm_testOrigin( "cm_testOrigin", "0 0 0", CVAR_GAME, "" );
346 static idCVar cm_testReset( "cm_testReset", "0", CVAR_GAME | CVAR_BOOL, "" );
347 static idCVar cm_testBox( "cm_testBox", "-16 -16 0 16 16 64", CVAR_GAME, "" );
348 static idCVar cm_testBoxRotation( "cm_testBoxRotation", "0 0 0", CVAR_GAME, "" );
349 static idCVar cm_testWalk( "cm_testWalk", "1", CVAR_GAME | CVAR_BOOL, "" );
350 static idCVar cm_testLength( "cm_testLength", "1024", CVAR_GAME | CVAR_FLOAT, "" );
351 static idCVar cm_testRadius( "cm_testRadius", "64", CVAR_GAME | CVAR_FLOAT, "" );
352 static idCVar cm_testAngle( "cm_testAngle", "60", CVAR_GAME | CVAR_FLOAT, "" );
353 
354 static int total_translation;
355 static int min_translation = 999999;
356 static int max_translation = -999999;
357 static int num_translation = 0;
358 static int total_rotation;
359 static int min_rotation = 999999;
360 static int max_rotation = -999999;
361 static int num_rotation = 0;
362 static idVec3 start;
363 static idVec3 *testend;
364 
365 #include "../sys/sys_public.h"
366 
368  int i, k, t;
369  char buf[128];
370  idVec3 end;
371  idAngles boxAngles;
372  idMat3 modelAxis, boxAxis;
373  idBounds bounds;
374  trace_t trace;
375 
376  if ( !cm_testCollision.GetBool() ) {
377  return;
378  }
379 
380  testend = (idVec3 *) Mem_Alloc( cm_testTimes.GetInteger() * sizeof(idVec3) );
381 
382  if ( cm_testReset.GetBool() || ( cm_testWalk.GetBool() && !start.Compare( start ) ) ) {
383  total_translation = total_rotation = 0;
384  min_translation = min_rotation = 999999;
385  max_translation = max_rotation = -999999;
386  num_translation = num_rotation = 0;
387  cm_testReset.SetBool( false );
388  }
389 
390  if ( cm_testWalk.GetBool() ) {
391  start = origin;
392  cm_testOrigin.SetString( va( "%1.2f %1.2f %1.2f", start[0], start[1], start[2] ) );
393  } else {
394  sscanf( cm_testOrigin.GetString(), "%f %f %f", &start[0], &start[1], &start[2] );
395  }
396 
397  sscanf( cm_testBox.GetString(), "%f %f %f %f %f %f", &bounds[0][0], &bounds[0][1], &bounds[0][2],
398  &bounds[1][0], &bounds[1][1], &bounds[1][2] );
399  sscanf( cm_testBoxRotation.GetString(), "%f %f %f", &boxAngles[0], &boxAngles[1], &boxAngles[2] );
400  boxAxis = boxAngles.ToMat3();
401  modelAxis.Identity();
402 
403  idTraceModel itm( bounds );
404  idRandom random( 0 );
405  idTimer timer;
406 
407  if ( cm_testRandomMany.GetBool() ) {
408  // if many traces in one random direction
409  for ( i = 0; i < 3; i++ ) {
410  testend[0][i] = start[i] + random.CRandomFloat() * cm_testLength.GetFloat();
411  }
412  for ( k = 1; k < cm_testTimes.GetInteger(); k++ ) {
413  testend[k] = testend[0];
414  }
415  } else {
416  // many traces each in a different random direction
417  for ( k = 0; k < cm_testTimes.GetInteger(); k++ ) {
418  for ( i = 0; i < 3; i++ ) {
419  testend[k][i] = start[i] + random.CRandomFloat() * cm_testLength.GetFloat();
420  }
421  }
422  }
423 
424  // translational collision detection
425  timer.Clear();
426  timer.Start();
427  for ( i = 0; i < cm_testTimes.GetInteger(); i++ ) {
428  Translation( &trace, start, testend[i], &itm, boxAxis, CONTENTS_SOLID|CONTENTS_PLAYERCLIP, cm_testModel.GetInteger(), vec3_origin, modelAxis );
429  }
430  timer.Stop();
431  t = timer.Milliseconds();
432  if ( t < min_translation ) min_translation = t;
433  if ( t > max_translation ) max_translation = t;
434  num_translation++;
435  total_translation += t;
436  if ( cm_testTimes.GetInteger() > 9999 ) {
437  sprintf( buf, "%3dK", (int ) ( cm_testTimes.GetInteger() / 1000 ) );
438  } else {
439  sprintf( buf, "%4d", cm_testTimes.GetInteger() );
440  }
441  common->Printf("%s translations: %4d milliseconds, (min = %d, max = %d, av = %1.1f)\n", buf, t, min_translation, max_translation, (float) total_translation / num_translation );
442 
443  if ( cm_testRandomMany.GetBool() ) {
444  // if many traces in one random direction
445  for ( i = 0; i < 3; i++ ) {
446  testend[0][i] = start[i] + random.CRandomFloat() * cm_testRadius.GetFloat();
447  }
448  for ( k = 1; k < cm_testTimes.GetInteger(); k++ ) {
449  testend[k] = testend[0];
450  }
451  } else {
452  // many traces each in a different random direction
453  for ( k = 0; k < cm_testTimes.GetInteger(); k++ ) {
454  for ( i = 0; i < 3; i++ ) {
455  testend[k][i] = start[i] + random.CRandomFloat() * cm_testRadius.GetFloat();
456  }
457  }
458  }
459 
460  if ( cm_testRotation.GetBool() ) {
461  // rotational collision detection
462  idVec3 vec( random.CRandomFloat(), random.CRandomFloat(), random.RandomFloat() );
463  vec.Normalize();
464  idRotation rotation( vec3_origin, vec, cm_testAngle.GetFloat() );
465 
466  timer.Clear();
467  timer.Start();
468  for ( i = 0; i < cm_testTimes.GetInteger(); i++ ) {
469  rotation.SetOrigin( testend[i] );
470  Rotation( &trace, start, rotation, &itm, boxAxis, CONTENTS_SOLID|CONTENTS_PLAYERCLIP, cm_testModel.GetInteger(), vec3_origin, modelAxis );
471  }
472  timer.Stop();
473  t = timer.Milliseconds();
474  if ( t < min_rotation ) min_rotation = t;
475  if ( t > max_rotation ) max_rotation = t;
476  num_rotation++;
477  total_rotation += t;
478  if ( cm_testTimes.GetInteger() > 9999 ) {
479  sprintf( buf, "%3dK", (int ) ( cm_testTimes.GetInteger() / 1000 ) );
480  } else {
481  sprintf( buf, "%4d", cm_testTimes.GetInteger() );
482  }
483  common->Printf("%s rotation: %4d milliseconds, (min = %d, max = %d, av = %1.1f)\n", buf, t, min_rotation, max_rotation, (float) total_rotation / num_rotation );
484  }
485 
486  Mem_Free( testend );
487  testend = NULL;
488 }
struct cm_node_s * children[2]
static int snPrintf(char *dest, int size, const char *fmt,...) id_attribute((format(printf
Definition: Str.cpp:1465
bool Compare(const idVec3 &a) const
Definition: Vector.h:496
float Normalize(void)
Definition: Vector.h:646
idVec4 colorGreen
Definition: Lib.cpp:118
idCVar cm_drawFilled("cm_drawFilled","0", CVAR_GAME|CVAR_BOOL,"draw filled polygons")
const idVec3 & Normal(void) const
Definition: Plane.h:239
virtual void DebugArrow(const idVec4 &color, const idVec3 &start, const idVec3 &end, int size, const int lifetime=0)=0
unsigned short numUsers
Definition: Timer.h:40
float y
Definition: Vector.h:811
float GetFloat(void) const
Definition: CVarSystem.h:144
idCVar cm_drawNormals("cm_drawNormals","0", CVAR_GAME|CVAR_BOOL,"draw polygon and edge normals")
idMat3 Transpose(void) const
Definition: Matrix.h:677
void Translation(trace_t *results, const idVec3 &start, const idVec3 &end, const idTraceModel *trm, const idMat3 &trmAxis, int contentMask, cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis)
int Length(void) const
Definition: Str.h:702
const char * StringFromContents(const int contents) const
idCVar cm_debugCollision("cm_debugCollision","0", CVAR_GAME|CVAR_BOOL,"debug the collision detection")
float z
Definition: Vector.h:812
struct cm_polygonRef_s * next
idCVar cm_drawColor("cm_drawColor","1 0 0 .5", CVAR_GAME,"color used to draw the collision models")
unsigned short internal
Definition: Vector.h:316
void Start(void)
Definition: Timer.h:144
int cmHandle_t
Definition: Token.h:71
GLuint src
Definition: glext.h:5390
double Milliseconds(void) const
Definition: Timer.h:191
void DrawEdge(cm_model_t *model, int edgeNum, const idVec3 &origin, const idMat3 &axis)
void Identity(void)
Definition: Matrix.h:591
bool IsRotated(void) const
Definition: Matrix.h:624
int i
Definition: process.py:33
int Icmp(const char *text) const
Definition: Str.h:667
int cm_contentsFlagByIndex[]
const char * cm_contentsNameByIndex[]
Definition: Lexer.h:137
idRenderWorld * rw
Definition: Session.h:153
cm_node_t * node
cm_vertex_t * vertices
void SetString(const char *value)
Definition: CVarSystem.h:146
Definition: Vector.h:808
#define MAX_STRING_CHARS
Definition: Lib.h:95
float RandomFloat(void)
Definition: Random.h:82
idVec3 vec3_origin(0.0f, 0.0f, 0.0f)
void Rotation(trace_t *results, const idVec3 &start, const idRotation &rotation, const idTraceModel *trm, const idMat3 &trmAxis, int contentMask, cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis)
GLuint GLuint end
Definition: glext.h:2845
idCommon * common
Definition: Common.cpp:206
#define NULL
Definition: Lib.h:88
int GetInteger(void) const
Definition: CVarSystem.h:143
float w
Definition: Vector.h:813
void Mem_Free(void *ptr)
Definition: Heap.cpp:1087
virtual void Printf(const char *fmt,...) id_attribute((format(printf
cm_edge_t * edges
void DebugOutput(const idVec3 &origin)
void DrawPolygon(cm_model_t *model, cm_polygon_t *p, const idVec3 &origin, const idMat3 &axis, const idVec3 &viewOrigin)
void Stop(void)
Definition: Timer.h:155
const char * GetString(void) const
Definition: CVarSystem.h:141
idVec4 colorCyan
Definition: Lib.cpp:122
int ContentsFromString(const char *string) const
Definition: Matrix.h:333
void DrawNodePolygons(cm_model_t *model, cm_node_t *node, const idVec3 &origin, const idMat3 &axis, const idVec3 &viewOrigin, const float radius)
idCVar cm_drawInternal("cm_drawInternal","1", CVAR_GAME|CVAR_BOOL,"draw internal edges green")
bool GetBool(void) const
Definition: CVarSystem.h:142
#define INTSIGNBITSET(i)
Definition: Math.h:71
void ClearModified(void)
Definition: CVarSystem.h:139
tuple f
Definition: idal.py:89
bool IsModified(void) const
Definition: CVarSystem.h:137
GLsizei const GLcharARB const GLint * length
Definition: glext.h:3599
idCVar cm_backFaceCull("cm_backFaceCull","0", CVAR_GAME|CVAR_BOOL,"cull back facing polygons")
virtual void DebugPolygon(const idVec4 &color, const idWinding &winding, const int lifeTime=0, const bool depthTest=false)=0
void SetBool(const bool value)
Definition: CVarSystem.h:147
void * Mem_Alloc(const int size)
Definition: Heap.cpp:1067
void DrawModel(cmHandle_t model, const idVec3 &origin, const idMat3 &axis, const idVec3 &viewOrigin, const float radius)
idSession * session
Definition: Session.cpp:48
char * va(const char *fmt,...)
Definition: Str.cpp:1568
cm_polygonRef_t * polygons
GLfloat GLfloat p
Definition: glext.h:4674
idCVar cm_drawMask("cm_drawMask","none", CVAR_GAME,"collision mask", cm_contentsNameByIndex, idCmdSystem::ArgCompletion_String< cm_contentsNameByIndex >)
float x
Definition: Vector.h:810
idVec4 colorMagenta
Definition: Lib.cpp:121
int ReadToken(idToken *token)
Definition: Lexer.cpp:820
int sprintf(idStr &string, const char *fmt,...)
Definition: Str.cpp:1528
float CRandomFloat(void)
Definition: Random.h:86
GLuint start
Definition: glext.h:2845
idVec4 colorBlue
Definition: Lib.cpp:119
void Clear(void)
Definition: Timer.h:172
GLdouble GLdouble t
Definition: glext.h:2943