doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
tritools.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  All triangle list functions should behave reasonably with NULL lists.
37 
38 */
39 
40 /*
41 ===============
42 AllocTri
43 ===============
44 */
45 mapTri_t *AllocTri( void ) {
46  mapTri_t *tri;
47 
48  tri = (mapTri_t *)Mem_Alloc( sizeof( *tri ) );
49  memset( tri, 0, sizeof( *tri ) );
50  return tri;
51 }
52 
53 /*
54 ===============
55 FreeTri
56 ===============
57 */
58 void FreeTri( mapTri_t *tri ) {
59  Mem_Free( tri );
60 }
61 
62 
63 /*
64 ===============
65 MergeTriLists
66 
67 This does not copy any tris, it just relinks them
68 ===============
69 */
71  mapTri_t **prev;
72 
73  prev = &a;
74  while ( *prev ) {
75  prev = &(*prev)->next;
76  }
77 
78  *prev = b;
79 
80  return a;
81 }
82 
83 
84 /*
85 ===============
86 FreeTriList
87 ===============
88 */
90  mapTri_t *next;
91 
92  for ( ; a ; a = next ) {
93  next = a->next;
94  Mem_Free( a );
95  }
96 }
97 
98 /*
99 ===============
100 CopyTriList
101 ===============
102 */
104  mapTri_t *testList;
105  const mapTri_t *tri;
106 
107  testList = NULL;
108  for ( tri = a ; tri ; tri = tri->next ) {
109  mapTri_t *copy;
110 
111  copy = CopyMapTri( tri );
112  copy ->next = testList;
113  testList = copy;
114  }
115 
116  return testList;
117 }
118 
119 
120 /*
121 =============
122 CountTriList
123 =============
124 */
125 int CountTriList( const mapTri_t *tri ) {
126  int c;
127 
128  c = 0;
129  while ( tri ) {
130  c++;
131  tri = tri->next;
132  }
133 
134  return c;
135 }
136 
137 
138 /*
139 ===============
140 CopyMapTri
141 ===============
142 */
143 mapTri_t *CopyMapTri( const mapTri_t *tri ) {
144  mapTri_t *t;
145 
146  t = (mapTri_t *)Mem_Alloc( sizeof( *t ) );
147  *t = *tri;
148 
149  return t;
150 }
151 
152 /*
153 ===============
154 MapTriArea
155 ===============
156 */
157 float MapTriArea( const mapTri_t *tri ) {
158  return idWinding::TriangleArea( tri->v[0].xyz, tri->v[1].xyz, tri->v[2].xyz );
159 }
160 
161 /*
162 ===============
163 RemoveBadTris
164 
165 Return a new list with any zero or negative area triangles removed
166 ===============
167 */
168 mapTri_t *RemoveBadTris( const mapTri_t *list ) {
169  mapTri_t *newList;
170  mapTri_t *copy;
171  const mapTri_t *tri;
172 
173  newList = NULL;
174 
175  for ( tri = list ; tri ; tri = tri->next ) {
176  if ( MapTriArea( tri ) > 0 ) {
177  copy = CopyMapTri( tri );
178  copy->next = newList;
179  newList = copy;
180  }
181  }
182 
183  return newList;
184 }
185 
186 /*
187 ================
188 BoundTriList
189 ================
190 */
191 void BoundTriList( const mapTri_t *list, idBounds &b ) {
192  b.Clear();
193  for ( ; list ; list = list->next ) {
194  b.AddPoint( list->v[0].xyz );
195  b.AddPoint( list->v[1].xyz );
196  b.AddPoint( list->v[2].xyz );
197  }
198 }
199 
200 /*
201 ================
202 DrawTri
203 ================
204 */
205 void DrawTri( const mapTri_t *tri ) {
206  idWinding w;
207 
208  w.SetNumPoints( 3 );
209  VectorCopy( tri->v[0].xyz, w[0] );
210  VectorCopy( tri->v[1].xyz, w[1] );
211  VectorCopy( tri->v[2].xyz, w[2] );
212  DrawWinding( &w );
213 }
214 
215 
216 /*
217 ================
218 FlipTriList
219 
220 Swaps the vertex order
221 ================
222 */
223 void FlipTriList( mapTri_t *tris ) {
224  mapTri_t *tri;
225 
226  for ( tri = tris ; tri ; tri = tri->next ) {
227  idDrawVert v;
228  const struct hashVert_s *hv;
229  struct optVertex_s *ov;
230 
231  v = tri->v[0];
232  tri->v[0] = tri->v[2];
233  tri->v[2] = v;
234 
235  hv = tri->hashVert[0];
236  tri->hashVert[0] = tri->hashVert[2];
237  tri->hashVert[2] = hv;
238 
239  ov = tri->optVert[0];
240  tri->optVert[0] = tri->optVert[2];
241  tri->optVert[2] = ov;
242  }
243 }
244 
245 /*
246 ================
247 WindingForTri
248 ================
249 */
251  idWinding *w;
252 
253  w = new idWinding( 3 );
254  w->SetNumPoints( 3 );
255  VectorCopy( tri->v[0].xyz, (*w)[0] );
256  VectorCopy( tri->v[1].xyz, (*w)[1] );
257  VectorCopy( tri->v[2].xyz, (*w)[2] );
258 
259  return w;
260 }
261 
262 /*
263 ================
264 TriVertsFromOriginal
265 
266 Regenerate the texcoords and colors on a fragmented tri from the plane equations
267 ================
268 */
269 void TriVertsFromOriginal( mapTri_t *tri, const mapTri_t *original ) {
270  int i, j;
271  float denom;
272 
273  denom = idWinding::TriangleArea( original->v[0].xyz, original->v[1].xyz, original->v[2].xyz );
274  if ( denom == 0 ) {
275  return; // original was degenerate, so it doesn't matter
276  }
277 
278  for ( i = 0 ; i < 3 ; i++ ) {
279  float a, b, c;
280 
281  // find the barycentric coordinates
282  a = idWinding::TriangleArea( tri->v[i].xyz, original->v[1].xyz, original->v[2].xyz ) / denom;
283  b = idWinding::TriangleArea( tri->v[i].xyz, original->v[2].xyz, original->v[0].xyz ) / denom;
284  c = idWinding::TriangleArea( tri->v[i].xyz, original->v[0].xyz, original->v[1].xyz ) / denom;
285 
286  // regenerate the interpolated values
287  tri->v[i].st[0] = a * original->v[0].st[0]
288  + b * original->v[1].st[0] + c * original->v[2].st[0];
289  tri->v[i].st[1] = a * original->v[0].st[1]
290  + b * original->v[1].st[1] + c * original->v[2].st[1];
291 
292  for ( j = 0 ; j < 3 ; j++ ) {
293  tri->v[i].normal[j] = a * original->v[0].normal[j]
294  + b * original->v[1].normal[j] + c * original->v[2].normal[j];
295  }
296  tri->v[i].normal.Normalize();
297  }
298 }
299 
300 /*
301 ================
302 WindingToTriList
303 
304 Generates a new list of triangles with proper texcoords from a winding
305 created by clipping the originalTri
306 
307 OriginalTri can be NULL if you don't care about texCoords
308 ================
309 */
310 mapTri_t *WindingToTriList( const idWinding *w, const mapTri_t *originalTri ) {
311  mapTri_t *tri;
312  mapTri_t *triList;
313  int i, j;
314  const idVec3 *vec;
315 
316  if ( !w ) {
317  return NULL;
318  }
319 
320  triList = NULL;
321  for ( i = 2 ; i < w->GetNumPoints() ; i++ ) {
322  tri = AllocTri();
323  if ( !originalTri ) {
324  memset( tri, 0, sizeof( *tri ) );
325  } else {
326  *tri = *originalTri;
327  }
328  tri->next = triList;
329  triList = tri;
330 
331  for ( j = 0 ; j < 3 ; j++ ) {
332  if ( j == 0 ) {
333  vec = &((*w)[0]).ToVec3();
334  } else if ( j == 1 ) {
335  vec = &((*w)[i-1]).ToVec3();
336  } else {
337  vec = &((*w)[i]).ToVec3();
338  }
339 
340  VectorCopy( *vec, tri->v[j].xyz );
341  }
342  if ( originalTri ) {
343  TriVertsFromOriginal( tri, originalTri );
344  }
345  }
346 
347  return triList;
348 }
349 
350 
351 /*
352 ==================
353 ClipTriList
354 ==================
355 */
356 void ClipTriList( const mapTri_t *list, const idPlane &plane, float epsilon,
357  mapTri_t **front, mapTri_t **back ) {
358  const mapTri_t *tri;
359  mapTri_t *newList;
360  idWinding *w, *frontW, *backW;
361 
362  *front = NULL;
363  *back = NULL;
364 
365  for ( tri = list ; tri ; tri = tri->next ) {
366  w = WindingForTri( tri );
367  w->Split( plane, epsilon, &frontW, &backW );
368 
369  newList = WindingToTriList( frontW, tri );
370  *front = MergeTriLists( *front, newList );
371 
372  newList = WindingToTriList( backW, tri );
373  *back = MergeTriLists( *back, newList );
374 
375  delete w;
376  }
377 
378 }
379 
380 /*
381 ==================
382 PlaneForTri
383 ==================
384 */
385 void PlaneForTri( const mapTri_t *tri, idPlane &plane ) {
386  plane.FromPoints( tri->v[0].xyz, tri->v[1].xyz, tri->v[2].xyz );
387 }
void DrawWinding(const idWinding *w)
Definition: gldraw.cpp:276
float Normalize(void)
Definition: Vector.h:646
void BoundTriList(const mapTri_t *list, idBounds &b)
Definition: tritools.cpp:191
bool FromPoints(const idVec3 &p1, const idVec3 &p2, const idVec3 &p3, bool fixDegenerate=true)
Definition: Plane.h:279
idWinding * WindingForTri(const mapTri_t *tri)
Definition: tritools.cpp:250
struct mapTri_s * next
Definition: dmap.h:60
const GLdouble * v
Definition: glext.h:2936
mapTri_t * WindingToTriList(const idWinding *w, const mapTri_t *originalTri)
Definition: tritools.cpp:310
idVec3 xyz
Definition: DrawVert.h:42
void ClipTriList(const mapTri_t *list, const idPlane &plane, float epsilon, mapTri_t **front, mapTri_t **back)
Definition: tritools.cpp:356
#define VectorCopy(a, b)
Definition: Vector.h:1999
Definition: Vector.h:316
const struct hashVert_s * hashVert[3]
Definition: dmap.h:68
void Clear(void)
Definition: Bounds.h:201
int i
Definition: process.py:33
idDrawVert v[3]
Definition: dmap.h:67
bool AddPoint(const idVec3 &v)
Definition: Bounds.h:226
idVec2 st
Definition: DrawVert.h:43
void FreeTri(mapTri_t *tri)
Definition: tritools.cpp:58
void TriVertsFromOriginal(mapTri_t *tri, const mapTri_t *original)
Definition: tritools.cpp:269
int GetNumPoints(void) const
Definition: Winding.h:238
const GLubyte * c
Definition: glext.h:4677
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:3454
static float TriangleArea(const idVec3 &a, const idVec3 &b, const idVec3 &c)
Definition: Winding.cpp:1446
#define NULL
Definition: Lib.h:88
void FlipTriList(mapTri_t *tris)
Definition: tritools.cpp:223
Definition: Plane.h:71
struct optVertex_s * optVert[3]
Definition: dmap.h:69
void Mem_Free(void *ptr)
Definition: Heap.cpp:1087
idVec3 normal
Definition: DrawVert.h:44
void FreeTriList(mapTri_t *a)
Definition: tritools.cpp:89
GLubyte GLubyte GLubyte a
Definition: glext.h:4662
void PlaneForTri(const mapTri_t *tri, idPlane &plane)
Definition: tritools.cpp:385
GLubyte GLubyte b
Definition: glext.h:4662
int CountTriList(const mapTri_t *tri)
Definition: tritools.cpp:125
int Split(const idPlane &plane, const float epsilon, idWinding **front, idWinding **back) const
Definition: Winding.cpp:92
Definition: dmap.h:59
mapTri_t * CopyTriList(const mapTri_t *a)
Definition: tritools.cpp:103
mapTri_t * MergeTriLists(mapTri_t *a, mapTri_t *b)
Definition: tritools.cpp:70
struct hashVert_s * next
mapTri_t * RemoveBadTris(const mapTri_t *list)
Definition: tritools.cpp:168
mapTri_t * CopyMapTri(const mapTri_t *tri)
Definition: tritools.cpp:143
mapTri_t * AllocTri(void)
Definition: tritools.cpp:45
void * Mem_Alloc(const int size)
Definition: Heap.cpp:1067
GLint j
Definition: qgl.h:264
void DrawTri(const mapTri_t *tri)
Definition: tritools.cpp:205
void SetNumPoints(int n)
Definition: Winding.h:242
GLdouble GLdouble t
Definition: glext.h:2943
float MapTriArea(const mapTri_t *tri)
Definition: tritools.cpp:157