doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
tritjunction.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  T junction fixing never creates more xyz points, but
37  new vertexes will be created when different surfaces
38  cause a fix
39 
40  The vertex cleaning accomplishes two goals: removing extranious low order
41  bits to avoid numbers like 1.000001233, and grouping nearby vertexes
42  together. Straight truncation accomplishes the first foal, but two vertexes
43  only a tiny epsilon apart could still be spread to different snap points.
44  To avoid this, we allow the merge test to group points together that
45  snapped to neighboring integer coordinates.
46 
47  Snaping verts can drag some triangles backwards or collapse them to points,
48  which will cause them to be removed.
49 
50 
51  When snapping to ints, a point can move a maximum of sqrt(3)/2 distance
52  Two points that were an epsilon apart can then become sqrt(3) apart
53 
54  A case that causes recursive overflow with point to triangle fixing:
55 
56  A
57  C D
58  B
59 
60  Triangle ABC tests against point D and splits into triangles ADC and DBC
61  Triangle DBC then tests against point A again and splits into ABC and ADB
62  infinite recursive loop
63 
64 
65  For a given source triangle
66  init the no-check list to hold the three triangle hashVerts
67 
68  recursiveFixTriAgainstHash
69 
70  recursiveFixTriAgainstHashVert_r
71  if hashVert is on the no-check list
72  exit
73  if the hashVert should split the triangle
74  add to the no-check list
75  recursiveFixTriAgainstHash(a)
76  recursiveFixTriAgainstHash(b)
77 
78 */
79 
80 #define SNAP_FRACTIONS 32
81 //#define SNAP_FRACTIONS 8
82 //#define SNAP_FRACTIONS 1
83 
84 #define VERTEX_EPSILON ( 1.0 / SNAP_FRACTIONS )
85 
86 #define COLINEAR_EPSILON ( 1.8 * VERTEX_EPSILON )
87 
88 #define HASH_BINS 16
89 
90 typedef struct hashVert_s {
91  struct hashVert_s *next;
93  int iv[3];
94 } hashVert_t;
95 
96 static idBounds hashBounds;
97 static idVec3 hashScale;
98 static hashVert_t *hashVerts[HASH_BINS][HASH_BINS][HASH_BINS];
99 static int numHashVerts, numTotalVerts;
100 static int hashIntMins[3], hashIntScale[3];
101 
102 /*
103 ===============
104 GetHashVert
105 
106 Also modifies the original vert to the snapped value
107 ===============
108 */
110  int iv[3];
111  int block[3];
112  int i;
113  hashVert_t *hv;
114 
115  numTotalVerts++;
116 
117  // snap the vert to integral values
118  for ( i = 0 ; i < 3 ; i++ ) {
119  iv[i] = floor( ( v[i] + 0.5/SNAP_FRACTIONS ) * SNAP_FRACTIONS );
120  block[i] = ( iv[i] - hashIntMins[i] ) / hashIntScale[i];
121  if ( block[i] < 0 ) {
122  block[i] = 0;
123  } else if ( block[i] >= HASH_BINS ) {
124  block[i] = HASH_BINS - 1;
125  }
126  }
127 
128  // see if a vertex near enough already exists
129  // this could still fail to find a near neighbor right at the hash block boundary
130  for ( hv = hashVerts[block[0]][block[1]][block[2]] ; hv ; hv = hv->next ) {
131 #if 0
132  if ( hv->iv[0] == iv[0] && hv->iv[1] == iv[1] && hv->iv[2] == iv[2] ) {
133  VectorCopy( hv->v, v );
134  return hv;
135  }
136 #else
137  for ( i = 0 ; i < 3 ; i++ ) {
138  int d;
139  d = hv->iv[i] - iv[i];
140  if ( d < -1 || d > 1 ) {
141  break;
142  }
143  }
144  if ( i == 3 ) {
145  VectorCopy( hv->v, v );
146  return hv;
147  }
148 #endif
149  }
150 
151  // create a new one
152  hv = (hashVert_t *)Mem_Alloc( sizeof( *hv ) );
153 
154  hv->next = hashVerts[block[0]][block[1]][block[2]];
155  hashVerts[block[0]][block[1]][block[2]] = hv;
156 
157  hv->iv[0] = iv[0];
158  hv->iv[1] = iv[1];
159  hv->iv[2] = iv[2];
160 
161  hv->v[0] = (float)iv[0] / SNAP_FRACTIONS;
162  hv->v[1] = (float)iv[1] / SNAP_FRACTIONS;
163  hv->v[2] = (float)iv[2] / SNAP_FRACTIONS;
164 
165  VectorCopy( hv->v, v );
166 
167  numHashVerts++;
168 
169  return hv;
170 }
171 
172 
173 /*
174 ==================
175 HashBlocksForTri
176 
177 Returns an inclusive bounding box of hash
178 bins that should hold the triangle
179 ==================
180 */
181 static void HashBlocksForTri( const mapTri_t *tri, int blocks[2][3] ) {
182  idBounds bounds;
183  int i;
184 
185  bounds.Clear();
186  bounds.AddPoint( tri->v[0].xyz );
187  bounds.AddPoint( tri->v[1].xyz );
188  bounds.AddPoint( tri->v[2].xyz );
189 
190  // add a 1.0 slop margin on each side
191  for ( i = 0 ; i < 3 ; i++ ) {
192  blocks[0][i] = ( bounds[0][i] - 1.0 - hashBounds[0][i] ) / hashScale[i];
193  if ( blocks[0][i] < 0 ) {
194  blocks[0][i] = 0;
195  } else if ( blocks[0][i] >= HASH_BINS ) {
196  blocks[0][i] = HASH_BINS - 1;
197  }
198 
199  blocks[1][i] = ( bounds[1][i] + 1.0 - hashBounds[0][i] ) / hashScale[i];
200  if ( blocks[1][i] < 0 ) {
201  blocks[1][i] = 0;
202  } else if ( blocks[1][i] >= HASH_BINS ) {
203  blocks[1][i] = HASH_BINS - 1;
204  }
205  }
206 }
207 
208 
209 /*
210 =================
211 HashTriangles
212 
213 Removes triangles that are degenerated or flipped backwards
214 =================
215 */
216 void HashTriangles( optimizeGroup_t *groupList ) {
217  mapTri_t *a;
218  int vert;
219  int i;
220  optimizeGroup_t *group;
221 
222  // clear the hash tables
223  memset( hashVerts, 0, sizeof( hashVerts ) );
224 
225  numHashVerts = 0;
226  numTotalVerts = 0;
227 
228  // bound all the triangles to determine the bucket size
229  hashBounds.Clear();
230  for ( group = groupList ; group ; group = group->nextGroup ) {
231  for ( a = group->triList ; a ; a = a->next ) {
232  hashBounds.AddPoint( a->v[0].xyz );
233  hashBounds.AddPoint( a->v[1].xyz );
234  hashBounds.AddPoint( a->v[2].xyz );
235  }
236  }
237 
238  // spread the bounds so it will never have a zero size
239  for ( i = 0 ; i < 3 ; i++ ) {
240  hashBounds[0][i] = floor( hashBounds[0][i] - 1 );
241  hashBounds[1][i] = ceil( hashBounds[1][i] + 1 );
242  hashIntMins[i] = hashBounds[0][i] * SNAP_FRACTIONS;
243 
244  hashScale[i] = ( hashBounds[1][i] - hashBounds[0][i] ) / HASH_BINS;
245  hashIntScale[i] = hashScale[i] * SNAP_FRACTIONS;
246  if ( hashIntScale[i] < 1 ) {
247  hashIntScale[i] = 1;
248  }
249  }
250 
251  // add all the points to the hash buckets
252  for ( group = groupList ; group ; group = group->nextGroup ) {
253  // don't create tjunctions against discrete surfaces (blood decals, etc)
254  if ( group->material != NULL && group->material->IsDiscrete() ) {
255  continue;
256  }
257  for ( a = group->triList ; a ; a = a->next ) {
258  for ( vert = 0 ; vert < 3 ; vert++ ) {
259  a->hashVert[vert] = GetHashVert( a->v[vert].xyz );
260  }
261  }
262  }
263 }
264 
265 /*
266 =================
267 FreeTJunctionHash
268 
269 The optimizer may add some more crossing verts
270 after t junction processing
271 =================
272 */
273 void FreeTJunctionHash( void ) {
274  int i, j, k;
275  hashVert_t *hv, *next;
276 
277  for ( i = 0 ; i < HASH_BINS ; i++ ) {
278  for ( j = 0 ; j < HASH_BINS ; j++ ) {
279  for ( k = 0 ; k < HASH_BINS ; k++ ) {
280  for ( hv = hashVerts[i][j][k] ; hv ; hv = next ) {
281  next = hv->next;
282  Mem_Free( hv );
283  }
284  }
285  }
286  }
287  memset( hashVerts, 0, sizeof( hashVerts ) );
288 }
289 
290 
291 /*
292 ==================
293 FixTriangleAgainstHashVert
294 
295 Returns a list of two new mapTri if the hashVert is
296 on an edge of the given mapTri, otherwise returns NULL.
297 ==================
298 */
299 static mapTri_t *FixTriangleAgainstHashVert( const mapTri_t *a, const hashVert_t *hv ) {
300  int i;
301  const idDrawVert *v1, *v2, *v3;
302  idDrawVert split;
303  idVec3 dir;
304  float len;
305  float frac;
306  mapTri_t *new1, *new2;
307  idVec3 temp;
308  float d, off;
309  const idVec3 *v;
310  idPlane plane1, plane2;
311 
312  v = &hv->v;
313 
314  // if the triangle already has this hashVert as a vert,
315  // it can't be split by it
316  if ( a->hashVert[0] == hv || a->hashVert[1] == hv || a->hashVert[2] == hv ) {
317  return NULL;
318  }
319 
320  // we probably should find the edge that the vertex is closest to.
321  // it is possible to be < 1 unit away from multiple
322  // edges, but we only want to split by one of them
323  for ( i = 0 ; i < 3 ; i++ ) {
324  v1 = &a->v[i];
325  v2 = &a->v[(i+1)%3];
326  v3 = &a->v[(i+2)%3];
327  VectorSubtract( v2->xyz, v1->xyz, dir );
328  len = dir.Normalize();
329 
330  // if it is close to one of the edge vertexes, skip it
331  VectorSubtract( *v, v1->xyz, temp );
332  d = DotProduct( temp, dir );
333  if ( d <= 0 || d >= len ) {
334  continue;
335  }
336 
337  // make sure it is on the line
338  VectorMA( v1->xyz, d, dir, temp );
339  VectorSubtract( temp, *v, temp );
340  off = temp.Length();
341  if ( off <= -COLINEAR_EPSILON || off >= COLINEAR_EPSILON ) {
342  continue;
343  }
344 
345  // take the x/y/z from the splitter,
346  // but interpolate everything else from the original tri
347  VectorCopy( *v, split.xyz );
348  frac = d / len;
349  split.st[0] = v1->st[0] + frac * ( v2->st[0] - v1->st[0] );
350  split.st[1] = v1->st[1] + frac * ( v2->st[1] - v1->st[1] );
351  split.normal[0] = v1->normal[0] + frac * ( v2->normal[0] - v1->normal[0] );
352  split.normal[1] = v1->normal[1] + frac * ( v2->normal[1] - v1->normal[1] );
353  split.normal[2] = v1->normal[2] + frac * ( v2->normal[2] - v1->normal[2] );
354  split.normal.Normalize();
355 
356  // split the tri
357  new1 = CopyMapTri( a );
358  new1->v[(i+1)%3] = split;
359  new1->hashVert[(i+1)%3] = hv;
360  new1->next = NULL;
361 
362  new2 = CopyMapTri( a );
363  new2->v[i] = split;
364  new2->hashVert[i] = hv;
365  new2->next = new1;
366 
367  plane1.FromPoints( new1->hashVert[0]->v, new1->hashVert[1]->v, new1->hashVert[2]->v );
368  plane2.FromPoints( new2->hashVert[0]->v, new2->hashVert[1]->v, new2->hashVert[2]->v );
369 
370  d = DotProduct( plane1, plane2 );
371 
372  // if the two split triangle's normals don't face the same way,
373  // it should not be split
374  if ( d <= 0 ) {
375  FreeTriList( new2 );
376  continue;
377  }
378 
379  return new2;
380  }
381 
382 
383  return NULL;
384 }
385 
386 
387 
388 /*
389 ==================
390 FixTriangleAgainstHash
391 
392 Potentially splits a triangle into a list of triangles based on tjunctions
393 ==================
394 */
395 static mapTri_t *FixTriangleAgainstHash( const mapTri_t *tri ) {
396  mapTri_t *fixed;
397  mapTri_t *a;
398  mapTri_t *test, *next;
399  int blocks[2][3];
400  int i, j, k;
401  hashVert_t *hv;
402 
403  // if this triangle is degenerate after point snapping,
404  // do nothing (this shouldn't happen, because they should
405  // be removed as they are hashed)
406  if ( tri->hashVert[0] == tri->hashVert[1]
407  || tri->hashVert[0] == tri->hashVert[2]
408  || tri->hashVert[1] == tri->hashVert[2] ) {
409  return NULL;
410  }
411 
412  fixed = CopyMapTri( tri );
413  fixed->next = NULL;
414 
415  HashBlocksForTri( tri, blocks );
416  for ( i = blocks[0][0] ; i <= blocks[1][0] ; i++ ) {
417  for ( j = blocks[0][1] ; j <= blocks[1][1] ; j++ ) {
418  for ( k = blocks[0][2] ; k <= blocks[1][2] ; k++ ) {
419  for ( hv = hashVerts[i][j][k] ; hv ; hv = hv->next ) {
420  // fix all triangles in the list against this point
421  test = fixed;
422  fixed = NULL;
423  for ( ; test ; test = next ) {
424  next = test->next;
425  a = FixTriangleAgainstHashVert( test, hv );
426  if ( a ) {
427  // cut into two triangles
428  a->next->next = fixed;
429  fixed = a;
430  FreeTri( test );
431  } else {
432  test->next = fixed;
433  fixed = test;
434  }
435  }
436  }
437  }
438  }
439  }
440 
441  return fixed;
442 }
443 
444 
445 /*
446 ==================
447 CountGroupListTris
448 ==================
449 */
450 int CountGroupListTris( const optimizeGroup_t *groupList ) {
451  int c;
452 
453  c = 0;
454  for ( ; groupList ; groupList = groupList->nextGroup ) {
455  c += CountTriList( groupList->triList );
456  }
457 
458  return c;
459 }
460 
461 /*
462 ==================
463 FixAreaGroupsTjunctions
464 ==================
465 */
467  const mapTri_t *tri;
468  mapTri_t *newList;
469  mapTri_t *fixed;
470  int startCount, endCount;
471  optimizeGroup_t *group;
472 
473  if ( dmapGlobals.noTJunc ) {
474  return;
475  }
476 
477  if ( !groupList ) {
478  return;
479  }
480 
481  startCount = CountGroupListTris( groupList );
482 
483  if ( dmapGlobals.verbose ) {
484  common->Printf( "----- FixAreaGroupsTjunctions -----\n" );
485  common->Printf( "%6i triangles in\n", startCount );
486  }
487 
488  HashTriangles( groupList );
489 
490  for ( group = groupList ; group ; group = group->nextGroup ) {
491  // don't touch discrete surfaces
492  if ( group->material != NULL && group->material->IsDiscrete() ) {
493  continue;
494  }
495 
496  newList = NULL;
497  for ( tri = group->triList ; tri ; tri = tri->next ) {
498  fixed = FixTriangleAgainstHash( tri );
499  newList = MergeTriLists( newList, fixed );
500  }
501  FreeTriList( group->triList );
502  group->triList = newList;
503  }
504 
505  endCount = CountGroupListTris( groupList );
506  if ( dmapGlobals.verbose ) {
507  common->Printf( "%6i triangles out\n", endCount );
508  }
509 }
510 
511 
512 /*
513 ==================
514 FixEntityTjunctions
515 ==================
516 */
518  int i;
519 
520  for ( i = 0 ; i < e->numAreas ; i++ ) {
523  }
524 }
525 
526 /*
527 ==================
528 FixGlobalTjunctions
529 ==================
530 */
532  mapTri_t *a;
533  int vert;
534  int i;
535  optimizeGroup_t *group;
536  int areaNum;
537 
538  common->Printf( "----- FixGlobalTjunctions -----\n" );
539 
540  // clear the hash tables
541  memset( hashVerts, 0, sizeof( hashVerts ) );
542 
543  numHashVerts = 0;
544  numTotalVerts = 0;
545 
546  // bound all the triangles to determine the bucket size
547  hashBounds.Clear();
548  for ( areaNum = 0 ; areaNum < e->numAreas ; areaNum++ ) {
549  for ( group = e->areas[areaNum].groups ; group ; group = group->nextGroup ) {
550  for ( a = group->triList ; a ; a = a->next ) {
551  hashBounds.AddPoint( a->v[0].xyz );
552  hashBounds.AddPoint( a->v[1].xyz );
553  hashBounds.AddPoint( a->v[2].xyz );
554  }
555  }
556  }
557 
558  // spread the bounds so it will never have a zero size
559  for ( i = 0 ; i < 3 ; i++ ) {
560  hashBounds[0][i] = floor( hashBounds[0][i] - 1 );
561  hashBounds[1][i] = ceil( hashBounds[1][i] + 1 );
562  hashIntMins[i] = hashBounds[0][i] * SNAP_FRACTIONS;
563 
564  hashScale[i] = ( hashBounds[1][i] - hashBounds[0][i] ) / HASH_BINS;
565  hashIntScale[i] = hashScale[i] * SNAP_FRACTIONS;
566  if ( hashIntScale[i] < 1 ) {
567  hashIntScale[i] = 1;
568  }
569  }
570 
571  // add all the points to the hash buckets
572  for ( areaNum = 0 ; areaNum < e->numAreas ; areaNum++ ) {
573  for ( group = e->areas[areaNum].groups ; group ; group = group->nextGroup ) {
574  // don't touch discrete surfaces
575  if ( group->material != NULL && group->material->IsDiscrete() ) {
576  continue;
577  }
578 
579  for ( a = group->triList ; a ; a = a->next ) {
580  for ( vert = 0 ; vert < 3 ; vert++ ) {
581  a->hashVert[vert] = GetHashVert( a->v[vert].xyz );
582  }
583  }
584  }
585  }
586 
587  // add all the func_static model vertexes to the hash buckets
588  // optionally inline some of the func_static models
589  if ( dmapGlobals.entityNum == 0 ) {
590  for ( int eNum = 1 ; eNum < dmapGlobals.num_entities ; eNum++ ) {
591  uEntity_t *entity = &dmapGlobals.uEntities[eNum];
592  const char *className = entity->mapEntity->epairs.GetString( "classname" );
593  if ( idStr::Icmp( className, "func_static" ) ) {
594  continue;
595  }
596  const char *modelName = entity->mapEntity->epairs.GetString( "model" );
597  if ( !modelName ) {
598  continue;
599  }
600  if ( !strstr( modelName, ".lwo" ) && !strstr( modelName, ".ase" ) && !strstr( modelName, ".ma" ) ) {
601  continue;
602  }
603 
604  idRenderModel *model = renderModelManager->FindModel( modelName );
605 
606 // common->Printf( "adding T junction verts for %s.\n", entity->mapEntity->epairs.GetString( "name" ) );
607 
608  idMat3 axis;
609  // get the rotation matrix in either full form, or single angle form
610  if ( !entity->mapEntity->epairs.GetMatrix( "rotation", "1 0 0 0 1 0 0 0 1", axis ) ) {
611  float angle = entity->mapEntity->epairs.GetFloat( "angle" );
612  if ( angle != 0.0f ) {
613  axis = idAngles( 0.0f, angle, 0.0f ).ToMat3();
614  } else {
615  axis.Identity();
616  }
617  }
618 
619  idVec3 origin = entity->mapEntity->epairs.GetVector( "origin" );
620 
621  for ( i = 0 ; i < model->NumSurfaces() ; i++ ) {
622  const modelSurface_t *surface = model->Surface( i );
623  const srfTriangles_t *tri = surface->geometry;
624 
625  mapTri_t mapTri;
626  memset( &mapTri, 0, sizeof( mapTri ) );
627  mapTri.material = surface->shader;
628  // don't let discretes (autosprites, etc) merge together
629  if ( mapTri.material->IsDiscrete() ) {
630  mapTri.mergeGroup = (void *)surface;
631  }
632  for ( int j = 0 ; j < tri->numVerts ; j += 3 ) {
633  idVec3 v = tri->verts[j].xyz * axis + origin;
634  GetHashVert( v );
635  }
636  }
637  }
638  }
639 
640 
641 
642  // now fix each area
643  for ( areaNum = 0 ; areaNum < e->numAreas ; areaNum++ ) {
644  for ( group = e->areas[areaNum].groups ; group ; group = group->nextGroup ) {
645  // don't touch discrete surfaces
646  if ( group->material != NULL && group->material->IsDiscrete() ) {
647  continue;
648  }
649 
650  mapTri_t *newList = NULL;
651  for ( mapTri_t *tri = group->triList ; tri ; tri = tri->next ) {
652  mapTri_t *fixed = FixTriangleAgainstHash( tri );
653  newList = MergeTriLists( newList, fixed );
654  }
655  FreeTriList( group->triList );
656  group->triList = newList;
657  }
658  }
659 
660 
661  // done
663 }
float GetFloat(const char *key, const char *defaultString="0") const
Definition: Dict.h:248
#define SNAP_FRACTIONS
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
struct mapTri_s * next
Definition: dmap.h:60
int numVerts
Definition: Model.h:98
mapTri_t * CopyMapTri(const mapTri_t *tri)
Definition: tritools.cpp:143
const GLdouble * v
Definition: glext.h:2936
#define VectorSubtract(a, b, c)
Definition: Vector.h:1995
idVec3 xyz
Definition: DrawVert.h:42
void * mergeGroup
Definition: dmap.h:63
#define VectorCopy(a, b)
Definition: Vector.h:1999
#define HASH_BINS
const idMaterial * shader
Definition: Model.h:146
void FixAreaGroupsTjunctions(optimizeGroup_t *groupList)
Definition: Vector.h:316
const struct hashVert_s * hashVert[3]
Definition: dmap.h:68
case const float
Definition: Callbacks.cpp:62
void FreeTri(mapTri_t *tri)
Definition: tritools.cpp:58
uArea_t * areas
Definition: dmap.h:54
void FixEntityTjunctions(uEntity_t *e)
void Clear(void)
Definition: Bounds.h:201
bool verbose
Definition: dmap.h:248
void FreeTJunctionHash(void)
struct hashVert_s * GetHashVert(idVec3 &v)
GLenum GLsizei len
Definition: glext.h:3472
void Identity(void)
Definition: Matrix.h:591
int i
Definition: process.py:33
mapTri_t * MergeTriLists(mapTri_t *a, mapTri_t *b)
Definition: tritools.cpp:70
int test(char *url)
Definition: lib500.c:3
int Icmp(const char *text) const
Definition: Str.h:667
idDict epairs
Definition: MapFile.h:166
void FreeTriList(mapTri_t *a)
Definition: tritools.cpp:89
int CountGroupListTris(const optimizeGroup_t *groupList)
idDrawVert v[3]
Definition: dmap.h:67
struct optimizeGroup_s * groups
Definition: dmap.h:42
bool AddPoint(const idVec3 &v)
Definition: Bounds.h:226
idVec2 st
Definition: DrawVert.h:43
GLfloat GLfloat GLfloat v2
Definition: glext.h:3608
const GLubyte * c
Definition: glext.h:4677
const char * GetString(const char *key, const char *defaultString="") const
Definition: Dict.h:240
float Length(void) const
Definition: Vector.h:631
idCommon * common
Definition: Common.cpp:206
#define NULL
Definition: Lib.h:88
srfTriangles_t * geometry
Definition: Model.h:147
virtual idRenderModel * FindModel(const char *modelName)=0
idVec3 GetVector(const char *key, const char *defaultString=NULL) const
Definition: Dict.h:260
virtual const modelSurface_t * Surface(int surfaceNum) const =0
Definition: Plane.h:71
void Mem_Free(void *ptr)
Definition: Heap.cpp:1087
idVec3 normal
Definition: DrawVert.h:44
GLubyte GLubyte GLubyte a
Definition: glext.h:4662
virtual void Printf(const char *fmt,...) id_attribute((format(printf
GLfloat GLfloat v1
Definition: glext.h:3607
int entityNum
Definition: dmap.h:244
uEntity_t * uEntities
Definition: dmap.h:242
#define COLINEAR_EPSILON
GLfloat GLfloat GLfloat GLfloat v3
Definition: glext.h:3609
idRenderModelManager * renderModelManager
Definition: Matrix.h:333
Definition: dmap.h:59
void HashTriangles(optimizeGroup_t *groupList)
const idMaterial * material
Definition: dmap.h:62
tuple f
Definition: idal.py:89
Definition: dmap.h:46
idMat3 ToMat3(void) const
Definition: Angles.cpp:199
int num_entities
Definition: dmap.h:241
mapTri_t * triList
Definition: dmap.h:207
int CountTriList(const mapTri_t *list)
Definition: tritools.cpp:125
struct hashVert_s * next
struct optimizeGroup_s * nextGroup
Definition: dmap.h:189
#define DotProduct(a, b)
Definition: Vector.h:1994
const idMaterial * material
Definition: dmap.h:197
void * Mem_Alloc(const int size)
Definition: Heap.cpp:1067
GLint j
Definition: qgl.h:264
#define VectorMA(v, s, b, o)
Definition: Vector.h:1998
idMat3 GetMatrix(const char *key, const char *defaultString=NULL) const
Definition: Dict.h:284
dmapGlobals_t dmapGlobals
Definition: dmap.cpp:34
void FixGlobalTjunctions(uEntity_t *e)
bool IsDiscrete(void) const
Definition: Material.h:441
bool noTJunc
Definition: dmap.h:256
idMapEntity * mapEntity
Definition: dmap.h:47
struct hashVert_s hashVert_t
idDrawVert * verts
Definition: Model.h:99
int numAreas
Definition: dmap.h:53
virtual int NumSurfaces() const =0