doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
output.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 "dmap.h"
33 
34 //=================================================================================
35 
36 
37 #if 0
38 
39 should we try and snap values very close to 0.5, 0.25, 0.125, etc?
40 
41  do we write out normals, or just a "smooth shade" flag?
42 resolved: normals. otherwise adjacent facet shaded surfaces get their
43  vertexes merged, and they would have to be split apart before drawing
44 
45  do we save out "wings" for shadow silhouette info?
46 
47 
48 #endif
49 
50 static idFile *procFile;
51 
52 #define AREANUM_DIFFERENT -2
53 /*
54 =============
55 PruneNodes_r
56 
57 Any nodes that have all children with the same
58 area can be combined into a single leaf node
59 
60 Returns the area number of all children, or
61 AREANUM_DIFFERENT if not the same.
62 =============
63 */
64 int PruneNodes_r( node_t *node ) {
65  int a1, a2;
66 
67  if ( node->planenum == PLANENUM_LEAF ) {
68  return node->area;
69  }
70 
71  a1 = PruneNodes_r( node->children[0] );
72  a2 = PruneNodes_r( node->children[1] );
73 
74  if ( a1 != a2 || a1 == AREANUM_DIFFERENT ) {
75  return AREANUM_DIFFERENT;
76  }
77 
78  // free all the nodes below this point
79  FreeTreePortals_r( node->children[0] );
80  FreeTreePortals_r( node->children[1] );
81  FreeTree_r( node->children[0] );
82  FreeTree_r( node->children[1] );
83 
84  // change this node to a leaf
85  node->planenum = PLANENUM_LEAF;
86  node->area = a1;
87 
88  return a1;
89 }
90 
91 static void WriteFloat( idFile *f, float v )
92 {
93  if ( idMath::Fabs(v - idMath::Rint(v)) < 0.001 ) {
94  f->WriteFloatString( "%i ", (int)idMath::Rint(v) );
95  }
96  else {
97  f->WriteFloatString( "%f ", v );
98  }
99 }
100 
101 void Write1DMatrix( idFile *f, int x, float *m ) {
102  int i;
103 
104  f->WriteFloatString( "( " );
105 
106  for ( i = 0; i < x; i++ ) {
107  WriteFloat( f, m[i] );
108  }
109 
110  f->WriteFloatString( ") " );
111 }
112 
113 static int CountUniqueShaders( optimizeGroup_t *groups ) {
114  optimizeGroup_t *a, *b;
115  int count;
116 
117  count = 0;
118 
119  for ( a = groups ; a ; a = a->nextGroup ) {
120  if ( !a->triList ) { // ignore groups with no tris
121  continue;
122  }
123  for ( b = groups ; b != a ; b = b->nextGroup ) {
124  if ( !b->triList ) {
125  continue;
126  }
127  if ( a->material != b->material ) {
128  continue;
129  }
130  if ( a->mergeGroup != b->mergeGroup ) {
131  continue;
132  }
133  break;
134  }
135  if ( a == b ) {
136  count++;
137  }
138  }
139 
140  return count;
141 }
142 
143 
144 /*
145 ==============
146 MatchVert
147 ==============
148 */
149 #define XYZ_EPSILON 0.01
150 #define ST_EPSILON 0.001
151 #define COSINE_EPSILON 0.999
152 
153 static bool MatchVert( const idDrawVert *a, const idDrawVert *b ) {
154  if ( idMath::Fabs( a->xyz[0] - b->xyz[0] ) > XYZ_EPSILON ) {
155  return false;
156  }
157  if ( idMath::Fabs( a->xyz[1] - b->xyz[1] ) > XYZ_EPSILON ) {
158  return false;
159  }
160  if ( idMath::Fabs( a->xyz[2] - b->xyz[2] ) > XYZ_EPSILON ) {
161  return false;
162  }
163  if ( idMath::Fabs( a->st[0] - b->st[0] ) > ST_EPSILON ) {
164  return false;
165  }
166  if ( idMath::Fabs( a->st[1] - b->st[1] ) > ST_EPSILON ) {
167  return false;
168  }
169 
170  // if the normal is 0 (smoothed normals), consider it a match
171  if ( a->normal[0] == 0 && a->normal[1] == 0 && a->normal[2] == 0
172  && b->normal[0] == 0 && b->normal[1] == 0 && b->normal[2] == 0 ) {
173  return true;
174  }
175 
176  // otherwise do a dot-product cosine check
177  if ( DotProduct( a->normal, b->normal ) < COSINE_EPSILON ) {
178  return false;
179  }
180 
181  return true;
182 }
183 
184 /*
185 ====================
186 ShareMapTriVerts
187 
188 Converts independent triangles to shared vertex triangles
189 ====================
190 */
192  const mapTri_t *step;
193  int count;
194  int i, j;
195  int numVerts;
196  int numIndexes;
197  srfTriangles_t *uTri;
198 
199  // unique the vertexes
200  count = CountTriList( tris );
201 
202  uTri = R_AllocStaticTriSurf();
203  R_AllocStaticTriSurfVerts( uTri, count * 3 );
204  R_AllocStaticTriSurfIndexes( uTri, count * 3 );
205 
206  numVerts = 0;
207  numIndexes = 0;
208 
209  for ( step = tris ; step ; step = step->next ) {
210  for ( i = 0 ; i < 3 ; i++ ) {
211  const idDrawVert *dv;
212 
213  dv = &step->v[i];
214 
215  // search for a match
216  for ( j = 0 ; j < numVerts ; j++ ) {
217  if ( MatchVert( &uTri->verts[j], dv ) ) {
218  break;
219  }
220  }
221  if ( j == numVerts ) {
222  numVerts++;
223  uTri->verts[j].xyz = dv->xyz;
224  uTri->verts[j].normal = dv->normal;
225  uTri->verts[j].st[0] = dv->st[0];
226  uTri->verts[j].st[1] = dv->st[1];
227  }
228 
229  uTri->indexes[numIndexes++] = j;
230  }
231  }
232 
233  uTri->numVerts = numVerts;
234  uTri->numIndexes = numIndexes;
235 
236  return uTri;
237 }
238 
239 /*
240 ==================
241 CleanupUTriangles
242 ==================
243 */
244 static void CleanupUTriangles( srfTriangles_t *tri ) {
245  // perform cleanup operations
246 
247  R_RangeCheckIndexes( tri );
248  R_CreateSilIndexes( tri );
249 // R_RemoveDuplicatedTriangles( tri ); // this may remove valid overlapped transparent triangles
251 // R_RemoveUnusedVerts( tri );
252 
254 }
255 
256 /*
257 ====================
258 WriteUTriangles
259 
260 Writes text verts and indexes to procfile
261 ====================
262 */
263 static void WriteUTriangles( const srfTriangles_t *uTris ) {
264  int col;
265  int i;
266 
267  // emit this chain
268  procFile->WriteFloatString( "/* numVerts = */ %i /* numIndexes = */ %i\n",
269  uTris->numVerts, uTris->numIndexes );
270 
271  // verts
272  col = 0;
273  for ( i = 0 ; i < uTris->numVerts ; i++ ) {
274  float vec[8];
275  const idDrawVert *dv;
276 
277  dv = &uTris->verts[i];
278 
279  vec[0] = dv->xyz[0];
280  vec[1] = dv->xyz[1];
281  vec[2] = dv->xyz[2];
282  vec[3] = dv->st[0];
283  vec[4] = dv->st[1];
284  vec[5] = dv->normal[0];
285  vec[6] = dv->normal[1];
286  vec[7] = dv->normal[2];
287  Write1DMatrix( procFile, 8, vec );
288 
289  if ( ++col == 3 ) {
290  col = 0;
291  procFile->WriteFloatString( "\n" );
292  }
293  }
294  if ( col != 0 ) {
295  procFile->WriteFloatString( "\n" );
296  }
297 
298  // indexes
299  col = 0;
300  for ( i = 0 ; i < uTris->numIndexes ; i++ ) {
301  procFile->WriteFloatString( "%i ", uTris->indexes[i] );
302 
303  if ( ++col == 18 ) {
304  col = 0;
305  procFile->WriteFloatString( "\n" );
306  }
307  }
308  if ( col != 0 ) {
309  procFile->WriteFloatString( "\n" );
310  }
311 }
312 
313 
314 /*
315 ====================
316 WriteShadowTriangles
317 
318 Writes text verts and indexes to procfile
319 ====================
320 */
321 static void WriteShadowTriangles( const srfTriangles_t *tri ) {
322  int col;
323  int i;
324 
325  // emit this chain
326  procFile->WriteFloatString( "/* numVerts = */ %i /* noCaps = */ %i /* noFrontCaps = */ %i /* numIndexes = */ %i /* planeBits = */ %i\n",
328 
329  // verts
330  col = 0;
331  for ( i = 0 ; i < tri->numVerts ; i++ ) {
332  Write1DMatrix( procFile, 3, &tri->shadowVertexes[i].xyz[0] );
333 
334  if ( ++col == 5 ) {
335  col = 0;
336  procFile->WriteFloatString( "\n" );
337  }
338  }
339  if ( col != 0 ) {
340  procFile->WriteFloatString( "\n" );
341  }
342 
343  // indexes
344  col = 0;
345  for ( i = 0 ; i < tri->numIndexes ; i++ ) {
346  procFile->WriteFloatString( "%i ", tri->indexes[i] );
347 
348  if ( ++col == 18 ) {
349  col = 0;
350  procFile->WriteFloatString( "\n" );
351  }
352  }
353  if ( col != 0 ) {
354  procFile->WriteFloatString( "\n" );
355  }
356 }
357 
358 
359 /*
360 =======================
361 GroupsAreSurfaceCompatible
362 
363 Planes, texcoords, and groupLights can differ,
364 but the material and mergegroup must match
365 =======================
366 */
367 static bool GroupsAreSurfaceCompatible( const optimizeGroup_t *a, const optimizeGroup_t *b ) {
368  if ( a->material != b->material ) {
369  return false;
370  }
371  if ( a->mergeGroup != b->mergeGroup ) {
372  return false;
373  }
374  return true;
375 }
376 
377 /*
378 ====================
379 WriteOutputSurfaces
380 ====================
381 */
382 static void WriteOutputSurfaces( int entityNum, int areaNum ) {
383  mapTri_t *ambient, *copy;
384  int surfaceNum;
385  int numSurfaces;
386  idMapEntity *entity;
387  uArea_t *area;
388  optimizeGroup_t *group, *groupStep;
389  int i; // , j;
390 // int col;
391  srfTriangles_t *uTri;
392 // mapTri_t *tri;
393 typedef struct interactionTris_s {
394  struct interactionTris_s *next;
395  mapTri_t *triList;
396  mapLight_t *light;
397 } interactionTris_t;
398 
399  interactionTris_t *interactions, *checkInter; //, *nextInter;
400 
401 
402  area = &dmapGlobals.uEntities[entityNum].areas[areaNum];
403  entity = dmapGlobals.uEntities[entityNum].mapEntity;
404 
405  numSurfaces = CountUniqueShaders( area->groups );
406 
407 
408  if ( entityNum == 0 ) {
409  procFile->WriteFloatString( "model { /* name = */ \"_area%i\" /* numSurfaces = */ %i\n\n",
410  areaNum, numSurfaces );
411  } else {
412  const char *name;
413 
414  entity->epairs.GetString( "name", "", &name );
415  if ( !name[0] ) {
416  common->Error( "Entity %i has surfaces, but no name key", entityNum );
417  }
418  procFile->WriteFloatString( "model { /* name = */ \"%s\" /* numSurfaces = */ %i\n\n",
419  name, numSurfaces );
420  }
421 
422  surfaceNum = 0;
423  for ( group = area->groups ; group ; group = group->nextGroup ) {
424  if ( group->surfaceEmited ) {
425  continue;
426  }
427 
428  // combine all groups compatible with this one
429  // usually several optimizeGroup_t can be combined into a single
430  // surface, even though they couldn't be merged together to save
431  // vertexes because they had different planes, texture coordinates, or lights.
432  // Different mergeGroups will stay in separate surfaces.
433  ambient = NULL;
434 
435  // each light that illuminates any of the groups in the surface will
436  // get its own list of indexes out of the original surface
437  interactions = NULL;
438 
439  for ( groupStep = group ; groupStep ; groupStep = groupStep->nextGroup ) {
440  if ( groupStep->surfaceEmited ) {
441  continue;
442  }
443  if ( !GroupsAreSurfaceCompatible( group, groupStep ) ) {
444  continue;
445  }
446 
447  // copy it out to the ambient list
448  copy = CopyTriList( groupStep->triList );
449  ambient = MergeTriLists( ambient, copy );
450  groupStep->surfaceEmited = true;
451 
452  // duplicate it into an interaction for each groupLight
453  for ( i = 0 ; i < groupStep->numGroupLights ; i++ ) {
454  for ( checkInter = interactions ; checkInter ; checkInter = checkInter->next ) {
455  if ( checkInter->light == groupStep->groupLights[i] ) {
456  break;
457  }
458  }
459  if ( !checkInter ) {
460  // create a new interaction
461  checkInter = (interactionTris_t *)Mem_ClearedAlloc( sizeof( *checkInter ) );
462  checkInter->light = groupStep->groupLights[i];
463  checkInter->next = interactions;
464  interactions = checkInter;
465  }
466  copy = CopyTriList( groupStep->triList );
467  checkInter->triList = MergeTriLists( checkInter->triList, copy );
468  }
469  }
470 
471  if ( !ambient ) {
472  continue;
473  }
474 
475  if ( surfaceNum >= numSurfaces ) {
476  common->Error( "WriteOutputSurfaces: surfaceNum >= numSurfaces" );
477  }
478 
479  procFile->WriteFloatString( "/* surface %i */ { ", surfaceNum );
480  surfaceNum++;
481  procFile->WriteFloatString( "\"%s\" ", ambient->material->GetName() );
482 
483  uTri = ShareMapTriVerts( ambient );
484  FreeTriList( ambient );
485 
486  CleanupUTriangles( uTri );
487  WriteUTriangles( uTri );
488  R_FreeStaticTriSurf( uTri );
489 
490  procFile->WriteFloatString( "}\n\n" );
491  }
492 
493  procFile->WriteFloatString( "}\n\n" );
494 }
495 
496 /*
497 ===============
498 WriteNode_r
499 
500 ===============
501 */
502 static void WriteNode_r( node_t *node ) {
503  int child[2];
504  int i;
505  idPlane *plane;
506 
507  if ( node->planenum == PLANENUM_LEAF ) {
508  // we shouldn't get here unless the entire world
509  // was a single leaf
510  procFile->WriteFloatString( "/* node 0 */ ( 0 0 0 0 ) -1 -1\n" );
511  return;
512  }
513 
514  for ( i = 0 ; i < 2 ; i++ ) {
515  if ( node->children[i]->planenum == PLANENUM_LEAF ) {
516  child[i] = -1 - node->children[i]->area;
517  } else {
518  child[i] = node->children[i]->nodeNumber;
519  }
520  }
521 
522  plane = &dmapGlobals.mapPlanes[node->planenum];
523 
524  procFile->WriteFloatString( "/* node %i */ ", node->nodeNumber );
525  Write1DMatrix( procFile, 4, plane->ToFloatPtr() );
526  procFile->WriteFloatString( "%i %i\n", child[0], child[1] );
527 
528  if ( child[0] > 0 ) {
529  WriteNode_r( node->children[0] );
530  }
531  if ( child[1] > 0 ) {
532  WriteNode_r( node->children[1] );
533  }
534 }
535 
536 static int NumberNodes_r( node_t *node, int nextNumber ) {
537  if ( node->planenum == PLANENUM_LEAF ) {
538  return nextNumber;
539  }
540  node->nodeNumber = nextNumber;
541  nextNumber++;
542  nextNumber = NumberNodes_r( node->children[0], nextNumber );
543  nextNumber = NumberNodes_r( node->children[1], nextNumber );
544 
545  return nextNumber;
546 }
547 
548 /*
549 ====================
550 WriteOutputNodes
551 ====================
552 */
553 static void WriteOutputNodes( node_t *node ) {
554  int numNodes;
555 
556  // prune unneeded nodes and count
557  PruneNodes_r( node );
558  numNodes = NumberNodes_r( node, 0 );
559 
560  // output
561  procFile->WriteFloatString( "nodes { /* numNodes = */ %i\n\n", numNodes );
562  procFile->WriteFloatString( "/* node format is: ( planeVector ) positiveChild negativeChild */\n" );
563  procFile->WriteFloatString( "/* a child number of 0 is an opaque, solid area */\n" );
564  procFile->WriteFloatString( "/* negative child numbers are areas: (-1-child) */\n" );
565 
566  WriteNode_r( node );
567 
568  procFile->WriteFloatString( "}\n\n" );
569 }
570 
571 /*
572 ====================
573 WriteOutputPortals
574 ====================
575 */
576 static void WriteOutputPortals( uEntity_t *e ) {
577  int i, j;
578  interAreaPortal_t *iap;
579  idWinding *w;
580 
581  procFile->WriteFloatString( "interAreaPortals { /* numAreas = */ %i /* numIAP = */ %i\n\n",
583  procFile->WriteFloatString( "/* interAreaPortal format is: numPoints positiveSideArea negativeSideArea ( point) ... */\n" );
584  for ( i = 0 ; i < numInterAreaPortals ; i++ ) {
585  iap = &interAreaPortals[i];
586  w = iap->side->winding;
587  procFile->WriteFloatString("/* iap %i */ %i %i %i ", i, w->GetNumPoints(), iap->area0, iap->area1 );
588  for ( j = 0 ; j < w->GetNumPoints() ; j++ ) {
589  Write1DMatrix( procFile, 3, (*w)[j].ToFloatPtr() );
590  }
591  procFile->WriteFloatString("\n" );
592  }
593 
594  procFile->WriteFloatString( "}\n\n" );
595 }
596 
597 
598 /*
599 ====================
600 WriteOutputEntity
601 ====================
602 */
603 static void WriteOutputEntity( int entityNum ) {
604  int i;
605  uEntity_t *e;
606 
607  e = &dmapGlobals.uEntities[entityNum];
608 
609  if ( entityNum != 0 ) {
610  // entities may have enclosed, empty areas that we don't need to write out
611  if ( e->numAreas > 1 ) {
612  e->numAreas = 1;
613  }
614  }
615 
616  for ( i = 0 ; i < e->numAreas ; i++ ) {
617  WriteOutputSurfaces( entityNum, i );
618  }
619 
620  // we will completely skip the portals and nodes if it is a single area
621  if ( entityNum == 0 && e->numAreas > 1 ) {
622  // output the area portals
623  WriteOutputPortals( e );
624 
625  // output the nodes
626  WriteOutputNodes( e->tree->headnode );
627  }
628 }
629 
630 
631 /*
632 ====================
633 WriteOutputFile
634 ====================
635 */
636 void WriteOutputFile( void ) {
637  int i;
638  uEntity_t *entity;
639  idStr qpath;
640 
641  // write the file
642  common->Printf( "----- WriteOutputFile -----\n" );
643 
644  sprintf( qpath, "%s." PROC_FILE_EXT, dmapGlobals.mapFileBase );
645 
646  common->Printf( "writing %s\n", qpath.c_str() );
647  // _D3XP used fs_cdpath
648  procFile = fileSystem->OpenFileWrite( qpath, "fs_devpath" );
649  if ( !procFile ) {
650  common->Error( "Error opening %s", qpath.c_str() );
651  }
652 
653  procFile->WriteFloatString( "%s\n\n", PROC_FILE_ID );
654 
655  // write the entity models and information, writing entities first
656  for ( i=dmapGlobals.num_entities - 1 ; i >= 0 ; i-- ) {
657  entity = &dmapGlobals.uEntities[i];
658 
659  if ( !entity->primitives ) {
660  continue;
661  }
662 
663  WriteOutputEntity( i );
664  }
665 
666  // write the shadow volumes
667  for ( i = 0 ; i < dmapGlobals.mapLights.Num() ; i++ ) {
668  mapLight_t *light = dmapGlobals.mapLights[i];
669  if ( !light->shadowTris ) {
670  continue;
671  }
672 
673  procFile->WriteFloatString( "shadowModel { /* name = */ \"_prelight_%s\"\n\n", light->name );
674  WriteShadowTriangles( light->shadowTris );
675  procFile->WriteFloatString( "}\n\n" );
676 
678  light->shadowTris = NULL;
679  }
680 
681  fileSystem->CloseFile( procFile );
682 }
int numShadowIndexesNoFrontCaps
Definition: Model.h:119
int shadowCapPlaneBits
Definition: Model.h:122
int numInterAreaPortals
Definition: portals.cpp:36
side_t * side
Definition: dmap.h:341
GLboolean GLenum GLenum GLvoid * values
Definition: glext.h:2868
int numGroupLights
Definition: dmap.h:198
node_t * headnode
Definition: dmap.h:173
struct mapTri_s * next
Definition: dmap.h:60
int numVerts
Definition: Model.h:98
void WriteOutputFile(void)
Definition: output.cpp:636
idWinding * winding
Definition: dmap.h:108
idVec4 xyz
Definition: Model.h:80
const GLdouble * v
Definition: glext.h:2936
primitive_t * primitives
Definition: dmap.h:50
char mapFileBase[1024]
Definition: dmap.h:235
idVec3 xyz
Definition: DrawVert.h:42
idList< mapLight_t * > mapLights
Definition: dmap.h:246
void FreeTree_r(node_t *node)
Definition: facebsp.cpp:93
idFileSystem * fileSystem
Definition: FileSystem.cpp:500
#define AREANUM_DIFFERENT
Definition: output.cpp:52
const float * ToFloatPtr(void) const
Definition: Plane.h:383
void R_FreeStaticTriSurfSilIndexes(srfTriangles_t *tri)
Definition: tr_trisurf.cpp:654
const char * GetName(void) const
Definition: DeclManager.h:140
uArea_t * areas
Definition: dmap.h:54
#define ST_EPSILON
Definition: output.cpp:150
int PruneNodes_r(node_t *node)
Definition: output.cpp:64
bool surfaceEmited
Definition: dmap.h:205
srfTriangles_t * R_AllocStaticTriSurf(void)
Definition: tr_trisurf.cpp:523
void Write1DMatrix(idFile *f, int x, float *m)
Definition: output.cpp:101
mapLight_t * groupLights[MAX_GROUP_LIGHTS]
Definition: dmap.h:199
static float Rint(float f)
Definition: Math.h:793
GLenum GLint x
Definition: glext.h:2849
int i
Definition: process.py:33
srfTriangles_t * shadowTris
Definition: dmap.h:183
mapTri_t * MergeTriLists(mapTri_t *a, mapTri_t *b)
Definition: tritools.cpp:70
int planenum
Definition: dmap.h:140
idPlaneSet mapPlanes
Definition: dmap.h:239
#define PROC_FILE_EXT
Definition: RenderWorld.h:40
idDict epairs
Definition: MapFile.h:166
#define PROC_FILE_ID
Definition: RenderWorld.h:41
void FreeTriList(mapTri_t *a)
Definition: tritools.cpp:89
void R_RemoveDegenerateTriangles(srfTriangles_t *tri)
idDrawVert v[3]
Definition: dmap.h:67
struct optimizeGroup_s * groups
Definition: dmap.h:42
Definition: File.h:50
idVec2 st
Definition: DrawVert.h:43
GLuint GLuint GLsizei count
Definition: glext.h:2845
#define XYZ_EPSILON
Definition: output.cpp:149
int GetNumPoints(void) const
Definition: Winding.h:238
struct node_s * children[2]
Definition: dmap.h:146
const char * GetString(const char *key, const char *defaultString="") const
Definition: Dict.h:240
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:3454
srfTriangles_t * ShareMapTriVerts(const mapTri_t *tris)
Definition: output.cpp:191
void FreeTreePortals_r(node_t *node)
Definition: facebsp.cpp:64
mapTri_t * CopyTriList(const mapTri_t *a)
Definition: tritools.cpp:103
static float Fabs(float f)
Definition: Math.h:779
idCommon * common
Definition: Common.cpp:206
#define NULL
Definition: Lib.h:88
Definition: dmap.h:41
virtual idFile * OpenFileWrite(const char *relativePath, const char *basePath="fs_savepath")=0
Definition: Plane.h:71
void R_FreeStaticTriSurf(srfTriangles_t *tri)
Definition: tr_trisurf.cpp:489
idVec3 normal
Definition: DrawVert.h:44
shadowCache_t * shadowVertexes
Definition: Model.h:127
virtual int WriteFloatString(const char *fmt,...) id_attribute((format(printf
Definition: File.cpp:294
#define COSINE_EPSILON
Definition: output.cpp:151
GLubyte GLubyte GLubyte a
Definition: glext.h:4662
virtual void Printf(const char *fmt,...) id_attribute((format(printf
void * mergeGroup
Definition: dmap.h:200
GLubyte GLubyte b
Definition: glext.h:4662
uEntity_t * uEntities
Definition: dmap.h:242
int numShadowIndexesNoCaps
Definition: Model.h:120
#define PLANENUM_LEAF
Definition: dmap.h:81
struct tree_s * tree
Definition: dmap.h:51
Definition: dmap.h:59
int nodeNumber
Definition: dmap.h:147
const idMaterial * material
Definition: dmap.h:62
tuple f
Definition: idal.py:89
int Num(void) const
Definition: List.h:265
Definition: dmap.h:46
int num_entities
Definition: dmap.h:241
const GLcharARB * name
Definition: glext.h:3629
mapTri_t * triList
Definition: dmap.h:207
interAreaPortal_t interAreaPortals[MAX_INTER_AREA_PORTALS]
Definition: portals.cpp:35
int CountTriList(const mapTri_t *list)
Definition: tritools.cpp:125
Definition: Str.h:116
struct optimizeGroup_s * nextGroup
Definition: dmap.h:189
void * Mem_ClearedAlloc(const int size)
Definition: Heap.cpp:1149
const char * c_str(void) const
Definition: Str.h:487
#define DotProduct(a, b)
Definition: Vector.h:1994
glIndex_t * indexes
Definition: Model.h:102
const idMaterial * material
Definition: dmap.h:197
void R_AllocStaticTriSurfIndexes(srfTriangles_t *tri, int numIndexes)
Definition: tr_trisurf.cpp:565
Definition: dmap.h:138
GLint j
Definition: qgl.h:264
int numIndexes
Definition: Model.h:101
dmapGlobals_t dmapGlobals
Definition: dmap.cpp:34
int area
Definition: dmap.h:155
virtual void CloseFile(idFile *f)=0
void R_CreateSilIndexes(srfTriangles_t *tri)
Definition: tr_trisurf.cpp:765
virtual void Error(const char *fmt,...) id_attribute((format(printf
void R_AllocStaticTriSurfVerts(srfTriangles_t *tri, int numVerts)
Definition: tr_trisurf.cpp:555
idMapEntity * mapEntity
Definition: dmap.h:47
void R_RangeCheckIndexes(const srfTriangles_t *tri)
Definition: tr_trisurf.cpp:671
int sprintf(idStr &string, const char *fmt,...)
Definition: Str.cpp:1528
char name[MAX_QPATH]
Definition: dmap.h:182
idDrawVert * verts
Definition: Model.h:99
int numAreas
Definition: dmap.h:53