FastAABBTriangleTest.h
Go to the documentation of this file.
1 // FastAABBTriangleTest.h
3 //
4 // Created on: Jan 27, 2014
5 // Author: mklingen
6 // Copied from Tomas_Akenine-Moller's 2001 C code
8 #ifndef FASTAABBTRIANGLETEST_H_
9 #define FASTAABBTRIANGLETEST_H_
10 /********************************************************/
11 /* AABB-triangle overlap test code */
12 /* by Tomas Akenine-Möller */
13 /* Function: int triBoxOverlap(float boxcenter[3], */
14 /* float boxhalfsize[3],float triverts[3][3]); */
15 /* History: */
16 /* 2001-03-05: released the code in its first version */
17 /* 2001-06-18: changed the order of the tests, faster */
18 /* */
19 /* Acknowledgement: Many thanks to Pierre Terdiman for */
20 /* suggestions and discussions on how to optimize code. */
21 /* Thanks to David Hunt for finding a ">="-bug! */
22 /********************************************************/
23 #include <math.h>
24 #include <stdio.h>
25 
27 {
28  #define X 0
29  #define Y 1
30  #define Z 2
31 
32  #define CROSS(dest,v1,v2) \
33  dest[0]=v1[1]*v2[2]-v1[2]*v2[1]; \
34  dest[1]=v1[2]*v2[0]-v1[0]*v2[2]; \
35  dest[2]=v1[0]*v2[1]-v1[1]*v2[0];
36 
37  #define DOT(v1,v2) (v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2])
38 
39  #define SUB(dest,v1,v2) \
40  dest[0]=v1[0]-v2[0]; \
41  dest[1]=v1[1]-v2[1]; \
42  dest[2]=v1[2]-v2[2];
43 
44  #define FINDMINMAX(x0,x1,x2,min,max) \
45  min = max = x0; \
46  if(x1<min) min=x1;\
47  if(x1>max) max=x1;\
48  if(x2<min) min=x2;\
49  if(x2>max) max=x2;
50 
51  int planeBoxOverlap(float normal[3], float vert[3], float maxbox[3]) // -NJMP-
52  {
53  int q;
54  float vmin[3], vmax[3], v;
55  for (q = X; q <= Z; q++)
56  {
57  v = vert[q]; // -NJMP-
58  if (normal[q] > 0.0f)
59  {
60  vmin[q] = -maxbox[q] - v; // -NJMP-
61  vmax[q] = maxbox[q] - v; // -NJMP-
62  }
63  else
64  {
65  vmin[q] = maxbox[q] - v; // -NJMP-
66  vmax[q] = -maxbox[q] - v; // -NJMP-
67  }
68  }
69  if (DOT(normal,vmin) > 0.0f)
70  return 0; // -NJMP-
71  if (DOT(normal,vmax) >= 0.0f)
72  return 1; // -NJMP-
73  return 0;
74  }
75 
76  /*======================== X-tests ========================*/
77  #define AXISTEST_X01(a, b, fa, fb) \
78  p0 = a*v0[Y] - b*v0[Z]; \
79  p2 = a*v2[Y] - b*v2[Z]; \
80  if(p0<p2) {min=p0; max=p2;} else {min=p2; max=p0;} \
81  rad = fa * boxhalfsize[Y] + fb * boxhalfsize[Z]; \
82  if(min>rad || max<-rad) return 0;
83  #define AXISTEST_X2(a, b, fa, fb) \
84  p0 = a*v0[Y] - b*v0[Z]; \
85  p1 = a*v1[Y] - b*v1[Z]; \
86  if(p0<p1) {min=p0; max=p1;} else {min=p1; max=p0;} \
87  rad = fa * boxhalfsize[Y] + fb * boxhalfsize[Z]; \
88  if(min>rad || max<-rad) return 0;
89 
90  /*======================== Y-tests ========================*/
91  #define AXISTEST_Y02(a, b, fa, fb) \
92  p0 = -a*v0[X] + b*v0[Z]; \
93  p2 = -a*v2[X] + b*v2[Z]; \
94  if(p0<p2) {min=p0; max=p2;} else {min=p2; max=p0;} \
95  rad = fa * boxhalfsize[X] + fb * boxhalfsize[Z]; \
96  if(min>rad || max<-rad) return 0;
97 
98  #define AXISTEST_Y1(a, b, fa, fb) \
99  p0 = -a*v0[X] + b*v0[Z]; \
100  p1 = -a*v1[X] + b*v1[Z]; \
101  if(p0<p1) {min=p0; max=p1;} else {min=p1; max=p0;} \
102  rad = fa * boxhalfsize[X] + fb * boxhalfsize[Z]; \
103  if(min>rad || max<-rad) return 0;
104 
105  /*======================== Z-tests ========================*/
106  #define AXISTEST_Z12(a, b, fa, fb) \
107  p1 = a*v1[X] - b*v1[Y]; \
108  p2 = a*v2[X] - b*v2[Y]; \
109  if(p2<p1) {min=p2; max=p1;} else {min=p1; max=p2;} \
110  rad = fa * boxhalfsize[X] + fb * boxhalfsize[Y]; \
111  if(min>rad || max<-rad) return 0;
112  #define AXISTEST_Z0(a, b, fa, fb) \
113  p0 = a*v0[X] - b*v0[Y]; \
114  p1 = a*v1[X] - b*v1[Y]; \
115  if(p0<p1) {min=p0; max=p1;} else {min=p1; max=p0;} \
116  rad = fa * boxhalfsize[X] + fb * boxhalfsize[Y]; \
117  if(min>rad || max<-rad) return 0;
118 
119  int triBoxOverlap(float boxcenter[3], float boxhalfsize[3],
120  float triverts[3][3])
121  {
122  /* use separating axis theorem to test overlap between triangle and box */
123  /* need to test for overlap in these directions: */
124  /* 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle */
125  /* we do not even need to test these) */
126  /* 2) normal of the triangle */
127  /* 3) crossproduct(edge from tri, {x,y,z}-directin) */
128  /* this gives 3x3=9 more tests */
129  float v0[3], v1[3], v2[3];
130  // float axis[3];
131  float min, max, p0, p1, p2, rad, fex, fey, fez; // -NJMP- "d" local variable removed
132  float normal[3], e0[3], e1[3], e2[3];
133  /* This is the fastest branch on Sun */
134  /* move everything so that the boxcenter is in (0,0,0) */
135  SUB(v0, triverts[0], boxcenter);
136  SUB(v1, triverts[1], boxcenter);
137  SUB(v2, triverts[2], boxcenter);
138  /* compute triangle edges */
139  SUB(e0, v1, v0);
140  /* tri edge 0 */
141  SUB(e1, v2, v1);
142  /* tri edge 1 */
143  SUB(e2, v0, v2);
144  /* tri edge 2 */
145  /* Bullet 3: */
146  /* test the 9 tests first (this was faster) */
147  fex = fabs(e0[X]);
148  fey = fabs(e0[Y]);
149  fez = fabs(e0[Z]);
150  AXISTEST_X01(e0[Z], e0[Y], fez, fey);
151  AXISTEST_Y02(e0[Z], e0[X], fez, fex);
152  AXISTEST_Z12(e0[Y], e0[X], fey, fex);
153  fex = fabs(e1[X]);
154  fey = fabs(e1[Y]);
155  fez = fabs(e1[Z]);
156  AXISTEST_X01(e1[Z], e1[Y], fez, fey);
157  AXISTEST_Y02(e1[Z], e1[X], fez, fex);
158  AXISTEST_Z0(e1[Y], e1[X], fey, fex);
159  fex = fabs(e2[X]);
160  fey = fabs(e2[Y]);
161  fez = fabs(e2[Z]);
162  AXISTEST_X2(e2[Z], e2[Y], fez, fey);
163  AXISTEST_Y1(e2[Z], e2[X], fez, fex);
164  AXISTEST_Z12(e2[Y], e2[X], fey, fex);
165  /* Bullet 1: */
166  /* first test overlap in the {x,y,z}-directions */
167  /* find min, max of the triangle each direction, and test for overlap in */
168  /* that direction -- this is equivalent to testing a minimal AABB around */
169  /* the triangle against the AABB */
170  /* test in X-direction */
171  FINDMINMAX(v0[X], v1[X], v2[X], min, max);
172  if (min > boxhalfsize[X] || max < -boxhalfsize[X])
173  return 0;
174  /* test in Y-direction */
175  FINDMINMAX(v0[Y], v1[Y], v2[Y], min, max);
176  if (min > boxhalfsize[Y] || max < -boxhalfsize[Y])
177  return 0;
178  /* test in Z-direction */
179  FINDMINMAX(v0[Z], v1[Z], v2[Z], min, max);
180  if (min > boxhalfsize[Z] || max < -boxhalfsize[Z])
181  return 0;
182  /* Bullet 2: */
183  /* test if the box intersects the plane of the triangle */
184  /* compute plane equation of triangle: normal*x+d=0 */
185  CROSS(normal, e0, e1);
186  // -NJMP- (line removed here)
187  if (!planeBoxOverlap(normal, v0, boxhalfsize))
188  return 0; // -NJMP-
189  return 1; /* box and triangle overlaps */
190  }
191 }
192 #endif /* FASTAABBTRIANGLETEST_H_ */
#define Z
#define AXISTEST_X2(a, b, fa, fb)
#define X
#define SUB(dest, v1, v2)
float max(float a, float b, float c)
#define AXISTEST_Y1(a, b, fa, fb)
#define DOT(v1, v2)
#define CROSS(dest, v1, v2)
#define AXISTEST_X01(a, b, fa, fb)
#define AXISTEST_Z0(a, b, fa, fb)
float min(float a, float b, float c)
#define AXISTEST_Z12(a, b, fa, fb)
#define Y
int planeBoxOverlap(float normal[3], float vert[3], float maxbox[3])
#define AXISTEST_Y02(a, b, fa, fb)
int triBoxOverlap(float boxcenter[3], float boxhalfsize[3], float triverts[3][3])
#define FINDMINMAX(x0, x1, x2, min, max)


or_octomap_plugin
Author(s): Yan Yu
autogenerated on Tue Oct 24 2017 18:02:48