doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
CollisionModel_files.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 #define CM_FILE_EXT "cm"
43 #define CM_FILEID "CM"
44 #define CM_FILEVERSION "1.00"
45 
46 
47 /*
48 ===============================================================================
49 
50 Writing of collision model file
51 
52 ===============================================================================
53 */
54 
55 void CM_GetNodeBounds( idBounds *bounds, cm_node_t *node );
56 int CM_GetNodeContents( cm_node_t *node );
57 
58 
59 /*
60 ================
61 idCollisionModelManagerLocal::WriteNodes
62 ================
63 */
65  fp->WriteFloatString( "\t( %d %f )\n", node->planeType, node->planeDist );
66  if ( node->planeType != -1 ) {
67  WriteNodes( fp, node->children[0] );
68  WriteNodes( fp, node->children[1] );
69  }
70 }
71 
72 /*
73 ================
74 idCollisionModelManagerLocal::CountPolygonMemory
75 ================
76 */
78  cm_polygonRef_t *pref;
79  cm_polygon_t *p;
80  int memory;
81 
82  memory = 0;
83  for ( pref = node->polygons; pref; pref = pref->next ) {
84  p = pref->p;
85  if ( p->checkcount == checkCount ) {
86  continue;
87  }
89 
90  memory += sizeof( cm_polygon_t ) + ( p->numEdges - 1 ) * sizeof( p->edges[0] );
91  }
92  if ( node->planeType != -1 ) {
93  memory += CountPolygonMemory( node->children[0] );
94  memory += CountPolygonMemory( node->children[1] );
95  }
96  return memory;
97 }
98 
99 /*
100 ================
101 idCollisionModelManagerLocal::WritePolygons
102 ================
103 */
105  cm_polygonRef_t *pref;
106  cm_polygon_t *p;
107  int i;
108 
109  for ( pref = node->polygons; pref; pref = pref->next ) {
110  p = pref->p;
111  if ( p->checkcount == checkCount ) {
112  continue;
113  }
114  p->checkcount = checkCount;
115  fp->WriteFloatString( "\t%d (", p->numEdges );
116  for ( i = 0; i < p->numEdges; i++ ) {
117  fp->WriteFloatString( " %d", p->edges[i] );
118  }
119  fp->WriteFloatString( " ) ( %f %f %f ) %f", p->plane.Normal()[0], p->plane.Normal()[1], p->plane.Normal()[2], p->plane.Dist() );
120  fp->WriteFloatString( " ( %f %f %f )", p->bounds[0][0], p->bounds[0][1], p->bounds[0][2] );
121  fp->WriteFloatString( " ( %f %f %f )", p->bounds[1][0], p->bounds[1][1], p->bounds[1][2] );
122  fp->WriteFloatString( " \"%s\"\n", p->material->GetName() );
123  }
124  if ( node->planeType != -1 ) {
125  WritePolygons( fp, node->children[0] );
126  WritePolygons( fp, node->children[1] );
127  }
128 }
129 
130 /*
131 ================
132 idCollisionModelManagerLocal::CountBrushMemory
133 ================
134 */
136  cm_brushRef_t *bref;
137  cm_brush_t *b;
138  int memory;
139 
140  memory = 0;
141  for ( bref = node->brushes; bref; bref = bref->next ) {
142  b = bref->b;
143  if ( b->checkcount == checkCount ) {
144  continue;
145  }
146  b->checkcount = checkCount;
147 
148  memory += sizeof( cm_brush_t ) + ( b->numPlanes - 1 ) * sizeof( b->planes[0] );
149  }
150  if ( node->planeType != -1 ) {
151  memory += CountBrushMemory( node->children[0] );
152  memory += CountBrushMemory( node->children[1] );
153  }
154  return memory;
155 }
156 
157 /*
158 ================
159 idCollisionModelManagerLocal::WriteBrushes
160 ================
161 */
163  cm_brushRef_t *bref;
164  cm_brush_t *b;
165  int i;
166 
167  for ( bref = node->brushes; bref; bref = bref->next ) {
168  b = bref->b;
169  if ( b->checkcount == checkCount ) {
170  continue;
171  }
172  b->checkcount = checkCount;
173  fp->WriteFloatString( "\t%d {\n", b->numPlanes );
174  for ( i = 0; i < b->numPlanes; i++ ) {
175  fp->WriteFloatString( "\t\t( %f %f %f ) %f\n", b->planes[i].Normal()[0], b->planes[i].Normal()[1], b->planes[i].Normal()[2], b->planes[i].Dist() );
176  }
177  fp->WriteFloatString( "\t} ( %f %f %f )", b->bounds[0][0], b->bounds[0][1], b->bounds[0][2] );
178  fp->WriteFloatString( " ( %f %f %f ) \"%s\"\n", b->bounds[1][0], b->bounds[1][1], b->bounds[1][2], StringFromContents( b->contents ) );
179  }
180  if ( node->planeType != -1 ) {
181  WriteBrushes( fp, node->children[0] );
182  WriteBrushes( fp, node->children[1] );
183  }
184 }
185 
186 /*
187 ================
188 idCollisionModelManagerLocal::WriteCollisionModel
189 ================
190 */
192  int i, polygonMemory, brushMemory;
193 
194  fp->WriteFloatString( "collisionModel \"%s\" {\n", model->name.c_str() );
195  // vertices
196  fp->WriteFloatString( "\tvertices { /* numVertices = */ %d\n", model->numVertices );
197  for ( i = 0; i < model->numVertices; i++ ) {
198  fp->WriteFloatString( "\t/* %d */ ( %f %f %f )\n", i, model->vertices[i].p[0], model->vertices[i].p[1], model->vertices[i].p[2] );
199  }
200  fp->WriteFloatString( "\t}\n" );
201  // edges
202  fp->WriteFloatString( "\tedges { /* numEdges = */ %d\n", model->numEdges );
203  for ( i = 0; i < model->numEdges; i++ ) {
204  fp->WriteFloatString( "\t/* %d */ ( %d %d ) %d %d\n", i, model->edges[i].vertexNum[0], model->edges[i].vertexNum[1], model->edges[i].internal, model->edges[i].numUsers );
205  }
206  fp->WriteFloatString( "\t}\n" );
207  // nodes
208  fp->WriteFloatString( "\tnodes {\n" );
209  WriteNodes( fp, model->node );
210  fp->WriteFloatString( "\t}\n" );
211  // polygons
212  checkCount++;
213  polygonMemory = CountPolygonMemory( model->node );
214  fp->WriteFloatString( "\tpolygons /* polygonMemory = */ %d {\n", polygonMemory );
215  checkCount++;
216  WritePolygons( fp, model->node );
217  fp->WriteFloatString( "\t}\n" );
218  // brushes
219  checkCount++;
220  brushMemory = CountBrushMemory( model->node );
221  fp->WriteFloatString( "\tbrushes /* brushMemory = */ %d {\n", brushMemory );
222  checkCount++;
223  WriteBrushes( fp, model->node );
224  fp->WriteFloatString( "\t}\n" );
225  // closing brace
226  fp->WriteFloatString( "}\n" );
227 }
228 
229 /*
230 ================
231 idCollisionModelManagerLocal::WriteCollisionModelsToFile
232 ================
233 */
234 void idCollisionModelManagerLocal::WriteCollisionModelsToFile( const char *filename, int firstModel, int lastModel, unsigned int mapFileCRC ) {
235  int i;
236  idFile *fp;
237  idStr name;
238 
239  name = filename;
241 
242  common->Printf( "writing %s\n", name.c_str() );
243  // _D3XP was saving to fs_cdpath
244  fp = fileSystem->OpenFileWrite( name, "fs_devpath" );
245  if ( !fp ) {
246  common->Warning( "idCollisionModelManagerLocal::WriteCollisionModelsToFile: Error opening file %s\n", name.c_str() );
247  return;
248  }
249 
250  // write file id and version
251  fp->WriteFloatString( "%s \"%s\"\n\n", CM_FILEID, CM_FILEVERSION );
252  // write the map file crc
253  fp->WriteFloatString( "%u\n\n", mapFileCRC );
254 
255  // write the collision models
256  for ( i = firstModel; i < lastModel; i++ ) {
257  WriteCollisionModel( fp, models[ i ] );
258  }
259 
260  fileSystem->CloseFile( fp );
261 }
262 
263 /*
264 ================
265 idCollisionModelManagerLocal::WriteCollisionModelForMapEntity
266 ================
267 */
268 bool idCollisionModelManagerLocal::WriteCollisionModelForMapEntity( const idMapEntity *mapEnt, const char *filename, const bool testTraceModel ) {
269  idFile *fp;
270  idStr name;
271  cm_model_t *model;
272 
273  SetupHash();
274  model = CollisionModelForMapEntity( mapEnt );
275  model->name = filename;
276 
277  name = filename;
279 
280  common->Printf( "writing %s\n", name.c_str() );
281  fp = fileSystem->OpenFileWrite( name, "fs_devpath" );
282  if ( !fp ) {
283  common->Printf( "idCollisionModelManagerLocal::WriteCollisionModelForMapEntity: Error opening file %s\n", name.c_str() );
284  FreeModel( model );
285  return false;
286  }
287 
288  // write file id and version
289  fp->WriteFloatString( "%s \"%s\"\n\n", CM_FILEID, CM_FILEVERSION );
290  // write the map file crc
291  fp->WriteFloatString( "%u\n\n", 0 );
292 
293  // write the collision model
294  WriteCollisionModel( fp, model );
295 
296  fileSystem->CloseFile( fp );
297 
298  if ( testTraceModel ) {
299  idTraceModel trm;
300  TrmFromModel( model, trm );
301  }
302 
303  FreeModel( model );
304 
305  return true;
306 }
307 
308 
309 /*
310 ===============================================================================
311 
312 Loading of collision model file
313 
314 ===============================================================================
315 */
316 
317 /*
318 ================
319 idCollisionModelManagerLocal::ParseVertices
320 ================
321 */
323  int i;
324 
325  src->ExpectTokenString( "{" );
326  model->numVertices = src->ParseInt();
327  model->maxVertices = model->numVertices;
328  model->vertices = (cm_vertex_t *) Mem_Alloc( model->maxVertices * sizeof( cm_vertex_t ) );
329  for ( i = 0; i < model->numVertices; i++ ) {
330  src->Parse1DMatrix( 3, model->vertices[i].p.ToFloatPtr() );
331  model->vertices[i].side = 0;
332  model->vertices[i].sideSet = 0;
333  model->vertices[i].checkcount = 0;
334  }
335  src->ExpectTokenString( "}" );
336 }
337 
338 /*
339 ================
340 idCollisionModelManagerLocal::ParseEdges
341 ================
342 */
344  int i;
345 
346  src->ExpectTokenString( "{" );
347  model->numEdges = src->ParseInt();
348  model->maxEdges = model->numEdges;
349  model->edges = (cm_edge_t *) Mem_Alloc( model->maxEdges * sizeof( cm_edge_t ) );
350  for ( i = 0; i < model->numEdges; i++ ) {
351  src->ExpectTokenString( "(" );
352  model->edges[i].vertexNum[0] = src->ParseInt();
353  model->edges[i].vertexNum[1] = src->ParseInt();
354  src->ExpectTokenString( ")" );
355  model->edges[i].side = 0;
356  model->edges[i].sideSet = 0;
357  model->edges[i].internal = src->ParseInt();
358  model->edges[i].numUsers = src->ParseInt();
359  model->edges[i].normal = vec3_origin;
360  model->edges[i].checkcount = 0;
361  model->numInternalEdges += model->edges[i].internal;
362  }
363  src->ExpectTokenString( "}" );
364 }
365 
366 /*
367 ================
368 idCollisionModelManagerLocal::ParseNodes
369 ================
370 */
372  cm_node_t *node;
373 
374  model->numNodes++;
376  node->brushes = NULL;
377  node->polygons = NULL;
378  node->parent = parent;
379  src->ExpectTokenString( "(" );
380  node->planeType = src->ParseInt();
381  node->planeDist = src->ParseFloat();
382  src->ExpectTokenString( ")" );
383  if ( node->planeType != -1 ) {
384  node->children[0] = ParseNodes( src, model, node );
385  node->children[1] = ParseNodes( src, model, node );
386  }
387  return node;
388 }
389 
390 /*
391 ================
392 idCollisionModelManagerLocal::ParsePolygons
393 ================
394 */
396  cm_polygon_t *p;
397  int i, numEdges;
398  idVec3 normal;
399  idToken token;
400 
401  if ( src->CheckTokenType( TT_NUMBER, 0, &token ) ) {
402  model->polygonBlock = (cm_polygonBlock_t *) Mem_Alloc( sizeof( cm_polygonBlock_t ) + token.GetIntValue() );
403  model->polygonBlock->bytesRemaining = token.GetIntValue();
404  model->polygonBlock->next = ( (byte *) model->polygonBlock ) + sizeof( cm_polygonBlock_t );
405  }
406 
407  src->ExpectTokenString( "{" );
408  while ( !src->CheckTokenString( "}" ) ) {
409  // parse polygon
410  numEdges = src->ParseInt();
411  p = AllocPolygon( model, numEdges );
412  p->numEdges = numEdges;
413  src->ExpectTokenString( "(" );
414  for ( i = 0; i < p->numEdges; i++ ) {
415  p->edges[i] = src->ParseInt();
416  }
417  src->ExpectTokenString( ")" );
418  src->Parse1DMatrix( 3, normal.ToFloatPtr() );
419  p->plane.SetNormal( normal );
420  p->plane.SetDist( src->ParseFloat() );
421  src->Parse1DMatrix( 3, p->bounds[0].ToFloatPtr() );
422  src->Parse1DMatrix( 3, p->bounds[1].ToFloatPtr() );
423  src->ExpectTokenType( TT_STRING, 0, &token );
424  // get material
425  p->material = declManager->FindMaterial( token );
426  p->contents = p->material->GetContentFlags();
427  p->checkcount = 0;
428  // filter polygon into tree
429  R_FilterPolygonIntoTree( model, model->node, NULL, p );
430  }
431 }
432 
433 /*
434 ================
435 idCollisionModelManagerLocal::ParseBrushes
436 ================
437 */
439  cm_brush_t *b;
440  int i, numPlanes;
441  idVec3 normal;
442  idToken token;
443 
444  if ( src->CheckTokenType( TT_NUMBER, 0, &token ) ) {
445  model->brushBlock = (cm_brushBlock_t *) Mem_Alloc( sizeof( cm_brushBlock_t ) + token.GetIntValue() );
446  model->brushBlock->bytesRemaining = token.GetIntValue();
447  model->brushBlock->next = ( (byte *) model->brushBlock ) + sizeof( cm_brushBlock_t );
448  }
449 
450  src->ExpectTokenString( "{" );
451  while ( !src->CheckTokenString( "}" ) ) {
452  // parse brush
453  numPlanes = src->ParseInt();
454  b = AllocBrush( model, numPlanes );
455  b->numPlanes = numPlanes;
456  src->ExpectTokenString( "{" );
457  for ( i = 0; i < b->numPlanes; i++ ) {
458  src->Parse1DMatrix( 3, normal.ToFloatPtr() );
459  b->planes[i].SetNormal( normal );
460  b->planes[i].SetDist( src->ParseFloat() );
461  }
462  src->ExpectTokenString( "}" );
463  src->Parse1DMatrix( 3, b->bounds[0].ToFloatPtr() );
464  src->Parse1DMatrix( 3, b->bounds[1].ToFloatPtr() );
465  src->ReadToken( &token );
466  if ( token.type == TT_NUMBER ) {
467  b->contents = token.GetIntValue(); // old .cm files use a single integer
468  } else {
469  b->contents = ContentsFromString( token );
470  }
471  b->checkcount = 0;
472  b->primitiveNum = 0;
473  // filter brush into tree
474  R_FilterBrushIntoTree( model, model->node, NULL, b );
475  }
476 }
477 
478 /*
479 ================
480 idCollisionModelManagerLocal::ParseCollisionModel
481 ================
482 */
484  cm_model_t *model;
485  idToken token;
486 
487  if ( numModels >= MAX_SUBMODELS ) {
488  common->Error( "LoadModel: no free slots" );
489  return false;
490  }
491  model = AllocModel();
492  models[numModels ] = model;
493  numModels++;
494  // parse the file
495  src->ExpectTokenType( TT_STRING, 0, &token );
496  model->name = token;
497  src->ExpectTokenString( "{" );
498  while ( !src->CheckTokenString( "}" ) ) {
499 
500  src->ReadToken( &token );
501 
502  if ( token == "vertices" ) {
503  ParseVertices( src, model );
504  continue;
505  }
506 
507  if ( token == "edges" ) {
508  ParseEdges( src, model );
509  continue;
510  }
511 
512  if ( token == "nodes" ) {
513  src->ExpectTokenString( "{" );
514  model->node = ParseNodes( src, model, NULL );
515  src->ExpectTokenString( "}" );
516  continue;
517  }
518 
519  if ( token == "polygons" ) {
520  ParsePolygons( src, model );
521  continue;
522  }
523 
524  if ( token == "brushes" ) {
525  ParseBrushes( src, model );
526  continue;
527  }
528 
529  src->Error( "ParseCollisionModel: bad token \"%s\"", token.c_str() );
530  }
531  // calculate edge normals
532  checkCount++;
533  CalculateEdgeNormals( model, model->node );
534  // get model bounds from brush and polygon bounds
535  CM_GetNodeBounds( &model->bounds, model->node );
536  // get model contents
537  model->contents = CM_GetNodeContents( model->node );
538  // total memory used by this model
539  model->usedMemory = model->numVertices * sizeof(cm_vertex_t) +
540  model->numEdges * sizeof(cm_edge_t) +
541  model->polygonMemory +
542  model->brushMemory +
543  model->numNodes * sizeof(cm_node_t) +
544  model->numPolygonRefs * sizeof(cm_polygonRef_t) +
545  model->numBrushRefs * sizeof(cm_brushRef_t);
546 
547  return true;
548 }
549 
550 /*
551 ================
552 idCollisionModelManagerLocal::LoadCollisionModelFile
553 ================
554 */
555 bool idCollisionModelManagerLocal::LoadCollisionModelFile( const char *name, unsigned int mapFileCRC ) {
556  idStr fileName;
557  idToken token;
558  idLexer *src;
559  unsigned int crc;
560 
561  // load it
562  fileName = name;
563  fileName.SetFileExtension( CM_FILE_EXT );
564  src = new idLexer( fileName );
566  if ( !src->IsLoaded() ) {
567  delete src;
568  return false;
569  }
570 
571  if ( !src->ExpectTokenString( CM_FILEID ) ) {
572  common->Warning( "%s is not an CM file.", fileName.c_str() );
573  delete src;
574  return false;
575  }
576 
577  if ( !src->ReadToken( &token ) || token != CM_FILEVERSION ) {
578  common->Warning( "%s has version %s instead of %s", fileName.c_str(), token.c_str(), CM_FILEVERSION );
579  delete src;
580  return false;
581  }
582 
583  if ( !src->ExpectTokenType( TT_NUMBER, TT_INTEGER, &token ) ) {
584  common->Warning( "%s has no map file CRC", fileName.c_str() );
585  delete src;
586  return false;
587  }
588 
589  crc = token.GetUnsignedLongValue();
590  if ( mapFileCRC && crc != mapFileCRC ) {
591  common->Printf( "%s is out of date\n", fileName.c_str() );
592  delete src;
593  return false;
594  }
595 
596  // parse the file
597  while ( 1 ) {
598  if ( !src->ReadToken( &token ) ) {
599  break;
600  }
601 
602  if ( token == "collisionModel" ) {
603  if ( !ParseCollisionModel( src ) ) {
604  delete src;
605  return false;
606  }
607  continue;
608  }
609 
610  src->Error( "idCollisionModelManagerLocal::LoadCollisionModelFile: bad token \"%s\"", token.c_str() );
611  }
612 
613  delete src;
614 
615  return true;
616 }
void WriteCollisionModelsToFile(const char *filename, int firstModel, int lastModel, unsigned int mapFileCRC)
int CheckTokenString(const char *string)
Definition: Lexer.cpp:1007
int CountPolygonMemory(cm_node_t *node) const
struct cm_vertex_s cm_vertex_t
struct cm_node_s * children[2]
int type
Definition: Token.h:77
idStr & SetFileExtension(const char *extension)
Definition: Str.cpp:743
const idVec3 & Normal(void) const
Definition: Plane.h:239
unsigned short numUsers
unsigned long sideSet
const float * ToFloatPtr(void) const
Definition: Vector.h:719
#define CM_FILEID
int Parse1DMatrix(int x, float *m)
Definition: Lexer.cpp:1300
const char * StringFromContents(const int contents) const
#define TT_INTEGER
Definition: Token.h:48
void WriteBrushes(idFile *fp, cm_node_t *node)
idFileSystem * fileSystem
Definition: FileSystem.cpp:500
cm_polygon_t * AllocPolygon(cm_model_t *model, int numEdges)
unsigned long GetUnsignedLongValue(void)
Definition: Token.h:142
struct cm_polygonRef_s * next
void ParsePolygons(idLexer *src, cm_model_t *model)
const char * GetName(void) const
Definition: DeclManager.h:140
unsigned short internal
Definition: Vector.h:316
const idMaterial * material
int CheckTokenType(int type, int subtype, idToken *token)
Definition: Lexer.cpp:1028
int CountBrushMemory(cm_node_t *node) const
Definition: Token.h:71
void SetFlags(int flags)
Definition: Lexer.h:298
#define TT_STRING
Definition: Token.h:41
virtual const idMaterial * FindMaterial(const char *name, bool makeDefault=true)=0
float ParseFloat(bool *errorFlag=NULL)
Definition: Lexer.cpp:1264
GLuint src
Definition: glext.h:5390
void SetNormal(const idVec3 &normal)
Definition: Plane.h:233
int i
Definition: process.py:33
void WriteNodes(idFile *fp, cm_node_t *node)
int ParseInt(void)
Definition: Lexer.cpp:1227
void R_FilterPolygonIntoTree(cm_model_t *model, cm_node_t *node, cm_polygonRef_t *pref, cm_polygon_t *p)
void CM_GetNodeBounds(idBounds *bounds, cm_node_t *node)
#define TT_NUMBER
Definition: Token.h:43
#define CM_FILEVERSION
Definition: File.h:50
Definition: Lexer.h:137
void Error(const char *str,...) id_attribute((format(printf
Definition: Lexer.cpp:215
#define MAX_SUBMODELS
bool LoadCollisionModelFile(const char *name, unsigned int mapFileCRC)
cm_node_t * node
int ExpectTokenType(int type, int subtype, idToken *token)
Definition: Lexer.cpp:938
cm_vertex_t * vertices
struct cm_polygonBlock_s cm_polygonBlock_t
#define NODE_BLOCK_SIZE_LARGE
void SetDist(const float dist)
Definition: Plane.h:275
idVec3 vec3_origin(0.0f, 0.0f, 0.0f)
cm_brushBlock_t * brushBlock
idCommon * common
Definition: Common.cpp:206
#define NULL
Definition: Lib.h:88
unsigned long sideSet
unsigned long side
void R_FilterBrushIntoTree(cm_model_t *model, cm_node_t *node, cm_brushRef_t *pref, cm_brush_t *b)
const int GetContentFlags(void) const
Definition: Material.h:497
void ParseEdges(idLexer *src, cm_model_t *model)
void FreeModel(cm_model_t *model)
cm_brushRef_t * brushes
virtual idFile * OpenFileWrite(const char *relativePath, const char *basePath="fs_savepath")=0
cm_polygonBlock_t * polygonBlock
struct cm_brushBlock_s cm_brushBlock_t
struct cm_brush_s cm_brush_t
void CalculateEdgeNormals(cm_model_t *model, cm_node_t *node)
virtual int WriteFloatString(const char *fmt,...) id_attribute((format(printf
Definition: File.cpp:294
virtual void Printf(const char *fmt,...) id_attribute((format(printf
unsigned long side
#define NODE_BLOCK_SIZE_SMALL
cm_node_t * AllocNode(cm_model_t *model, int blockSize)
cm_edge_t * edges
idDeclManager * declManager
void ParseVertices(idLexer *src, cm_model_t *model)
void WritePolygons(idFile *fp, cm_node_t *node)
GLubyte GLubyte b
Definition: glext.h:4662
struct cm_polygon_s cm_polygon_t
bool WriteCollisionModelForMapEntity(const idMapEntity *mapEnt, const char *filename, const bool testTraceModel=true)
int ExpectTokenString(const char *string)
Definition: Lexer.cpp:919
int CM_GetNodeContents(cm_node_t *node)
int ContentsFromString(const char *string) const
cm_model_t * CollisionModelForMapEntity(const idMapEntity *mapEnt)
void WriteCollisionModel(idFile *fp, cm_model_t *model)
unsigned char byte
Definition: Lib.h:75
const GLcharARB * name
Definition: glext.h:3629
struct cm_node_s cm_node_t
struct cm_node_s * parent
Definition: Str.h:116
struct cm_brushRef_s * next
int GetIntValue(void)
Definition: Token.h:152
const char * c_str(void) const
Definition: Str.h:487
void * Mem_Alloc(const int size)
Definition: Heap.cpp:1067
struct cm_brushRef_s cm_brushRef_t
int IsLoaded(void)
Definition: Lexer.h:158
void ParseBrushes(idLexer *src, cm_model_t *model)
bool TrmFromModel(const char *modelName, idTraceModel &trm)
virtual void CloseFile(idFile *f)=0
cm_polygonRef_t * polygons
virtual void Error(const char *fmt,...) id_attribute((format(printf
GLfloat GLfloat p
Definition: glext.h:4674
virtual void virtual void Warning(const char *fmt,...) id_attribute((format(printf
int ReadToken(idToken *token)
Definition: Lexer.cpp:820
cm_node_t * ParseNodes(idLexer *src, cm_model_t *model, cm_node_t *parent)
float Dist(void) const
Definition: Plane.h:271
#define CM_FILE_EXT
cm_brush_t * AllocBrush(cm_model_t *model, int numPlanes)