1.3.49
 
Loading...
Searching...
No Matches
primitiveIntersection.cu
Go to the documentation of this file.
1
16#include <optix.h>
17#include <optixu/optixu_aabb_namespace.h>
18#include <optixu/optixu_math_namespace.h>
19#include <optixu/optixu_matrix_namespace.h>
20
21using namespace optix;
22
23#include "RayTracing.cuh"
24
25rtDeclareVariable(Ray, ray, rtCurrentRay, );
26rtDeclareVariable(PerRayData, prd, rtPayload, );
27
28rtDeclareVariable(unsigned int, UUID, attribute UUID, );
29
30//----------------- Rectangle Primitive ----------------------//
31
34RT_PROGRAM void rectangle_intersect(int objID ) {
35
36 if (prd.origin_UUID == patch_UUID[objID]) { // the ray should not intersect the primitive from which it was launched
37 return;
38 } else if (twosided_flag[patch_UUID[objID]] >= 2) { // if twosided_flag=2, ignore intersection (transparent)
39 return;
40 }
41
42 float3 v0 = patch_vertices[make_uint2(0, objID)];
43 float3 v1 = patch_vertices[make_uint2(1, objID)];
44 float3 v2 = patch_vertices[make_uint2(2, objID)];
45 float3 v3 = patch_vertices[make_uint2(3, objID)];
46
47 float3 anchor = v0;
48 float3 normal = normalize(cross(v1 - v0, v2 - v0));
49
50 float3 a = v1 - v0;
51 float3 b = v3 - v0;
52
53 float t = dot(anchor - ray.origin, normal) / dot(ray.direction, normal);
54
55 if (t == t && t > 1e-8 && t < 1e8) {
56
57 float3 p = ray.origin + ray.direction * t;
58 float3 d = p - anchor;
59
60 float ddota = dot(d, a);
61
62 if (ddota > 0.0 && ddota < dot(a, a)) {
63
64 float ddotb = dot(d, b);
65
66 if (ddotb > 0.0 && ddotb < dot(b, b)) {
67
68 uint U = patch_UUID[objID];
69
70 uint ID = objectID[U];
71
72 if (maskID[ID] == -1) { // no texture transparency
73 if (rtPotentialIntersection(t)) {
74 UUID = patch_UUID[objID];
75 rtReportIntersection(0);
76 }
77 } else { // use transparency mask
78
79 float amag = d_magnitude(a);
80 float bmag = d_magnitude(b);
81 float2 uv = make_float2(ddota / amag / amag, ddotb / bmag / bmag);
82 int2 sz = masksize[maskID[ID]];
83 uint3 ind;
84 if (uvID[ID] == -1) { // does not have custom (u,v) coordinates
85 ind = make_uint3(floorf(float(sz.x - 1) * uv.x), floorf(float(sz.y - 1) * (1.f - uv.y)), maskID[ID]);
86 } else {
87
88 float2 uvmin = uvdata[make_uint2(0, uvID[ID])];
89 float2 duv;
90 duv.x = uvdata[make_uint2(1, uvID[ID])].x - uvdata[make_uint2(0, uvID[ID])].x;
91 duv.y = uvdata[make_uint2(2, uvID[ID])].y - uvdata[make_uint2(1, uvID[ID])].y;
92
93 ind = make_uint3(floorf(float(sz.x - 1) * (uvmin.x + uv.x * duv.x)), floorf(float(sz.y - 1) * (1.f - uvmin.y - uv.y * duv.y)), maskID[ID]);
94 if (ind.x >= sz.x || ind.y >= sz.y) {
95 rtPrintf("ERROR: texture out of bounds. uv = (%f,%f)\n", uv.x, uv.y);
96 }
97 }
98 if (maskdata[ind]) {
99 if (rtPotentialIntersection(t)) {
100 UUID = patch_UUID[objID];
101 rtReportIntersection(0);
102 }
103 }
104 }
105 }
106 }
107 }
108}
109
112RT_PROGRAM void rectangle_bounds(int objID, float result[6]) {
113 optix::Aabb *aabb = (optix::Aabb *) result;
114 float3 v0 = patch_vertices[make_uint2(0, objID)];
115 float3 v1 = patch_vertices[make_uint2(1, objID)];
116 float3 v2 = patch_vertices[make_uint2(2, objID)];
117 float3 v3 = patch_vertices[make_uint2(3, objID)];
118 float3 min = make_float3(fmin(fmin(v0.x, v1.x), fmin(v2.x, v3.x)), fmin(fmin(v0.y, v1.y), fmin(v2.y, v3.y)), fmin(fmin(v0.z, v1.z), fmin(v2.z, v3.z)));
119 float3 max = make_float3(fmax(fmax(v0.x, v1.x), fmax(v2.x, v3.x)), fmax(fmax(v0.y, v1.y), fmax(v2.y, v3.y)), fmax(fmax(v0.z, v1.z), fmax(v2.z, v3.z)));
120 aabb->set(min, max);
121}
122
123//----------------- Triangle Primitive ----------------------//
124
127RT_PROGRAM void triangle_intersect(int objID ) {
128
129 if (prd.origin_UUID == triangle_UUID[objID]) { // the ray should not intersect the primitive from which it was launched
130 return;
131 } else if (twosided_flag[triangle_UUID[objID]] >= 2) { // if twosided_flag=2, ignore intersection (transparent)
132 return;
133 }
134
135 float3 v0 = triangle_vertices[make_uint2(0, objID)];
136 float3 v1 = triangle_vertices[make_uint2(1, objID)];
137 float3 v2 = triangle_vertices[make_uint2(2, objID)];
138
139 float a = v0.x - v1.x, b = v0.x - v2.x, c = ray.direction.x, d = v0.x - ray.origin.x;
140 float e = v0.y - v1.y, f = v0.y - v2.y, g = ray.direction.y, h = v0.y - ray.origin.y;
141 float i = v0.z - v1.z, j = v0.z - v2.z, k = ray.direction.z, l = v0.z - ray.origin.z;
142
143 float m = f * k - g * j, n = h * k - g * l, p = f * l - h * j;
144 float q = g * i - e * k, s = e * j - f * i;
145
146 float inv_denom = 1.f / (a * m + b * q + c * s);
147
148 float e1 = d * m - b * n - c * p;
149 float beta = e1 * inv_denom;
150
151 if (beta > 0.0) {
152
153 float r = r = e * l - h * i;
154 float e2 = a * n + d * q + c * r;
155 float gamma = e2 * inv_denom;
156
157 if (gamma > 0.0 && beta + gamma < 1.0) {
158
159 float e3 = a * p - b * r + d * s;
160 float t = e3 * inv_denom;
161
162 if (t > 1e-8) {
163
164 uint U = triangle_UUID[objID];
165
166 uint ID = objectID[U];
167
168 if (maskID[ID] == -1) { // no texture transparency
169 if (rtPotentialIntersection(t)) {
170 UUID = triangle_UUID[objID];
171 rtReportIntersection(0);
172 }
173 } else { // has texture transparency
174
175 int2 sz = masksize[maskID[ID]];
176
177 float2 uv0 = uvdata[make_uint2(0, uvID[ID])];
178 float2 uv1 = uvdata[make_uint2(1, uvID[ID])];
179 float2 uv2 = uvdata[make_uint2(2, uvID[ID])];
180
181 float2 uv = uv0 + beta * (uv1 - uv0) + gamma * (uv2 - uv0);
182 uv.y = 1.f - uv.y;
183
184 uint3 ind = make_uint3(roundf(float(sz.x - 1) * fabs(uv.x)), roundf(float(sz.y - 1) * fabs(uv.y)), maskID[ID]);
185 if (ind.x >= sz.x || ind.y >= sz.y) {
186 rtPrintf("ERROR: texture out of bounds. uv = (%f,%f)\n", uv.x, uv.y);
187 }
188 if (maskdata[ind]) {
189 if (rtPotentialIntersection(t)) {
190 UUID = triangle_UUID[objID];
191 rtReportIntersection(0);
192 }
193 }
194 }
195 }
196 }
197 }
198}
199
200
202RT_PROGRAM void triangle_bounds(int objID, float result[6]) {
203 optix::Aabb *aabb = (optix::Aabb *) result;
204 float3 v0 = triangle_vertices[make_uint2(0, objID)];
205 float3 v1 = triangle_vertices[make_uint2(1, objID)];
206 float3 v2 = triangle_vertices[make_uint2(2, objID)];
207 float3 mn = make_float3(fmin(fmin(v0.x, v1.x), v2.x), fmin(fmin(v0.y, v1.y), v2.y), fmin(fmin(v0.z, v1.z), v2.z));
208 float3 mx = make_float3(fmax(fmax(v0.x, v1.x), v2.x), fmax(fmax(v0.y, v1.y), v2.y), fmax(fmax(v0.z, v1.z), v2.z));
209 aabb->set(mn, mx);
210}
211
212//----------------- Disk Primitive ----------------------//
213
216RT_PROGRAM void disk_intersect(int objID ) {
217
218 if (prd.origin_UUID == disk_UUID[objID]) { // the ray should not intersect the primitive from which it was launched
219 return;
220 } else if (twosided_flag[disk_UUID[objID]] >= 2) { // if twosided_flag=2, ignore intersection (transparent)
221 return;
222 }
223
224 float3 center = make_float3(0, 0, 0);
225 float3 normal = make_float3(0, 0, 1);
226
227 float t = dot(center - ray.origin, normal) / dot(ray.direction, normal);
228
229 if (t > 1e-6) {
230
231 float3 p = ray.origin + t * ray.direction;
232
233 float3 r = p - center;
234
235 if (r.x * r.x + r.y * r.y + r.z * r.z < 1.f) {
236
237 if (rtPotentialIntersection(t)) {
238 UUID = disk_UUID[objID];
239 rtReportIntersection(0);
240 }
241 }
242 }
243}
244
245
247RT_PROGRAM void disk_bounds(int objID, float result[6]) {
248 optix::Aabb *aabb = (optix::Aabb *) result;
249 float3 mn = make_float3(-1, -1, -0.001f);
250 float3 mx = make_float3(1, 1, 0.001f);
251 aabb->set(mn, mx);
252}
253
254//----------------- Voxel Primitive ----------------------//
255
258RT_PROGRAM void voxel_intersect(int objID ) {
259
260 if (prd.origin_UUID == voxel_UUID[objID]) { // the ray should not intersect the primitive from which it was launched
261 return;
262 } else if (twosided_flag[voxel_UUID[objID]] >= 2) { // if twosided_flag=2, ignore intersection (transparent)
263 return;
264 }
265
266 float x0 = voxel_vertices[make_uint2(0, objID)].x;
267 float y0 = voxel_vertices[make_uint2(0, objID)].y;
268 float z0 = voxel_vertices[make_uint2(0, objID)].z;
269
270 float x1 = voxel_vertices[make_uint2(1, objID)].x;
271 float y1 = voxel_vertices[make_uint2(1, objID)].y;
272 float z1 = voxel_vertices[make_uint2(1, objID)].z;
273
274 float ox = ray.origin.x;
275 float oy = ray.origin.y;
276 float oz = ray.origin.z;
277 float dx = ray.direction.x;
278 float dy = ray.direction.y;
279 float dz = ray.direction.z;
280
281 float tx_min, ty_min, tz_min;
282 float tx_max, ty_max, tz_max;
283
284 float a = 1.0 / dx;
285 if (a >= 0) {
286 tx_min = (x0 - ox) * a;
287 tx_max = (x1 - ox) * a;
288 } else {
289 tx_min = (x1 - ox) * a;
290 tx_max = (x0 - ox) * a;
291 }
292
293 float b = 1.0 / dy;
294 if (b >= 0) {
295 ty_min = (y0 - oy) * b;
296 ty_max = (y1 - oy) * b;
297 } else {
298 ty_min = (y1 - oy) * b;
299 ty_max = (y0 - oy) * b;
300 }
301
302 float c = 1.0 / dz;
303 if (c >= 0) {
304 tz_min = (z0 - oz) * c;
305 tz_max = (z1 - oz) * c;
306 } else {
307 tz_min = (z1 - oz) * c;
308 tz_max = (z0 - oz) * c;
309 }
310
311 float t0, t1;
312
313 // find largest entering t value
314
315 if (tx_min > ty_min)
316 t0 = tx_min;
317 else
318 t0 = ty_min;
319
320 if (tz_min > t0)
321 t0 = tz_min;
322
323 // find smallest exiting t value
324
325 if (tx_max < ty_max)
326 t1 = tx_max;
327 else
328 t1 = ty_max;
329
330 if (tz_max < t1)
331 t1 = tz_max;
332
333 if (t0 < t1 && t0 > 1e-5) { // note: if ray originated inside voxel, no intersection occurs.
334 if (rtPotentialIntersection(t0)) {
335 UUID = voxel_UUID[objID];
336 rtReportIntersection(0);
337 }
338 }
339}
340
343RT_PROGRAM void voxel_bounds(int objID, float result[6]) {
344 optix::Aabb *aabb = (optix::Aabb *) result;
345 float3 min = voxel_vertices[make_uint2(0, objID)];
346 float3 max = voxel_vertices[make_uint2(1, objID)];
347 aabb->set(min, max);
348}
349
350//----------------- Bounding Box Primitive ----------------------//
351
354RT_PROGRAM void bbox_intersect(int objID ) {
355
356 if (prd.origin_UUID == bbox_UUID[objID]) { // the ray should not intersect the primitive from which it was launched
357 return;
358 } else if (twosided_flag[bbox_UUID[objID]] >= 2) { // if twosided_flag=2, ignore intersection (transparent)
359 return;
360 }
361
362 float3 v0 = bbox_vertices[make_uint2(0, objID)];
363 float3 v1 = bbox_vertices[make_uint2(1, objID)];
364 float3 v2 = bbox_vertices[make_uint2(2, objID)];
365 float3 v3 = bbox_vertices[make_uint2(3, objID)];
366
367 float3 anchor = v0;
368 float3 normal = normalize(cross(v1 - v0, v2 - v0));
369
370 float3 a = v1 - v0;
371 float3 b = v3 - v0;
372
373 float t = dot(anchor - ray.origin, normal) / dot(ray.direction, normal);
374
375 if (t == t && t > 1e-8 && t < 1e8) {
376
377 float3 p = ray.origin + ray.direction * t;
378 float3 d = p - anchor;
379
380 float ddota = dot(d, a);
381
382 if (ddota > 0.0 && ddota < dot(a, a)) {
383
384 float ddotb = dot(d, b);
385
386 if (ddotb > 0.0 && ddotb < dot(b, b)) {
387
388 if (rtPotentialIntersection(t)) {
389 UUID = bbox_UUID[objID];
390 rtReportIntersection(0);
391 }
392 }
393 }
394 }
395}
396
399RT_PROGRAM void bbox_bounds(int objID, float result[6]) {
400 optix::Aabb *aabb = (optix::Aabb *) result;
401 float3 v0 = bbox_vertices[make_uint2(0, objID)];
402 float3 v1 = bbox_vertices[make_uint2(1, objID)];
403 float3 v2 = bbox_vertices[make_uint2(2, objID)];
404 float3 v3 = bbox_vertices[make_uint2(3, objID)];
405 float3 min = make_float3(fmin(fmin(v0.x, v1.x), fmin(v2.x, v3.x)), fmin(fmin(v0.y, v1.y), fmin(v2.y, v3.y)), fmin(fmin(v0.z, v1.z), fmin(v2.z, v3.z)));
406 float3 max = make_float3(fmax(fmax(v0.x, v1.x), fmax(v2.x, v3.x)), fmax(fmax(v0.y, v1.y), fmax(v2.y, v3.y)), fmax(fmax(v0.z, v1.z), fmax(v2.z, v3.z)));
407 aabb->set(min, max);
408}
409
410//----------------- Tile Object ----------------------//
411
414RT_PROGRAM void tile_intersect(int objID ) {
415
416 if (prd.origin_UUID == tile_UUID[objID]) { // the ray should not intersect the primitive from which it was launched
417 return;
418 } else if (twosided_flag[tile_UUID[objID]] >= 2) { // if twosided_flag=2, ignore intersection (transparent)
419 return;
420 }
421
422 float3 v0 = tile_vertices[make_uint2(0, objID)];
423 float3 v1 = tile_vertices[make_uint2(1, objID)];
424 float3 v2 = tile_vertices[make_uint2(2, objID)];
425 float3 v3 = tile_vertices[make_uint2(3, objID)];
426
427 float3 anchor = v0;
428 float3 normal = normalize(cross(v1 - v0, v2 - v0));
429
430 float3 a = v1 - v0;
431 float3 b = v3 - v0;
432
433 float t = dot(anchor - ray.origin, normal) / dot(ray.direction, normal);
434
435 if (t == t && t > 1e-8 && t < 1e8) {
436
437 float3 p = ray.origin + ray.direction * t;
438 float3 d = p - anchor;
439
440 float ddota = dot(d, a);
441
442 if (ddota > 0.0 && ddota < dot(a, a)) {
443
444 float ddotb = dot(d, b);
445
446 if (ddotb > 0.0 && ddotb < dot(b, b)) {
447
448 float amag = d_magnitude(a);
449 float bmag = d_magnitude(b);
450 float2 uv = make_float2(ddota / amag / amag, ddotb / bmag / bmag);
451
452 uint U = tile_UUID[objID];
453
454 uint ID = objectID[U];
455
456 if (maskID[ID] == -1) { // no texture transparency
457 if (rtPotentialIntersection(t)) {
458 UUID = U + floorf(uv.y * object_subdivisions[ID].y) * object_subdivisions[ID].x + floorf(uv.x * object_subdivisions[ID].x);
459 rtReportIntersection(0);
460 }
461 } else { // use transparency mask
462
463
464 int2 sz = masksize[maskID[ID]];
465 uint3 ind = make_uint3(floorf(float(sz.x - 1) * uv.x), floorf(float(sz.y - 1) * (1.f - uv.y)), maskID[ID]);
466
467 if (maskdata[ind]) {
468 if (rtPotentialIntersection(t)) {
469 UUID = U + floorf(uv.y * object_subdivisions[ID].y) * object_subdivisions[ID].x + floorf(uv.x * object_subdivisions[ID].x);
470 rtReportIntersection(0);
471 }
472 }
473 }
474 }
475 }
476 }
477}
478
481RT_PROGRAM void tile_bounds(int objID, float result[6]) {
482 optix::Aabb *aabb = (optix::Aabb *) result;
483 float3 v0 = tile_vertices[make_uint2(0, objID)];
484 float3 v1 = tile_vertices[make_uint2(1, objID)];
485 float3 v2 = tile_vertices[make_uint2(2, objID)];
486 float3 v3 = tile_vertices[make_uint2(3, objID)];
487 float3 min = make_float3(fmin(fmin(v0.x, v1.x), fmin(v2.x, v3.x)), fmin(fmin(v0.y, v1.y), fmin(v2.y, v3.y)), fmin(fmin(v0.z, v1.z), fmin(v2.z, v3.z)));
488 float3 max = make_float3(fmax(fmax(v0.x, v1.x), fmax(v2.x, v3.x)), fmax(fmax(v0.y, v1.y), fmax(v2.y, v3.y)), fmax(fmax(v0.z, v1.z), fmax(v2.z, v3.z)));
489 aabb->set(min, max);
490}