1 // Creative Commons Legal Code
2 //
3 // CC0 1.0 Universal
4 //
5 //     CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
6 //     LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
7 //     ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
8 //     INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
9 //     REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
10 //     PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
11 //     THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
12 //     HEREUNDER.
13 //
14 // Statement of Purpose
15 //
16 // The laws of most jurisdictions throughout the world automatically confer
17 // exclusive Copyright and Related Rights (defined below) upon the creator
18 // and subsequent owner(s) (each and all, an "owner") of an original work of
19 // authorship and/or a database (each, a "Work").
20 //
21 // Certain owners wish to permanently relinquish those rights to a Work for
22 // the purpose of contributing to a commons of creative, cultural and
23 // scientific works ("Commons") that the public can reliably and without fear
24 // of later claims of infringement build upon, modify, incorporate in other
25 // works, reuse and redistribute as freely as possible in any form whatsoever
26 // and for any purposes, including without limitation commercial purposes.
27 // These owners may contribute to the Commons to promote the ideal of a free
28 // culture and the further production of creative, cultural and scientific
29 // works, or to gain reputation or greater distribution for their Work in
30 // part through the use and efforts of others.
31 //
32 // For these and/or other purposes and motivations, and without any
33 // expectation of additional consideration or compensation, the person
34 // associating CC0 with a Work (the "Affirmer"), to the extent that he or she
35 // is an owner of Copyright and Related Rights in the Work, voluntarily
36 // elects to apply CC0 to the Work and publicly distribute the Work under its
37 // terms, with knowledge of his or her Copyright and Related Rights in the
38 // Work and the meaning and intended legal effect of CC0 on those rights.
39 //
40 // 1. Copyright and Related Rights. A Work made available under CC0 may be
41 // protected by copyright and related or neighboring rights ("Copyright and
42 // Related Rights"). Copyright and Related Rights include, but are not
43 // limited to, the following:
44 //
45 //   i. the right to reproduce, adapt, distribute, perform, display,
46 //      communicate, and translate a Work;
47 //  ii. moral rights retained by the original author(s) and/or performer(s);
48 // iii. publicity and privacy rights pertaining to a person's image or
49 //      likeness depicted in a Work;
50 //  iv. rights protecting against unfair competition in regards to a Work,
51 //      subject to the limitations in paragraph 4(a), below;
52 //   v. rights protecting the extraction, dissemination, use and reuse of data
53 //      in a Work;
54 //  vi. database rights (such as those arising under Directive 96/9/EC of the
55 //      European Parliament and of the Council of 11 March 1996 on the legal
56 //      protection of databases, and under any national implementation
57 //      thereof, including any amended or successor version of such
58 //      directive); and
59 // vii. other similar, equivalent or corresponding rights throughout the
60 //      world based on applicable law or treaty, and any national
61 //      implementations thereof.
62 //
63 // 2. Waiver. To the greatest extent permitted by, but not in contravention
64 // of, applicable law, Affirmer hereby overtly, fully, permanently,
65 // irrevocably and unconditionally waives, abandons, and surrenders all of
66 // Affirmer's Copyright and Related Rights and associated claims and causes
67 // of action, whether now known or unknown (including existing as well as
68 // future claims and causes of action), in the Work (i) in all territories
69 // worldwide, (ii) for the maximum duration provided by applicable law or
70 // treaty (including future time extensions), (iii) in any current or future
71 // medium and for any number of copies, and (iv) for any purpose whatsoever,
72 // including without limitation commercial, advertising or promotional
73 // purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
74 // member of the public at large and to the detriment of Affirmer's heirs and
75 // successors, fully intending that such Waiver shall not be subject to
76 // revocation, rescission, cancellation, termination, or any other legal or
77 // equitable action to disrupt the quiet enjoyment of the Work by the public
78 // as contemplated by Affirmer's express Statement of Purpose.
79 //
80 // 3. Public License Fallback. Should any part of the Waiver for any reason
81 // be judged legally invalid or ineffective under applicable law, then the
82 // Waiver shall be preserved to the maximum extent permitted taking into
83 // account Affirmer's express Statement of Purpose. In addition, to the
84 // extent the Waiver is so judged Affirmer hereby grants to each affected
85 // person a royalty-free, non transferable, non sublicensable, non exclusive,
86 // irrevocable and unconditional license to exercise Affirmer's Copyright and
87 // Related Rights in the Work (i) in all territories worldwide, (ii) for the
88 // maximum duration provided by applicable law or treaty (including future
89 // time extensions), (iii) in any current or future medium and for any number
90 // of copies, and (iv) for any purpose whatsoever, including without
91 // limitation commercial, advertising or promotional purposes (the
92 // "License"). The License shall be deemed effective as of the date CC0 was
93 // applied by Affirmer to the Work. Should any part of the License for any
94 // reason be judged legally invalid or ineffective under applicable law, such
95 // partial invalidity or ineffectiveness shall not invalidate the remainder
96 // of the License, and in such case Affirmer hereby affirms that he or she
97 // will not (i) exercise any of his or her remaining Copyright and Related
98 // Rights in the Work or (ii) assert any associated claims and causes of
99 // action with respect to the Work, in either case contrary to Affirmer's
100 // express Statement of Purpose.
101 //
102 // 4. Limitations and Disclaimers.
103 //
104 //  a. No trademark or patent rights held by Affirmer are waived, abandoned,
105 //     surrendered, licensed or otherwise affected by this document.
106 //  b. Affirmer offers the Work as-is and makes no representations or
107 //     warranties of any kind concerning the Work, express, implied,
108 //     statutory or otherwise, including without limitation warranties of
109 //     title, merchantability, fitness for a particular purpose, non
110 //     infringement, or the absence of latent or other defects, accuracy, or
111 //     the present or absence of errors, whether or not discoverable, all to
112 //     the greatest extent permissible under applicable law.
113 //  c. Affirmer disclaims responsibility for clearing rights of other persons
114 //     that may apply to the Work or any use thereof, including without
115 //     limitation any person's Copyright and Related Rights in the Work.
116 //     Further, Affirmer disclaims responsibility for obtaining any necessary
117 //     consents, permissions or other rights required for any use of the
118 //     Work.
119 //  d. Affirmer understands and acknowledges that Creative Commons is not a
120 //     party to this document and has no duty or obligation with respect to
121 //     this CC0 or use of the Work.
122 
123 /********************************************************/
124 /* AABB-triangle overlap test code                      */
125 /* originally by Tomas Akenine-Möller                   */
126 /* modified by Conlain Kelly for ProjectChrono          */
127 /* Function: int triBoxOverlap(float boxcenter[3],      */
128 /*          float boxhalfsize[3],float triverts[3][3]); */
129 /* History:                                             */
130 /*   2001-03-05: released the code in its first version */
131 /*   2001-06-18: changed the order of the tests, faster */
132 /*                                                      */
133 /* Acknowledgement: Many thanks to Pierre Terdiman for  */
134 /* suggestions and discussions on how to optimize code. */
135 /* Thanks to David Hunt for finding a ">="-bug!         */
136 /********************************************************/
137 
138 #pragma once
139 
140 #include <math.h>
141 #include <stdio.h>
142 
143 #define X 0
144 #define Y 1
145 #define Z 2
146 
147 #define CROSS(dest, v1, v2)                  \
148     dest[0] = v1[1] * v2[2] - v1[2] * v2[1]; \
149     dest[1] = v1[2] * v2[0] - v1[0] * v2[2]; \
150     dest[2] = v1[0] * v2[1] - v1[1] * v2[0];
151 
152 #define DOT(v1, v2) (v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2])
153 
154 #define SUB(dest, v1, v2)    \
155     dest[0] = v1[0] - v2[0]; \
156     dest[1] = v1[1] - v2[1]; \
157     dest[2] = v1[2] - v2[2];
158 
159 #define SUBTRACT(dest, v1, v2) \
160     dest[0] = v1.x - v2[0];    \
161     dest[1] = v1.y - v2[1];    \
162     dest[2] = v1.z - v2[2];
163 
164 #define FINDMINMAX(x0, x1, x2, min, max) \
165     min = max = x0;                      \
166     if (x1 < min)                        \
167         min = x1;                        \
168     if (x1 > max)                        \
169         max = x1;                        \
170     if (x2 < min)                        \
171         min = x2;                        \
172     if (x2 > max)                        \
173         max = x2;
174 
planeBoxOverlap(float normal[3],float vert[3],float maxbox[3])175 inline __device__ bool planeBoxOverlap(float normal[3], float vert[3], float maxbox[3]) {
176     int q;
177     float vmin[3], vmax[3], v;
178     for (q = X; q <= Z; q++) {
179         v = vert[q];
180         if (normal[q] > 0.0f) {
181             vmin[q] = -maxbox[q] - v;
182             vmax[q] = maxbox[q] - v;
183         } else {
184             vmin[q] = maxbox[q] - v;
185             vmax[q] = -maxbox[q] - v;
186         }
187     }
188     if (DOT(normal, vmin) > 0.0f)
189         return false;
190     if (DOT(normal, vmax) >= 0.0f)
191         return true;
192 
193     return false;
194 }
195 
196 /*======================== X-tests ========================*/
197 #define AXISTEST_X01(a, b, fa, fb)                   \
198     p0 = a * v0[Y] - b * v0[Z];                      \
199     p2 = a * v2[Y] - b * v2[Z];                      \
200     if (p0 < p2) {                                   \
201         min = p0;                                    \
202         max = p2;                                    \
203     } else {                                         \
204         min = p2;                                    \
205         max = p0;                                    \
206     }                                                \
207     rad = fa * boxhalfsize[Y] + fb * boxhalfsize[Z]; \
208     if (min > rad || max < -rad)                     \
209         return false;
210 
211 #define AXISTEST_X2(a, b, fa, fb)                    \
212     p0 = a * v0[Y] - b * v0[Z];                      \
213     p1 = a * v1[Y] - b * v1[Z];                      \
214     if (p0 < p1) {                                   \
215         min = p0;                                    \
216         max = p1;                                    \
217     } else {                                         \
218         min = p1;                                    \
219         max = p0;                                    \
220     }                                                \
221     rad = fa * boxhalfsize[Y] + fb * boxhalfsize[Z]; \
222     if (min > rad || max < -rad)                     \
223         return false;
224 
225 /*======================== Y-tests ========================*/
226 #define AXISTEST_Y02(a, b, fa, fb)                   \
227     p0 = -a * v0[X] + b * v0[Z];                     \
228     p2 = -a * v2[X] + b * v2[Z];                     \
229     if (p0 < p2) {                                   \
230         min = p0;                                    \
231         max = p2;                                    \
232     } else {                                         \
233         min = p2;                                    \
234         max = p0;                                    \
235     }                                                \
236     rad = fa * boxhalfsize[X] + fb * boxhalfsize[Z]; \
237     if (min > rad || max < -rad)                     \
238         return false;
239 
240 #define AXISTEST_Y1(a, b, fa, fb)                    \
241     p0 = -a * v0[X] + b * v0[Z];                     \
242     p1 = -a * v1[X] + b * v1[Z];                     \
243     if (p0 < p1) {                                   \
244         min = p0;                                    \
245         max = p1;                                    \
246     } else {                                         \
247         min = p1;                                    \
248         max = p0;                                    \
249     }                                                \
250     rad = fa * boxhalfsize[X] + fb * boxhalfsize[Z]; \
251     if (min > rad || max < -rad)                     \
252         return false;
253 
254 /*======================== Z-tests ========================*/
255 
256 #define AXISTEST_Z12(a, b, fa, fb)                   \
257     p1 = a * v1[X] - b * v1[Y];                      \
258     p2 = a * v2[X] - b * v2[Y];                      \
259     if (p2 < p1) {                                   \
260         min = p2;                                    \
261         max = p1;                                    \
262     } else {                                         \
263         min = p1;                                    \
264         max = p2;                                    \
265     }                                                \
266     rad = fa * boxhalfsize[X] + fb * boxhalfsize[Y]; \
267     if (min > rad || max < -rad)                     \
268         return false;
269 
270 #define AXISTEST_Z0(a, b, fa, fb)                    \
271     p0 = a * v0[X] - b * v0[Y];                      \
272     p1 = a * v1[X] - b * v1[Y];                      \
273     if (p0 < p1) {                                   \
274         min = p0;                                    \
275         max = p1;                                    \
276     } else {                                         \
277         min = p1;                                    \
278         max = p0;                                    \
279     }                                                \
280     rad = fa * boxhalfsize[X] + fb * boxhalfsize[Y]; \
281     if (min > rad || max < -rad)                     \
282         return false;
283 
284 /**
285 * Figure out whether a triangle touches an SD. Function gets hit a lot, very desirable to be fast.
286 Input:
287 - boxcenter: defines center of the box
288 - boxhalfsize: half the size of the box in an axis aligned context
289 - vA, vB, vC: the three vertices of the triangle
290 Output:
291 - "true" if there is overlap; "false" otherwise
292 NOTE: This function works with "float" - precision is not paramount.
293 */
check_TriangleBoxOverlap(float boxcenter[3],float boxhalfsize[3],const float3 & vA,const float3 & vB,const float3 & vC)294 inline __device__ bool check_TriangleBoxOverlap(float boxcenter[3],
295                                                 float boxhalfsize[3],
296                                                 const float3& vA,
297                                                 const float3& vB,
298                                                 const float3& vC) {
299     /**    Use the separating axis theorem to test overlap between triangle and box.
300     We test for overlap in these directions:
301     1) the {x,y,z}-directions (actually, since we use the AABB of the triangle we do not even need to test these)
302     2) normal of the triangle
303     3) crossproduct(edge from tri, {x,y,z}-directin) this gives 3x3=9 more tests */
304     float v0[3], v1[3], v2[3];
305     float min, max, p0, p1, p2, rad, fex, fey, fez;
306     float normal[3], e0[3], e1[3], e2[3];
307 
308     /* This is the fastest branch on Sun */
309     /* move everything so that the boxcenter is in (0,0,0) */
310     SUBTRACT(v0, vA, boxcenter);
311     SUBTRACT(v1, vB, boxcenter);
312     SUBTRACT(v2, vC, boxcenter);
313 
314     /* compute triangle edges */
315     SUB(e0, v1, v0); /* tri edge 0 */
316     SUB(e1, v2, v1); /* tri edge 1 */
317     SUB(e2, v0, v2); /* tri edge 2 */
318 
319     /* Case 3)  */
320     /*  test the 9 tests first (this was faster) */
321     fex = fabsf(e0[X]);
322     fey = fabsf(e0[Y]);
323     fez = fabsf(e0[Z]);
324     AXISTEST_X01(e0[Z], e0[Y], fez, fey);
325     AXISTEST_Y02(e0[Z], e0[X], fez, fex);
326     AXISTEST_Z12(e0[Y], e0[X], fey, fex);
327 
328     fex = fabsf(e1[X]);
329     fey = fabsf(e1[Y]);
330     fez = fabsf(e1[Z]);
331     AXISTEST_X01(e1[Z], e1[Y], fez, fey);
332     AXISTEST_Y02(e1[Z], e1[X], fez, fex);
333     AXISTEST_Z0(e1[Y], e1[X], fey, fex);
334 
335     fex = fabsf(e2[X]);
336     fey = fabsf(e2[Y]);
337     fez = fabsf(e2[Z]);
338     AXISTEST_X2(e2[Z], e2[Y], fez, fey);
339     AXISTEST_Y1(e2[Z], e2[X], fez, fex);
340     AXISTEST_Z12(e2[Y], e2[X], fey, fex);
341 
342     /* Case 1) */
343     /*  first test overlap in the {x,y,z}-directions */
344     /*  find min, max of the triangle each direction, and test for overlap in */
345     /*  that direction -- this is equivalent to testing a minimal AABB around */
346     /*  the triangle against the AABB */
347 
348     /* test in X-direction */
349     FINDMINMAX(v0[X], v1[X], v2[X], min, max);
350     if (min > boxhalfsize[X] || max < -boxhalfsize[X])
351         return false;
352 
353     /* test in Y-direction */
354     FINDMINMAX(v0[Y], v1[Y], v2[Y], min, max);
355     if (min > boxhalfsize[Y] || max < -boxhalfsize[Y])
356         return false;
357 
358     /* test in Z-direction */
359     FINDMINMAX(v0[Z], v1[Z], v2[Z], min, max);
360     if (min > boxhalfsize[Z] || max < -boxhalfsize[Z])
361         return false;
362 
363     /* Case 2) */
364     /*  test if the box intersects the plane of the triangle */
365     /*  compute plane equation of triangle: normal*x+d=0 */
366     CROSS(normal, e0, e1);
367     if (!planeBoxOverlap(normal, v0, boxhalfsize))
368         return false;
369 
370     return true; /* box and triangle overlaps */
371 }
372