doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Plane.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 __MATH_PLANE_H__
30 #define __MATH_PLANE_H__
31 
32 /*
33 ===============================================================================
34 
35  3D plane with equation: a * x + b * y + c * z + d = 0
36 
37 ===============================================================================
38 */
39 
40 
41 class idVec3;
42 class idMat3;
43 
44 #define ON_EPSILON 0.1f
45 #define DEGENERATE_DIST_EPSILON 1e-4f
46 
47 #define SIDE_FRONT 0
48 #define SIDE_BACK 1
49 #define SIDE_ON 2
50 #define SIDE_CROSS 3
51 
52 // plane sides
53 #define PLANESIDE_FRONT 0
54 #define PLANESIDE_BACK 1
55 #define PLANESIDE_ON 2
56 #define PLANESIDE_CROSS 3
57 
58 // plane types
59 #define PLANETYPE_X 0
60 #define PLANETYPE_Y 1
61 #define PLANETYPE_Z 2
62 #define PLANETYPE_NEGX 3
63 #define PLANETYPE_NEGY 4
64 #define PLANETYPE_NEGZ 5
65 #define PLANETYPE_TRUEAXIAL 6 // all types < 6 are true axial planes
66 #define PLANETYPE_ZEROX 6
67 #define PLANETYPE_ZEROY 7
68 #define PLANETYPE_ZEROZ 8
69 #define PLANETYPE_NONAXIAL 9
70 
71 class idPlane {
72 public:
73  idPlane( void );
74  idPlane( float a, float b, float c, float d );
75  idPlane( const idVec3 &normal, const float dist );
76 
77  float operator[]( int index ) const;
78  float & operator[]( int index );
79  idPlane operator-() const; // flips plane
80  idPlane & operator=( const idVec3 &v ); // sets normal and sets idPlane::d to zero
81  idPlane operator+( const idPlane &p ) const; // add plane equations
82  idPlane operator-( const idPlane &p ) const; // subtract plane equations
83  idPlane & operator*=( const idMat3 &m ); // Normal() *= m
84 
85  bool Compare( const idPlane &p ) const; // exact compare, no epsilon
86  bool Compare( const idPlane &p, const float epsilon ) const; // compare with epsilon
87  bool Compare( const idPlane &p, const float normalEps, const float distEps ) const; // compare with epsilon
88  bool operator==( const idPlane &p ) const; // exact compare, no epsilon
89  bool operator!=( const idPlane &p ) const; // exact compare, no epsilon
90 
91  void Zero( void ); // zero plane
92  void SetNormal( const idVec3 &normal ); // sets the normal
93  const idVec3 & Normal( void ) const; // reference to const normal
94  idVec3 & Normal( void ); // reference to normal
95  float Normalize( bool fixDegenerate = true ); // only normalizes the plane normal, does not adjust d
96  bool FixDegenerateNormal( void ); // fix degenerate normal
97  bool FixDegeneracies( float distEpsilon ); // fix degenerate normal and dist
98  float Dist( void ) const; // returns: -d
99  void SetDist( const float dist ); // sets: d = -dist
100  int Type( void ) const; // returns plane type
101 
102  bool FromPoints( const idVec3 &p1, const idVec3 &p2, const idVec3 &p3, bool fixDegenerate = true );
103  bool FromVecs( const idVec3 &dir1, const idVec3 &dir2, const idVec3 &p, bool fixDegenerate = true );
104  void FitThroughPoint( const idVec3 &p ); // assumes normal is valid
105  bool HeightFit( const idVec3 *points, const int numPoints );
106  idPlane Translate( const idVec3 &translation ) const;
107  idPlane & TranslateSelf( const idVec3 &translation );
108  idPlane Rotate( const idVec3 &origin, const idMat3 &axis ) const;
109  idPlane & RotateSelf( const idVec3 &origin, const idMat3 &axis );
110 
111  float Distance( const idVec3 &v ) const;
112  int Side( const idVec3 &v, const float epsilon = 0.0f ) const;
113 
114  bool LineIntersection( const idVec3 &start, const idVec3 &end ) const;
115  // intersection point is start + dir * scale
116  bool RayIntersection( const idVec3 &start, const idVec3 &dir, float &scale ) const;
117  bool PlaneIntersection( const idPlane &plane, idVec3 &start, idVec3 &dir ) const;
118 
119  int GetDimension( void ) const;
120 
121  const idVec4 & ToVec4( void ) const;
122  idVec4 & ToVec4( void );
123  const float * ToFloatPtr( void ) const;
124  float * ToFloatPtr( void );
125  const char * ToString( int precision = 2 ) const;
126 
127 private:
128  float a;
129  float b;
130  float c;
131  float d;
132 };
133 
134 extern idPlane plane_origin;
135 #define plane_zero plane_origin
136 
137 ID_INLINE idPlane::idPlane( void ) {
138 }
139 
140 ID_INLINE idPlane::idPlane( float a, float b, float c, float d ) {
141  this->a = a;
142  this->b = b;
143  this->c = c;
144  this->d = d;
145 }
146 
147 ID_INLINE idPlane::idPlane( const idVec3 &normal, const float dist ) {
148  this->a = normal.x;
149  this->b = normal.y;
150  this->c = normal.z;
151  this->d = -dist;
152 }
153 
154 ID_INLINE float idPlane::operator[]( int index ) const {
155  return ( &a )[ index ];
156 }
157 
158 ID_INLINE float& idPlane::operator[]( int index ) {
159  return ( &a )[ index ];
160 }
161 
162 ID_INLINE idPlane idPlane::operator-() const {
163  return idPlane( -a, -b, -c, -d );
164 }
165 
166 ID_INLINE idPlane &idPlane::operator=( const idVec3 &v ) {
167  a = v.x;
168  b = v.y;
169  c = v.z;
170  d = 0;
171  return *this;
172 }
173 
174 ID_INLINE idPlane idPlane::operator+( const idPlane &p ) const {
175  return idPlane( a + p.a, b + p.b, c + p.c, d + p.d );
176 }
177 
178 ID_INLINE idPlane idPlane::operator-( const idPlane &p ) const {
179  return idPlane( a - p.a, b - p.b, c - p.c, d - p.d );
180 }
181 
182 ID_INLINE idPlane &idPlane::operator*=( const idMat3 &m ) {
183  Normal() *= m;
184  return *this;
185 }
186 
187 ID_INLINE bool idPlane::Compare( const idPlane &p ) const {
188  return ( a == p.a && b == p.b && c == p.c && d == p.d );
189 }
190 
191 ID_INLINE bool idPlane::Compare( const idPlane &p, const float epsilon ) const {
192  if ( idMath::Fabs( a - p.a ) > epsilon ) {
193  return false;
194  }
195 
196  if ( idMath::Fabs( b - p.b ) > epsilon ) {
197  return false;
198  }
199 
200  if ( idMath::Fabs( c - p.c ) > epsilon ) {
201  return false;
202  }
203 
204  if ( idMath::Fabs( d - p.d ) > epsilon ) {
205  return false;
206  }
207 
208  return true;
209 }
210 
211 ID_INLINE bool idPlane::Compare( const idPlane &p, const float normalEps, const float distEps ) const {
212  if ( idMath::Fabs( d - p.d ) > distEps ) {
213  return false;
214  }
215  if ( !Normal().Compare( p.Normal(), normalEps ) ) {
216  return false;
217  }
218  return true;
219 }
220 
221 ID_INLINE bool idPlane::operator==( const idPlane &p ) const {
222  return Compare( p );
223 }
224 
225 ID_INLINE bool idPlane::operator!=( const idPlane &p ) const {
226  return !Compare( p );
227 }
228 
229 ID_INLINE void idPlane::Zero( void ) {
230  a = b = c = d = 0.0f;
231 }
232 
233 ID_INLINE void idPlane::SetNormal( const idVec3 &normal ) {
234  a = normal.x;
235  b = normal.y;
236  c = normal.z;
237 }
238 
239 ID_INLINE const idVec3 &idPlane::Normal( void ) const {
240  return *reinterpret_cast<const idVec3 *>(&a);
241 }
242 
243 ID_INLINE idVec3 &idPlane::Normal( void ) {
244  return *reinterpret_cast<idVec3 *>(&a);
245 }
246 
247 ID_INLINE float idPlane::Normalize( bool fixDegenerate ) {
248  float length = reinterpret_cast<idVec3 *>(&a)->Normalize();
249 
250  if ( fixDegenerate ) {
252  }
253  return length;
254 }
255 
256 ID_INLINE bool idPlane::FixDegenerateNormal( void ) {
257  return Normal().FixDegenerateNormal();
258 }
259 
260 ID_INLINE bool idPlane::FixDegeneracies( float distEpsilon ) {
261  bool fixedNormal = FixDegenerateNormal();
262  // only fix dist if the normal was degenerate
263  if ( fixedNormal ) {
264  if ( idMath::Fabs( d - idMath::Rint( d ) ) < distEpsilon ) {
265  d = idMath::Rint( d );
266  }
267  }
268  return fixedNormal;
269 }
270 
271 ID_INLINE float idPlane::Dist( void ) const {
272  return -d;
273 }
274 
275 ID_INLINE void idPlane::SetDist( const float dist ) {
276  d = -dist;
277 }
278 
279 ID_INLINE bool idPlane::FromPoints( const idVec3 &p1, const idVec3 &p2, const idVec3 &p3, bool fixDegenerate ) {
280  Normal() = (p1 - p2).Cross( p3 - p2 );
281  if ( Normalize( fixDegenerate ) == 0.0f ) {
282  return false;
283  }
284  d = -( Normal() * p2 );
285  return true;
286 }
287 
288 ID_INLINE bool idPlane::FromVecs( const idVec3 &dir1, const idVec3 &dir2, const idVec3 &p, bool fixDegenerate ) {
289  Normal() = dir1.Cross( dir2 );
290  if ( Normalize( fixDegenerate ) == 0.0f ) {
291  return false;
292  }
293  d = -( Normal() * p );
294  return true;
295 }
296 
297 ID_INLINE void idPlane::FitThroughPoint( const idVec3 &p ) {
298  d = -( Normal() * p );
299 }
300 
301 ID_INLINE idPlane idPlane::Translate( const idVec3 &translation ) const {
302  return idPlane( a, b, c, d - translation * Normal() );
303 }
304 
305 ID_INLINE idPlane &idPlane::TranslateSelf( const idVec3 &translation ) {
306  d -= translation * Normal();
307  return *this;
308 }
309 
310 ID_INLINE idPlane idPlane::Rotate( const idVec3 &origin, const idMat3 &axis ) const {
311  idPlane p;
312  p.Normal() = Normal() * axis;
313  p.d = d + origin * Normal() - origin * p.Normal();
314  return p;
315 }
316 
317 ID_INLINE idPlane &idPlane::RotateSelf( const idVec3 &origin, const idMat3 &axis ) {
318  d += origin * Normal();
319  Normal() *= axis;
320  d -= origin * Normal();
321  return *this;
322 }
323 
324 ID_INLINE float idPlane::Distance( const idVec3 &v ) const {
325  return a * v.x + b * v.y + c * v.z + d;
326 }
327 
328 ID_INLINE int idPlane::Side( const idVec3 &v, const float epsilon ) const {
329  float dist = Distance( v );
330  if ( dist > epsilon ) {
331  return PLANESIDE_FRONT;
332  }
333  else if ( dist < -epsilon ) {
334  return PLANESIDE_BACK;
335  }
336  else {
337  return PLANESIDE_ON;
338  }
339 }
340 
341 ID_INLINE bool idPlane::LineIntersection( const idVec3 &start, const idVec3 &end ) const {
342  float d1, d2, fraction;
343 
344  d1 = Normal() * start + d;
345  d2 = Normal() * end + d;
346  if ( d1 == d2 ) {
347  return false;
348  }
349  if ( d1 > 0.0f && d2 > 0.0f ) {
350  return false;
351  }
352  if ( d1 < 0.0f && d2 < 0.0f ) {
353  return false;
354  }
355  fraction = ( d1 / ( d1 - d2 ) );
356  return ( fraction >= 0.0f && fraction <= 1.0f );
357 }
358 
359 ID_INLINE bool idPlane::RayIntersection( const idVec3 &start, const idVec3 &dir, float &scale ) const {
360  float d1, d2;
361 
362  d1 = Normal() * start + d;
363  d2 = Normal() * dir;
364  if ( d2 == 0.0f ) {
365  return false;
366  }
367  scale = -( d1 / d2 );
368  return true;
369 }
370 
371 ID_INLINE int idPlane::GetDimension( void ) const {
372  return 4;
373 }
374 
375 ID_INLINE const idVec4 &idPlane::ToVec4( void ) const {
376  return *reinterpret_cast<const idVec4 *>(&a);
377 }
378 
379 ID_INLINE idVec4 &idPlane::ToVec4( void ) {
380  return *reinterpret_cast<idVec4 *>(&a);
381 }
382 
383 ID_INLINE const float *idPlane::ToFloatPtr( void ) const {
384  return reinterpret_cast<const float *>(&a);
385 }
386 
387 ID_INLINE float *idPlane::ToFloatPtr( void ) {
388  return reinterpret_cast<float *>(&a);
389 }
390 
391 #endif /* !__MATH_PLANE_H__ */
GLsizei const GLfloat * points
Definition: glext.h:3884
bool FromPoints(const idVec3 &p1, const idVec3 &p2, const idVec3 &p3, bool fixDegenerate=true)
Definition: Plane.h:279
#define PLANESIDE_ON
Definition: Plane.h:55
const idVec3 & Normal(void) const
Definition: Plane.h:239
bool Compare(const idPlane &p) const
Definition: Plane.h:187
const GLdouble * v
Definition: glext.h:2936
idPlane(void)
Definition: Plane.h:137
GLenum GLenum GLenum GLenum GLenum scale
Definition: glext.h:4804
float Distance(const idVec3 &v) const
Definition: Plane.h:324
float z
Definition: Vector.h:320
bool PlaneIntersection(const idPlane &plane, idVec3 &start, idVec3 &dir) const
Definition: Plane.cpp:126
const float * ToFloatPtr(void) const
Definition: Plane.h:383
const idVec4 & ToVec4(void) const
Definition: Plane.h:375
idPlane & TranslateSelf(const idVec3 &translation)
Definition: Plane.h:305
Definition: Vector.h:316
float c
Definition: Plane.h:130
idPlane & RotateSelf(const idVec3 &origin, const idMat3 &axis)
Definition: Plane.h:317
void SetNormal(const idVec3 &normal)
Definition: Plane.h:233
idVec3 Cross(const idVec3 &a) const
Definition: Vector.h:619
float x
Definition: Vector.h:318
static float Rint(float f)
Definition: Math.h:793
idPlane Rotate(const idVec3 &origin, const idMat3 &axis) const
Definition: Plane.h:310
int Type(void) const
Definition: Plane.cpp:39
const char * ToString(int precision=2) const
Definition: Plane.cpp:152
#define PLANESIDE_FRONT
Definition: Plane.h:53
idPlane & operator*=(const idMat3 &m)
Definition: Plane.h:182
idPlane operator-() const
Definition: Plane.h:162
GLuint index
Definition: glext.h:3476
const GLubyte * c
Definition: glext.h:4677
Definition: Vector.h:808
void SetDist(const float dist)
Definition: Plane.h:275
GLuint GLuint end
Definition: glext.h:2845
static float Fabs(float f)
Definition: Math.h:779
bool HeightFit(const idVec3 *points, const int numPoints)
Definition: Plane.cpp:72
#define PLANESIDE_BACK
Definition: Plane.h:54
float b
Definition: Plane.h:129
bool FromVecs(const idVec3 &dir1, const idVec3 &dir2, const idVec3 &p, bool fixDegenerate=true)
Definition: Plane.h:288
float y
Definition: Vector.h:319
idPlane plane_origin
bool operator!=(const idPlane &p) const
Definition: Plane.h:225
Definition: Plane.h:71
bool FixDegenerateNormal(void)
Definition: Plane.h:256
int GetDimension(void) const
Definition: Plane.h:371
GLubyte GLubyte GLubyte a
Definition: glext.h:4662
bool RayIntersection(const idVec3 &start, const idVec3 &dir, float &scale) const
Definition: Plane.h:359
float Normalize(bool fixDegenerate=true)
Definition: Plane.h:247
bool FixDegenerateNormal(void)
Definition: Vector.h:535
idPlane operator+(const idPlane &p) const
Definition: Plane.h:174
int Side(const idVec3 &v, const float epsilon=0.0f) const
Definition: Plane.h:328
GLubyte GLubyte b
Definition: glext.h:4662
bool LineIntersection(const idVec3 &start, const idVec3 &end) const
Definition: Plane.h:341
Definition: Matrix.h:333
tuple f
Definition: idal.py:89
float d
Definition: Plane.h:131
float a
Definition: Plane.h:128
idPlane & operator=(const idVec3 &v)
Definition: Plane.h:166
GLsizei const GLcharARB const GLint * length
Definition: glext.h:3599
idPlane Translate(const idVec3 &translation) const
Definition: Plane.h:301
void Zero(void)
Definition: Plane.h:229
bool operator==(const idPlane &p) const
Definition: Plane.h:221
bool FixDegeneracies(float distEpsilon)
Definition: Plane.h:260
GLfloat GLfloat p
Definition: glext.h:4674
GLuint start
Definition: glext.h:2845
float operator[](int index) const
Definition: Plane.h:154
float Dist(void) const
Definition: Plane.h:271
void FitThroughPoint(const idVec3 &p)
Definition: Plane.h:297