doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Winding.h
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 #ifndef __WINDING_H__
30 #define __WINDING_H__
31 
32 /*
33 ===============================================================================
34 
35  A winding is an arbitrary convex polygon defined by an array of points.
36 
37 ===============================================================================
38 */
39 
40 class idWinding {
41 
42 public:
43  idWinding( void );
44  explicit idWinding( const int n ); // allocate for n points
45  explicit idWinding( const idVec3 *verts, const int n ); // winding from points
46  explicit idWinding( const idVec3 &normal, const float dist ); // base winding for plane
47  explicit idWinding( const idPlane &plane ); // base winding for plane
48  explicit idWinding( const idWinding &winding );
49  virtual ~idWinding( void );
50 
51  idWinding & operator=( const idWinding &winding );
52  const idVec5 & operator[]( const int index ) const;
53  idVec5 & operator[]( const int index );
54 
55  // add a point to the end of the winding point array
56  idWinding & operator+=( const idVec3 &v );
57  idWinding & operator+=( const idVec5 &v );
58  void AddPoint( const idVec3 &v );
59  void AddPoint( const idVec5 &v );
60 
61  // number of points on winding
62  int GetNumPoints( void ) const;
63  void SetNumPoints( int n );
64  virtual void Clear( void );
65 
66  // huge winding for plane, the points go counter clockwise when facing the front of the plane
67  void BaseForPlane( const idVec3 &normal, const float dist );
68  void BaseForPlane( const idPlane &plane );
69 
70  // splits the winding into a front and back winding, the winding itself stays unchanged
71  // returns a SIDE_?
72  int Split( const idPlane &plane, const float epsilon, idWinding **front, idWinding **back ) const;
73  // returns the winding fragment at the front of the clipping plane,
74  // if there is nothing at the front the winding itself is destroyed and NULL is returned
75  idWinding * Clip( const idPlane &plane, const float epsilon = ON_EPSILON, const bool keepOn = false );
76  // cuts off the part at the back side of the plane, returns true if some part was at the front
77  // if there is nothing at the front the number of points is set to zero
78  bool ClipInPlace( const idPlane &plane, const float epsilon = ON_EPSILON, const bool keepOn = false );
79 
80  // returns a copy of the winding
81  idWinding * Copy( void ) const;
82  idWinding * Reverse( void ) const;
83  void ReverseSelf( void );
84  void RemoveEqualPoints( const float epsilon = ON_EPSILON );
85  void RemoveColinearPoints( const idVec3 &normal, const float epsilon = ON_EPSILON );
86  void RemovePoint( int point );
87  void InsertPoint( const idVec3 &point, int spot );
88  bool InsertPointIfOnEdge( const idVec3 &point, const idPlane &plane, const float epsilon = ON_EPSILON );
89  // add a winding to the convex hull
90  void AddToConvexHull( const idWinding *winding, const idVec3 &normal, const float epsilon = ON_EPSILON );
91  // add a point to the convex hull
92  void AddToConvexHull( const idVec3 &point, const idVec3 &normal, const float epsilon = ON_EPSILON );
93  // tries to merge 'this' with the given winding, returns NULL if merge fails, both 'this' and 'w' stay intact
94  // 'keep' tells if the contacting points should stay even if they create colinear edges
95  idWinding * TryMerge( const idWinding &w, const idVec3 &normal, int keep = false ) const;
96  // check whether the winding is valid or not
97  bool Check( bool print = true ) const;
98 
99  float GetArea( void ) const;
100  idVec3 GetCenter( void ) const;
101  float GetRadius( const idVec3 &center ) const;
102  void GetPlane( idVec3 &normal, float &dist ) const;
103  void GetPlane( idPlane &plane ) const;
104  void GetBounds( idBounds &bounds ) const;
105 
106  bool IsTiny( void ) const;
107  bool IsHuge( void ) const; // base winding for a plane is typically huge
108  void Print( void ) const;
109 
110  float PlaneDistance( const idPlane &plane ) const;
111  int PlaneSide( const idPlane &plane, const float epsilon = ON_EPSILON ) const;
112 
113  bool PlanesConcave( const idWinding &w2, const idVec3 &normal1, const idVec3 &normal2, float dist1, float dist2 ) const;
114 
115  bool PointInside( const idVec3 &normal, const idVec3 &point, const float epsilon ) const;
116  // returns true if the line or ray intersects the winding
117  bool LineIntersection( const idPlane &windingPlane, const idVec3 &start, const idVec3 &end, bool backFaceCull = false ) const;
118  // intersection point is start + dir * scale
119  bool RayIntersection( const idPlane &windingPlane, const idVec3 &start, const idVec3 &dir, float &scale, bool backFaceCull = false ) const;
120 
121  static float TriangleArea( const idVec3 &a, const idVec3 &b, const idVec3 &c );
122 
123 protected:
124  int numPoints; // number of points
125  idVec5 * p; // pointer to point data
127 
128  bool EnsureAlloced( int n, bool keep = false );
129  virtual bool ReAllocate( int n, bool keep = false );
130 };
131 
132 ID_INLINE idWinding::idWinding( void ) {
133  numPoints = allocedSize = 0;
134  p = NULL;
135 }
136 
137 ID_INLINE idWinding::idWinding( int n ) {
138  numPoints = allocedSize = 0;
139  p = NULL;
140  EnsureAlloced( n );
141 }
142 
143 ID_INLINE idWinding::idWinding( const idVec3 *verts, const int n ) {
144  int i;
145 
146  numPoints = allocedSize = 0;
147  p = NULL;
148  if ( !EnsureAlloced( n ) ) {
149  numPoints = 0;
150  return;
151  }
152  for ( i = 0; i < n; i++ ) {
153  p[i].ToVec3() = verts[i];
154  p[i].s = p[i].t = 0.0f;
155  }
156  numPoints = n;
157 }
158 
159 ID_INLINE idWinding::idWinding( const idVec3 &normal, const float dist ) {
160  numPoints = allocedSize = 0;
161  p = NULL;
162  BaseForPlane( normal, dist );
163 }
164 
165 ID_INLINE idWinding::idWinding( const idPlane &plane ) {
166  numPoints = allocedSize = 0;
167  p = NULL;
168  BaseForPlane( plane );
169 }
170 
171 ID_INLINE idWinding::idWinding( const idWinding &winding ) {
172  int i;
173  if ( !EnsureAlloced( winding.GetNumPoints() ) ) {
174  numPoints = 0;
175  return;
176  }
177  for ( i = 0; i < winding.GetNumPoints(); i++ ) {
178  p[i] = winding[i];
179  }
180  numPoints = winding.GetNumPoints();
181 }
182 
183 ID_INLINE idWinding::~idWinding( void ) {
184  delete[] p;
185  p = NULL;
186 }
187 
188 ID_INLINE idWinding &idWinding::operator=( const idWinding &winding ) {
189  int i;
190 
191  if ( !EnsureAlloced( winding.numPoints ) ) {
192  numPoints = 0;
193  return *this;
194  }
195  for ( i = 0; i < winding.numPoints; i++ ) {
196  p[i] = winding.p[i];
197  }
198  numPoints = winding.numPoints;
199  return *this;
200 }
201 
202 ID_INLINE const idVec5 &idWinding::operator[]( const int index ) const {
203  //assert( index >= 0 && index < numPoints );
204  return p[ index ];
205 }
206 
207 ID_INLINE idVec5 &idWinding::operator[]( const int index ) {
208  //assert( index >= 0 && index < numPoints );
209  return p[ index ];
210 }
211 
212 ID_INLINE idWinding &idWinding::operator+=( const idVec3 &v ) {
213  AddPoint( v );
214  return *this;
215 }
216 
217 ID_INLINE idWinding &idWinding::operator+=( const idVec5 &v ) {
218  AddPoint( v );
219  return *this;
220 }
221 
222 ID_INLINE void idWinding::AddPoint( const idVec3 &v ) {
223  if ( !EnsureAlloced(numPoints+1, true) ) {
224  return;
225  }
226  p[numPoints] = v;
227  numPoints++;
228 }
229 
230 ID_INLINE void idWinding::AddPoint( const idVec5 &v ) {
231  if ( !EnsureAlloced(numPoints+1, true) ) {
232  return;
233  }
234  p[numPoints] = v;
235  numPoints++;
236 }
237 
238 ID_INLINE int idWinding::GetNumPoints( void ) const {
239  return numPoints;
240 }
241 
242 ID_INLINE void idWinding::SetNumPoints( int n ) {
243  if ( !EnsureAlloced( n, true ) ) {
244  return;
245  }
246  numPoints = n;
247 }
248 
249 ID_INLINE void idWinding::Clear( void ) {
250  numPoints = 0;
251  delete[] p;
252  p = NULL;
253 }
254 
255 ID_INLINE void idWinding::BaseForPlane( const idPlane &plane ) {
256  BaseForPlane( plane.Normal(), plane.Dist() );
257 }
258 
259 ID_INLINE bool idWinding::EnsureAlloced( int n, bool keep ) {
260  if ( n > allocedSize ) {
261  return ReAllocate( n, keep );
262  }
263  return true;
264 }
265 
266 
267 /*
268 ===============================================================================
269 
270  idFixedWinding is a fixed buffer size winding not using
271  memory allocations.
272 
273  When an operation would overflow the fixed buffer a warning
274  is printed and the operation is safely cancelled.
275 
276 ===============================================================================
277 */
278 
279 #define MAX_POINTS_ON_WINDING 64
280 
281 class idFixedWinding : public idWinding {
282 
283 public:
284  idFixedWinding( void );
285  explicit idFixedWinding( const int n );
286  explicit idFixedWinding( const idVec3 *verts, const int n );
287  explicit idFixedWinding( const idVec3 &normal, const float dist );
288  explicit idFixedWinding( const idPlane &plane );
289  explicit idFixedWinding( const idWinding &winding );
290  explicit idFixedWinding( const idFixedWinding &winding );
291  virtual ~idFixedWinding( void );
292 
293  idFixedWinding &operator=( const idWinding &winding );
294 
295  virtual void Clear( void );
296 
297  // splits the winding in a back and front part, 'this' becomes the front part
298  // returns a SIDE_?
299  int Split( idFixedWinding *back, const idPlane &plane, const float epsilon = ON_EPSILON );
300 
301 protected:
303 
304  virtual bool ReAllocate( int n, bool keep = false );
305 };
306 
308  numPoints = 0;
309  p = data;
311 }
312 
314  numPoints = 0;
315  p = data;
317 }
318 
319 ID_INLINE idFixedWinding::idFixedWinding( const idVec3 *verts, const int n ) {
320  int i;
321 
322  numPoints = 0;
323  p = data;
325  if ( !EnsureAlloced( n ) ) {
326  numPoints = 0;
327  return;
328  }
329  for ( i = 0; i < n; i++ ) {
330  p[i].ToVec3() = verts[i];
331  p[i].s = p[i].t = 0;
332  }
333  numPoints = n;
334 }
335 
336 ID_INLINE idFixedWinding::idFixedWinding( const idVec3 &normal, const float dist ) {
337  numPoints = 0;
338  p = data;
340  BaseForPlane( normal, dist );
341 }
342 
343 ID_INLINE idFixedWinding::idFixedWinding( const idPlane &plane ) {
344  numPoints = 0;
345  p = data;
347  BaseForPlane( plane );
348 }
349 
350 ID_INLINE idFixedWinding::idFixedWinding( const idWinding &winding ) {
351  int i;
352 
353  p = data;
355  if ( !EnsureAlloced( winding.GetNumPoints() ) ) {
356  numPoints = 0;
357  return;
358  }
359  for ( i = 0; i < winding.GetNumPoints(); i++ ) {
360  p[i] = winding[i];
361  }
362  numPoints = winding.GetNumPoints();
363 }
364 
365 ID_INLINE idFixedWinding::idFixedWinding( const idFixedWinding &winding ) {
366  int i;
367 
368  p = data;
370  if ( !EnsureAlloced( winding.GetNumPoints() ) ) {
371  numPoints = 0;
372  return;
373  }
374  for ( i = 0; i < winding.GetNumPoints(); i++ ) {
375  p[i] = winding[i];
376  }
377  numPoints = winding.GetNumPoints();
378 }
379 
381  p = NULL; // otherwise it tries to free the fixed buffer
382 }
383 
384 ID_INLINE idFixedWinding &idFixedWinding::operator=( const idWinding &winding ) {
385  int i;
386 
387  if ( !EnsureAlloced( winding.GetNumPoints() ) ) {
388  numPoints = 0;
389  return *this;
390  }
391  for ( i = 0; i < winding.GetNumPoints(); i++ ) {
392  p[i] = winding[i];
393  }
394  numPoints = winding.GetNumPoints();
395  return *this;
396 }
397 
398 ID_INLINE void idFixedWinding::Clear( void ) {
399  numPoints = 0;
400 }
401 #endif /* !__WINDING_H__ */
idWinding & operator+=(const idVec3 &v)
Definition: Winding.h:212
void GetBounds(idBounds &bounds) const
Definition: Winding.cpp:700
void RemoveEqualPoints(const float epsilon=ON_EPSILON)
Definition: Winding.cpp:733
virtual void Clear(void)
Definition: Winding.h:249
float GetArea(void) const
Definition: Winding.cpp:598
const idVec3 & Normal(void) const
Definition: Plane.h:239
int allocedSize
Definition: Winding.h:126
bool LineIntersection(const idPlane &windingPlane, const idVec3 &start, const idVec3 &end, bool backFaceCull=false) const
Definition: Winding.cpp:1379
const GLdouble * v
Definition: glext.h:2936
void AddToConvexHull(const idWinding *winding, const idVec3 &normal, const float epsilon=ON_EPSILON)
Definition: Winding.cpp:789
idFixedWinding & operator=(const idWinding &winding)
Definition: Winding.h:384
GLenum GLenum GLenum GLenum GLenum scale
Definition: glext.h:4804
idWinding * TryMerge(const idWinding &w, const idVec3 &normal, int keep=false) const
Definition: Winding.cpp:998
GLenum GLsizei n
Definition: glext.h:3705
Definition: Vector.h:316
void Print(void) const
Definition: Winding.cpp:1244
void ReverseSelf(void)
Definition: Winding.cpp:495
idWinding * Reverse(void) const
Definition: Winding.cpp:478
idWinding * Clip(const idPlane &plane, const float epsilon=ON_EPSILON, const bool keepOn=false)
Definition: Winding.cpp:234
idVec5 * p
Definition: Winding.h:125
bool PlanesConcave(const idWinding &w2, const idVec3 &normal1, const idVec3 &normal2, float dist1, float dist2) const
Definition: Winding.cpp:1333
int i
Definition: process.py:33
int Split(idFixedWinding *back, const idPlane &plane, const float epsilon=ON_EPSILON)
Definition: Winding.cpp:1484
bool InsertPointIfOnEdge(const idVec3 &point, const idPlane &plane, const float epsilon=ON_EPSILON)
Definition: Winding.cpp:1145
idWinding & operator=(const idWinding &winding)
Definition: Winding.h:188
virtual bool ReAllocate(int n, bool keep=false)
Definition: Winding.cpp:44
const idVec5 & operator[](const int index) const
Definition: Winding.h:202
int PlaneSide(const idPlane &plane, const float epsilon=ON_EPSILON) const
Definition: Winding.cpp:1292
void InsertPoint(const idVec3 &point, int spot)
Definition: Winding.cpp:1121
bool EnsureAlloced(int n, bool keep=false)
Definition: Winding.h:259
int GetNumPoints(void) const
Definition: Winding.h:238
#define MAX_POINTS_ON_WINDING
Definition: Winding.h:279
GLuint index
Definition: glext.h:3476
const GLubyte * c
Definition: glext.h:4677
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:3454
bool IsHuge(void) const
Definition: Winding.cpp:1226
GLuint GLuint end
Definition: glext.h:2845
static float TriangleArea(const idVec3 &a, const idVec3 &b, const idVec3 &c)
Definition: Winding.cpp:1446
#define NULL
Definition: Lib.h:88
GLsizei GLsizei GLenum GLenum const GLvoid * data
Definition: glext.h:2853
virtual void Clear(void)
Definition: Winding.h:398
void GetPlane(idVec3 &normal, float &dist) const
Definition: Winding.cpp:656
Definition: Plane.h:71
virtual ~idWinding(void)
Definition: Winding.h:183
virtual ~idFixedWinding(void)
Definition: Winding.h:380
idWinding(void)
Definition: Winding.h:132
bool Check(bool print=true) const
Definition: Winding.cpp:511
GLubyte GLubyte GLubyte a
Definition: glext.h:4662
idVec5 data[MAX_POINTS_ON_WINDING]
Definition: Winding.h:302
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble GLdouble w2
Definition: glext.h:4080
GLubyte GLubyte b
Definition: glext.h:4662
bool IsTiny(void) const
Definition: Winding.cpp:1202
int Split(const idPlane &plane, const float epsilon, idWinding **front, idWinding **back) const
Definition: Winding.cpp:92
#define ON_EPSILON
Definition: Plane.h:44
bool PointInside(const idVec3 &normal, const idVec3 &point, const float epsilon) const
Definition: Winding.cpp:1357
virtual bool ReAllocate(int n, bool keep=false)
Definition: Winding.cpp:1468
idVec3 GetCenter(void) const
Definition: Winding.cpp:639
idWinding * Copy(void) const
Definition: Winding.cpp:464
void BaseForPlane(const idVec3 &normal, const float dist)
Definition: Winding.cpp:66
float GetRadius(const idVec3 &center) const
Definition: Winding.cpp:618
void RemovePoint(int point)
Definition: Winding.cpp:1106
void AddPoint(const idVec3 &v)
Definition: Winding.h:222
GLfloat GLfloat p
Definition: glext.h:4674
float PlaneDistance(const idPlane &plane) const
Definition: Winding.cpp:1257
bool ClipInPlace(const idPlane &plane, const float epsilon=ON_EPSILON, const bool keepOn=false)
Definition: Winding.cpp:349
bool RayIntersection(const idPlane &windingPlane, const idVec3 &start, const idVec3 &dir, float &scale, bool backFaceCull=false) const
Definition: Winding.cpp:1419
GLuint start
Definition: glext.h:2845
float Dist(void) const
Definition: Plane.h:271
void RemoveColinearPoints(const idVec3 &normal, const float epsilon=ON_EPSILON)
Definition: Winding.cpp:753
int numPoints
Definition: Winding.h:124
idFixedWinding(void)
Definition: Winding.h:307
void SetNumPoints(int n)
Definition: Winding.h:242