doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Winding2D.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 "../precompiled.h"
30 #pragma hdrstop
31 
32 #include "Winding2D.h"
33 
34 
35 /*
36 ============
37 GetAxialBevel
38 ============
39 */
40 bool GetAxialBevel( const idVec3 &plane1, const idVec3 &plane2, const idVec2 &point, idVec3 &bevel ) {
41  if ( FLOATSIGNBITSET( plane1.x ) ^ FLOATSIGNBITSET( plane2.x ) ) {
42  if ( idMath::Fabs( plane1.x ) > 0.1f && idMath::Fabs( plane2.x ) > 0.1f ) {
43  bevel.x = 0.0f;
44  if ( FLOATSIGNBITSET( plane1.y ) ) {
45  bevel.y = -1.0f;
46  }
47  else {
48  bevel.y = 1.0f;
49  }
50  bevel.z = - ( point.x * bevel.x + point.y * bevel.y );
51  return true;
52  }
53  }
54  if ( FLOATSIGNBITSET( plane1.y ) ^ FLOATSIGNBITSET( plane2.y ) ) {
55  if ( idMath::Fabs( plane1.y ) > 0.1f && idMath::Fabs( plane2.y ) > 0.1f ) {
56  bevel.y = 0.0f;
57  if ( FLOATSIGNBITSET( plane1.x ) ) {
58  bevel.x = -1.0f;
59  }
60  else {
61  bevel.x = 1.0f;
62  }
63  bevel.z = - ( point.x * bevel.x + point.y * bevel.y );
64  return true;
65  }
66  }
67  return false;
68 }
69 
70 /*
71 ============
72 idWinding2D::ExpandForAxialBox
73 ============
74 */
75 void idWinding2D::ExpandForAxialBox( const idVec2 bounds[2] ) {
76  int i, j, numPlanes;
77  idVec2 v;
78  idVec3 planes[MAX_POINTS_ON_WINDING_2D], plane, bevel;
79 
80  // get planes for the edges and add bevels
81  for ( numPlanes = i = 0; i < numPoints; i++ ) {
82  j = (i+1) % numPoints;
83  if ( ( p[j] - p[i] ).LengthSqr() < 0.01f ) {
84  continue;
85  }
86  plane = Plane2DFromPoints( p[i], p[j], true );
87  if ( i ) {
88  if ( GetAxialBevel( planes[numPlanes-1], plane, p[i], bevel ) ) {
89  planes[numPlanes++] = bevel;
90  }
91  }
92  assert( numPlanes < MAX_POINTS_ON_WINDING_2D );
93  planes[numPlanes++] = plane;
94  }
95  if ( GetAxialBevel( planes[numPlanes-1], planes[0], p[0], bevel ) ) {
96  planes[numPlanes++] = bevel;
97  }
98 
99  // expand the planes
100  for ( i = 0; i < numPlanes; i++ ) {
101  v.x = bounds[ FLOATSIGNBITSET( planes[i].x ) ].x;
102  v.y = bounds[ FLOATSIGNBITSET( planes[i].y ) ].y;
103  planes[i].z += v.x * planes[i].x + v.y * planes[i].y;
104  }
105 
106  // get intersection points of the planes
107  for ( numPoints = i = 0; i < numPlanes; i++ ) {
108  if ( Plane2DIntersection( planes[(i+numPlanes-1) % numPlanes], planes[i], p[numPoints] ) ) {
109  numPoints++;
110  }
111  }
112 }
113 
114 /*
115 ============
116 idWinding2D::Expand
117 ============
118 */
119 void idWinding2D::Expand( const float d ) {
120  int i;
121  idVec2 edgeNormals[MAX_POINTS_ON_WINDING_2D];
122 
123  for ( i = 0; i < numPoints; i++ ) {
124  idVec2 &start = p[i];
125  idVec2 &end = p[(i+1)%numPoints];
126  edgeNormals[i].x = start.y - end.y;
127  edgeNormals[i].y = end.x - start.x;
128  edgeNormals[i].Normalize();
129  edgeNormals[i] *= d;
130  }
131 
132  for ( i = 0; i < numPoints; i++ ) {
133  p[i] += edgeNormals[i] + edgeNormals[(i+numPoints-1)%numPoints];
134  }
135 }
136 
137 /*
138 =============
139 idWinding2D::Split
140 =============
141 */
142 int idWinding2D::Split( const idVec3 &plane, const float epsilon, idWinding2D **front, idWinding2D **back ) const {
143  float dists[MAX_POINTS_ON_WINDING_2D];
145  int counts[3];
146  float dot;
147  int i, j;
148  const idVec2 * p1, *p2;
149  idVec2 mid;
150  idWinding2D * f;
151  idWinding2D * b;
152  int maxpts;
153 
154  counts[0] = counts[1] = counts[2] = 0;
155 
156  // determine sides for each point
157  for ( i = 0; i < numPoints; i++ ) {
158  dists[i] = dot = plane.x * p[i].x + plane.y * p[i].y + plane.z;
159  if ( dot > epsilon ) {
160  sides[i] = SIDE_FRONT;
161  } else if ( dot < -epsilon ) {
162  sides[i] = SIDE_BACK;
163  } else {
164  sides[i] = SIDE_ON;
165  }
166  counts[sides[i]]++;
167  }
168  sides[i] = sides[0];
169  dists[i] = dists[0];
170 
171  *front = *back = NULL;
172 
173  // if nothing at the front of the clipping plane
174  if ( !counts[SIDE_FRONT] ) {
175  *back = Copy();
176  return SIDE_BACK;
177  }
178  // if nothing at the back of the clipping plane
179  if ( !counts[SIDE_BACK] ) {
180  *front = Copy();
181  return SIDE_FRONT;
182  }
183 
184  maxpts = numPoints+4; // cant use counts[0]+2 because of fp grouping errors
185 
186  *front = f = new idWinding2D;
187  *back = b = new idWinding2D;
188 
189  for ( i = 0; i < numPoints; i++ ) {
190  p1 = &p[i];
191 
192  if ( sides[i] == SIDE_ON ) {
193  f->p[f->numPoints] = *p1;
194  f->numPoints++;
195  b->p[b->numPoints] = *p1;
196  b->numPoints++;
197  continue;
198  }
199 
200  if ( sides[i] == SIDE_FRONT ) {
201  f->p[f->numPoints] = *p1;
202  f->numPoints++;
203  }
204 
205  if ( sides[i] == SIDE_BACK ) {
206  b->p[b->numPoints] = *p1;
207  b->numPoints++;
208  }
209 
210  if ( sides[i+1] == SIDE_ON || sides[i+1] == sides[i] ) {
211  continue;
212  }
213 
214  // generate a split point
215  p2 = &p[(i+1)%numPoints];
216 
217  // always calculate the split going from the same side
218  // or minor epsilon issues can happen
219  if ( sides[i] == SIDE_FRONT ) {
220  dot = dists[i] / ( dists[i] - dists[i+1] );
221  for ( j = 0; j < 2; j++ ) {
222  // avoid round off error when possible
223  if ( plane[j] == 1.0f ) {
224  mid[j] = plane.z;
225  } else if ( plane[j] == -1.0f ) {
226  mid[j] = -plane.z;
227  } else {
228  mid[j] = (*p1)[j] + dot * ((*p2)[j] - (*p1)[j]);
229  }
230  }
231  } else {
232  dot = dists[i+1] / ( dists[i+1] - dists[i] );
233  for ( j = 0; j < 2; j++ ) {
234  // avoid round off error when possible
235  if ( plane[j] == 1.0f ) {
236  mid[j] = plane.z;
237  } else if ( plane[j] == -1.0f ) {
238  mid[j] = -plane.z;
239  } else {
240  mid[j] = (*p2)[j] + dot * ( (*p1)[j] - (*p2)[j] );
241  }
242  }
243  }
244 
245  f->p[f->numPoints] = mid;
246  f->numPoints++;
247  b->p[b->numPoints] = mid;
248  b->numPoints++;
249  }
250 
251  return SIDE_CROSS;
252 }
253 
254 /*
255 ============
256 idWinding2D::ClipInPlace
257 ============
258 */
259 bool idWinding2D::ClipInPlace( const idVec3 &plane, const float epsilon, const bool keepOn ) {
260  int i, j, maxpts, newNumPoints;
261  int sides[MAX_POINTS_ON_WINDING_2D+1], counts[3];
262  float dot, dists[MAX_POINTS_ON_WINDING_2D+1];
263  idVec2 *p1, *p2, mid, newPoints[MAX_POINTS_ON_WINDING_2D+4];
264 
265  counts[SIDE_FRONT] = counts[SIDE_BACK] = counts[SIDE_ON] = 0;
266 
267  for ( i = 0; i < numPoints; i++ ) {
268  dists[i] = dot = plane.x * p[i].x + plane.y * p[i].y + plane.z;
269  if ( dot > epsilon ) {
270  sides[i] = SIDE_FRONT;
271  } else if ( dot < -epsilon ) {
272  sides[i] = SIDE_BACK;
273  } else {
274  sides[i] = SIDE_ON;
275  }
276  counts[sides[i]]++;
277  }
278  sides[i] = sides[0];
279  dists[i] = dists[0];
280 
281  // if the winding is on the plane and we should keep it
282  if ( keepOn && !counts[SIDE_FRONT] && !counts[SIDE_BACK] ) {
283  return true;
284  }
285  if ( !counts[SIDE_FRONT] ) {
286  numPoints = 0;
287  return false;
288  }
289  if ( !counts[SIDE_BACK] ) {
290  return true;
291  }
292 
293  maxpts = numPoints + 4; // cant use counts[0]+2 because of fp grouping errors
294  newNumPoints = 0;
295 
296  for ( i = 0; i < numPoints; i++ ) {
297  p1 = &p[i];
298 
299  if ( newNumPoints+1 > maxpts ) {
300  return true; // can't split -- fall back to original
301  }
302 
303  if ( sides[i] == SIDE_ON ) {
304  newPoints[newNumPoints] = *p1;
305  newNumPoints++;
306  continue;
307  }
308 
309  if ( sides[i] == SIDE_FRONT ) {
310  newPoints[newNumPoints] = *p1;
311  newNumPoints++;
312  }
313 
314  if ( sides[i+1] == SIDE_ON || sides[i+1] == sides[i] ) {
315  continue;
316  }
317 
318  if ( newNumPoints+1 > maxpts ) {
319  return true; // can't split -- fall back to original
320  }
321 
322  // generate a split point
323  p2 = &p[(i+1)%numPoints];
324 
325  dot = dists[i] / (dists[i] - dists[i+1]);
326  for ( j = 0; j < 2; j++ ) {
327  // avoid round off error when possible
328  if ( plane[j] == 1.0f ) {
329  mid[j] = plane.z;
330  } else if ( plane[j] == -1.0f ) {
331  mid[j] = -plane.z;
332  } else {
333  mid[j] = (*p1)[j] + dot * ((*p2)[j] - (*p1)[j]);
334  }
335  }
336 
337  newPoints[newNumPoints] = mid;
338  newNumPoints++;
339  }
340 
341  if ( newNumPoints >= MAX_POINTS_ON_WINDING_2D ) {
342  return true;
343  }
344 
345  numPoints = newNumPoints;
346  memcpy( p, newPoints, newNumPoints * sizeof(idVec2) );
347 
348  return true;
349 }
350 
351 /*
352 =============
353 idWinding2D::Copy
354 =============
355 */
357  idWinding2D *w;
358 
359  w = new idWinding2D;
360  w->numPoints = numPoints;
361  memcpy( w->p, p, numPoints * sizeof( p[0] ) );
362  return w;
363 }
364 
365 /*
366 =============
367 idWinding2D::Reverse
368 =============
369 */
371  idWinding2D *w;
372  int i;
373 
374  w = new idWinding2D;
375  w->numPoints = numPoints;
376  for ( i = 0; i < numPoints; i++ ) {
377  w->p[ numPoints - i - 1 ] = p[i];
378  }
379  return w;
380 }
381 
382 /*
383 ============
384 idWinding2D::GetArea
385 ============
386 */
387 float idWinding2D::GetArea( void ) const {
388  int i;
389  idVec2 d1, d2;
390  float total;
391 
392  total = 0.0f;
393  for ( i = 2; i < numPoints; i++ ) {
394  d1 = p[i-1] - p[0];
395  d2 = p[i] - p[0];
396  total += d1.x * d2.y - d1.y * d2.x;
397  }
398  return total * 0.5f;
399 }
400 
401 /*
402 ============
403 idWinding2D::GetCenter
404 ============
405 */
407  int i;
408  idVec2 center;
409 
410  center.Zero();
411  for ( i = 0; i < numPoints; i++ ) {
412  center += p[i];
413  }
414  center *= ( 1.0f / numPoints );
415  return center;
416 }
417 
418 /*
419 ============
420 idWinding2D::GetRadius
421 ============
422 */
423 float idWinding2D::GetRadius( const idVec2 &center ) const {
424  int i;
425  float radius, r;
426  idVec2 dir;
427 
428  radius = 0.0f;
429  for ( i = 0; i < numPoints; i++ ) {
430  dir = p[i] - center;
431  r = dir * dir;
432  if ( r > radius ) {
433  radius = r;
434  }
435  }
436  return idMath::Sqrt( radius );
437 }
438 
439 /*
440 ============
441 idWinding2D::GetBounds
442 ============
443 */
444 void idWinding2D::GetBounds( idVec2 bounds[2] ) const {
445  int i;
446 
447  if ( !numPoints ) {
448  bounds[0].x = bounds[0].y = idMath::INFINITY;
449  bounds[1].x = bounds[1].y = -idMath::INFINITY;
450  return;
451  }
452  bounds[0] = bounds[1] = p[0];
453  for ( i = 1; i < numPoints; i++ ) {
454  if ( p[i].x < bounds[0].x ) {
455  bounds[0].x = p[i].x;
456  } else if ( p[i].x > bounds[1].x ) {
457  bounds[1].x = p[i].x;
458  }
459  if ( p[i].y < bounds[0].y ) {
460  bounds[0].y = p[i].y;
461  } else if ( p[i].y > bounds[1].y ) {
462  bounds[1].y = p[i].y;
463  }
464  }
465 }
466 
467 /*
468 =============
469 idWinding2D::IsTiny
470 =============
471 */
472 #define EDGE_LENGTH 0.2f
473 
474 bool idWinding2D::IsTiny( void ) const {
475  int i;
476  float len;
477  idVec2 delta;
478  int edges;
479 
480  edges = 0;
481  for ( i = 0; i < numPoints; i++ ) {
482  delta = p[(i+1)%numPoints] - p[i];
483  len = delta.Length();
484  if ( len > EDGE_LENGTH ) {
485  if ( ++edges == 3 ) {
486  return false;
487  }
488  }
489  }
490  return true;
491 }
492 
493 /*
494 =============
495 idWinding2D::IsHuge
496 =============
497 */
498 bool idWinding2D::IsHuge( void ) const {
499  int i, j;
500 
501  for ( i = 0; i < numPoints; i++ ) {
502  for ( j = 0; j < 2; j++ ) {
503  if ( p[i][j] <= MIN_WORLD_COORD || p[i][j] >= MAX_WORLD_COORD ) {
504  return true;
505  }
506  }
507  }
508  return false;
509 }
510 
511 /*
512 =============
513 idWinding2D::Print
514 =============
515 */
516 void idWinding2D::Print( void ) const {
517  int i;
518 
519  for ( i = 0; i < numPoints; i++ ) {
520  idLib::common->Printf( "(%5.1f, %5.1f)\n", p[i][0], p[i][1] );
521  }
522 }
523 
524 /*
525 =============
526 idWinding2D::PlaneDistance
527 =============
528 */
529 float idWinding2D::PlaneDistance( const idVec3 &plane ) const {
530  int i;
531  float d, min, max;
532 
533  min = idMath::INFINITY;
534  max = -min;
535  for ( i = 0; i < numPoints; i++ ) {
536  d = plane.x * p[i].x + plane.y * p[i].y + plane.z;
537  if ( d < min ) {
538  min = d;
539  if ( FLOATSIGNBITSET( min ) & FLOATSIGNBITNOTSET( max ) ) {
540  return 0.0f;
541  }
542  }
543  if ( d > max ) {
544  max = d;
545  if ( FLOATSIGNBITSET( min ) & FLOATSIGNBITNOTSET( max ) ) {
546  return 0.0f;
547  }
548  }
549  }
550  if ( FLOATSIGNBITNOTSET( min ) ) {
551  return min;
552  }
553  if ( FLOATSIGNBITSET( max ) ) {
554  return max;
555  }
556  return 0.0f;
557 }
558 
559 /*
560 =============
561 idWinding2D::PlaneSide
562 =============
563 */
564 int idWinding2D::PlaneSide( const idVec3 &plane, const float epsilon ) const {
565  bool front, back;
566  int i;
567  float d;
568 
569  front = false;
570  back = false;
571  for ( i = 0; i < numPoints; i++ ) {
572  d = plane.x * p[i].x + plane.y * p[i].y + plane.z;
573  if ( d < -epsilon ) {
574  if ( front ) {
575  return SIDE_CROSS;
576  }
577  back = true;
578  continue;
579  }
580  else if ( d > epsilon ) {
581  if ( back ) {
582  return SIDE_CROSS;
583  }
584  front = true;
585  continue;
586  }
587  }
588 
589  if ( back ) {
590  return SIDE_BACK;
591  }
592  if ( front ) {
593  return SIDE_FRONT;
594  }
595  return SIDE_ON;
596 }
597 
598 /*
599 ============
600 idWinding2D::PointInside
601 ============
602 */
603 bool idWinding2D::PointInside( const idVec2 &point, const float epsilon ) const {
604  int i;
605  float d;
606  idVec3 plane;
607 
608  for ( i = 0; i < numPoints; i++ ) {
609  plane = Plane2DFromPoints( p[i], p[(i+1) % numPoints] );
610  d = plane.x * point.x + plane.y * point.y + plane.z;
611  if ( d > epsilon ) {
612  return false;
613  }
614  }
615  return true;
616 }
617 
618 /*
619 ============
620 idWinding2D::LineIntersection
621 ============
622 */
623 bool idWinding2D::LineIntersection( const idVec2 &start, const idVec2 &end ) const {
624  int i, numEdges;
625  int sides[MAX_POINTS_ON_WINDING_2D+1], counts[3];
626  float d1, d2, epsilon = 0.1f;
627  idVec3 plane, edges[2];
628 
629  counts[SIDE_FRONT] = counts[SIDE_BACK] = counts[SIDE_ON] = 0;
630 
631  plane = Plane2DFromPoints( start, end );
632  for ( i = 0; i < numPoints; i++ ) {
633  d1 = plane.x * p[i].x + plane.y * p[i].y + plane.z;
634  if ( d1 > epsilon ) {
635  sides[i] = SIDE_FRONT;
636  }
637  else if ( d1 < -epsilon ) {
638  sides[i] = SIDE_BACK;
639  }
640  else {
641  sides[i] = SIDE_ON;
642  }
643  counts[sides[i]]++;
644  }
645  sides[i] = sides[0];
646 
647  if ( !counts[SIDE_FRONT] ) {
648  return false;
649  }
650  if ( !counts[SIDE_BACK] ) {
651  return false;
652  }
653 
654  numEdges = 0;
655  for ( i = 0; i < numPoints; i++ ) {
656  if ( sides[i] != sides[i+1] && sides[i+1] != SIDE_ON ) {
657  edges[numEdges++] = Plane2DFromPoints( p[i], p[(i+1)%numPoints] );
658  if ( numEdges >= 2 ) {
659  break;
660  }
661  }
662  }
663  if ( numEdges < 2 ) {
664  return false;
665  }
666 
667  d1 = edges[0].x * start.x + edges[0].y * start.y + edges[0].z;
668  d2 = edges[0].x * end.x + edges[0].y * end.y + edges[0].z;
669  if ( FLOATSIGNBITNOTSET( d1 ) & FLOATSIGNBITNOTSET( d2 ) ) {
670  return false;
671  }
672  d1 = edges[1].x * start.x + edges[1].y * start.y + edges[1].z;
673  d2 = edges[1].x * end.x + edges[1].y * end.y + edges[1].z;
674  if ( FLOATSIGNBITNOTSET( d1 ) & FLOATSIGNBITNOTSET( d2 ) ) {
675  return false;
676  }
677  return true;
678 }
679 
680 /*
681 ============
682 idWinding2D::RayIntersection
683 ============
684 */
685 bool idWinding2D::RayIntersection( const idVec2 &start, const idVec2 &dir, float &scale1, float &scale2, int *edgeNums ) const {
686  int i, numEdges, localEdgeNums[2];
687  int sides[MAX_POINTS_ON_WINDING_2D+1], counts[3];
688  float d1, d2, epsilon = 0.1f;
689  idVec3 plane, edges[2];
690 
691  scale1 = scale2 = 0.0f;
692  counts[SIDE_FRONT] = counts[SIDE_BACK] = counts[SIDE_ON] = 0;
693 
694  plane = Plane2DFromVecs( start, dir );
695  for ( i = 0; i < numPoints; i++ ) {
696  d1 = plane.x * p[i].x + plane.y * p[i].y + plane.z;
697  if ( d1 > epsilon ) {
698  sides[i] = SIDE_FRONT;
699  }
700  else if ( d1 < -epsilon ) {
701  sides[i] = SIDE_BACK;
702  }
703  else {
704  sides[i] = SIDE_ON;
705  }
706  counts[sides[i]]++;
707  }
708  sides[i] = sides[0];
709 
710  if ( !counts[SIDE_FRONT] ) {
711  return false;
712  }
713  if ( !counts[SIDE_BACK] ) {
714  return false;
715  }
716 
717  numEdges = 0;
718  for ( i = 0; i < numPoints; i++ ) {
719  if ( sides[i] != sides[i+1] && sides[i+1] != SIDE_ON ) {
720  localEdgeNums[numEdges] = i;
721  edges[numEdges++] = Plane2DFromPoints( p[i], p[(i+1)%numPoints] );
722  if ( numEdges >= 2 ) {
723  break;
724  }
725  }
726  }
727  if ( numEdges < 2 ) {
728  return false;
729  }
730 
731  d1 = edges[0].x * start.x + edges[0].y * start.y + edges[0].z;
732  d2 = - ( edges[0].x * dir.x + edges[0].y * dir.y );
733  if ( d2 == 0.0f ) {
734  return false;
735  }
736  scale1 = d1 / d2;
737  d1 = edges[1].x * start.x + edges[1].y * start.y + edges[1].z;
738  d2 = - ( edges[1].x * dir.x + edges[1].y * dir.y );
739  if ( d2 == 0.0f ) {
740  return false;
741  }
742  scale2 = d1 / d2;
743 
744  if ( idMath::Fabs( scale1 ) > idMath::Fabs( scale2 ) ) {
745  idSwap( scale1, scale2 );
746  idSwap( localEdgeNums[0], localEdgeNums[1] );
747  }
748 
749  if ( edgeNums ) {
750  edgeNums[0] = localEdgeNums[0];
751  edgeNums[1] = localEdgeNums[1];
752  }
753  return true;
754 }
static const float INFINITY
Definition: Math.h:218
#define min(a, b)
float GetArea(void) const
Definition: Winding2D.cpp:387
bool IsTiny(void) const
Definition: Winding2D.cpp:474
assert(prefInfo.fullscreenBtn)
#define SIDE_CROSS
Definition: Plane.h:50
void Expand(const float d)
Definition: Winding2D.cpp:119
static bool Plane2DIntersection(const idVec3 &plane1, const idVec3 &plane2, idVec2 &point)
Definition: Winding2D.h:149
float y
Definition: Vector.h:55
const GLdouble * v
Definition: glext.h:2936
int numPoints
Definition: Winding2D.h:89
#define SIDE_BACK
Definition: Plane.h:48
int PlaneSide(const idVec3 &plane, const float epsilon=ON_EPSILON) const
Definition: Winding2D.cpp:564
GLenum GLint GLint y
Definition: glext.h:2849
float z
Definition: Vector.h:320
#define MAX_WORLD_COORD
Definition: Lib.h:98
Definition: Vector.h:316
static float Sqrt(float x)
Definition: Math.h:302
idWinding2D(void)
Definition: Winding2D.h:93
float PlaneDistance(const idVec3 &plane) const
Definition: Winding2D.cpp:529
GLenum GLsizei len
Definition: glext.h:3472
float x
Definition: Vector.h:318
void Print(void) const
Definition: Winding2D.cpp:516
GLenum GLint x
Definition: glext.h:2849
int i
Definition: process.py:33
float Length(void) const
Definition: Vector.h:155
idVec2 p[MAX_POINTS_ON_WINDING_2D]
Definition: Winding2D.h:90
#define MIN_WORLD_COORD
Definition: Lib.h:99
void Zero(void)
Definition: Vector.h:119
Definition: Vector.h:52
#define FLOATSIGNBITSET(f)
Definition: Math.h:68
bool PointInside(const idVec2 &point, const float epsilon) const
Definition: Winding2D.cpp:603
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:3454
int Split(const idVec3 &plane, const float epsilon, idWinding2D **front, idWinding2D **back) const
Definition: Winding2D.cpp:142
bool GetAxialBevel(const idVec3 &plane1, const idVec3 &plane2, const idVec2 &point, idVec3 &bevel)
Definition: Winding2D.cpp:40
GLuint GLuint end
Definition: glext.h:2845
static float Fabs(float f)
Definition: Math.h:779
idWinding2D * Copy(void) const
Definition: Winding2D.cpp:356
#define NULL
Definition: Lib.h:88
float y
Definition: Vector.h:319
static idVec3 Plane2DFromPoints(const idVec2 &start, const idVec2 &end, const bool normalize=false)
Definition: Winding2D.h:127
void ExpandForAxialBox(const idVec2 bounds[2])
Definition: Winding2D.cpp:75
idVec2 GetCenter(void) const
Definition: Winding2D.cpp:406
float x
Definition: Vector.h:54
bool ClipInPlace(const idVec3 &plane, const float epsilon=ON_EPSILON, const bool keepOn=false)
Definition: Winding2D.cpp:259
virtual void Printf(const char *fmt,...) id_attribute((format(printf
ID_INLINE void idSwap(type &a, type &b)
Definition: List.h:77
float GetRadius(const idVec2 &center) const
Definition: Winding2D.cpp:423
bool RayIntersection(const idVec2 &start, const idVec2 &dir, float &scale1, float &scale2, int *edgeNums=NULL) const
Definition: Winding2D.cpp:685
GLubyte GLubyte b
Definition: glext.h:4662
#define MAX_POINTS_ON_WINDING_2D
Definition: Winding2D.h:40
#define SIDE_ON
Definition: Plane.h:49
GLdouble GLdouble GLdouble r
Definition: glext.h:2951
tuple f
Definition: idal.py:89
void GetBounds(idVec2 bounds[2]) const
Definition: Winding2D.cpp:444
#define FLOATSIGNBITNOTSET(f)
Definition: Math.h:69
bool LineIntersection(const idVec2 &start, const idVec2 &end) const
Definition: Winding2D.cpp:623
unsigned char byte
Definition: Lib.h:75
#define EDGE_LENGTH
Definition: Winding2D.cpp:472
bool IsHuge(void) const
Definition: Winding2D.cpp:498
float Normalize(void)
Definition: Vector.h:170
GLint j
Definition: qgl.h:264
float dot(float a[], float b[])
Definition: Model_lwo.cpp:3883
idWinding2D * Reverse(void) const
Definition: Winding2D.cpp:370
#define max(x, y)
Definition: os.h:70
GLfloat GLfloat p
Definition: glext.h:4674
#define SIDE_FRONT
Definition: Plane.h:47
GLuint start
Definition: glext.h:2845
static idVec3 Plane2DFromVecs(const idVec2 &start, const idVec2 &dir, const bool normalize=false)
Definition: Winding2D.h:138
static class idCommon * common
Definition: Lib.h:53