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