91
RayObject* RE_rayface_from_vlak(RayFace *rayface, ObjectInstanceRen *obi, VlakRen *vlr)
88
RayObject *RE_rayface_from_vlak(RayFace *rayface, ObjectInstanceRen *obi, VlakRen *vlr)
93
90
return rayface_from_coords(rayface, obi, vlr, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4 ? vlr->v4->co : 0);
93
RayObject *RE_rayface_from_coords(RayFace *rayface, void *ob, void *face, float *v1, float *v2, float *v3, float *v4)
95
return rayface_from_coords(rayface, ob, face, v1, v2, v3, v4);
96
98
/* VlakPrimitive */
98
RayObject* RE_vlakprimitive_from_vlak(VlakPrimitive *face, struct ObjectInstanceRen *obi, struct VlakRen *vlr)
100
RayObject *RE_vlakprimitive_from_vlak(VlakPrimitive *face, struct ObjectInstanceRen *obi, struct VlakRen *vlr)
101
103
face->face = vlr;
115
117
/* I know... cpu cycle waste, might do smarter once */
116
if (is->mode==RE_RAY_MIRROR)
118
if (is->mode == RE_RAY_MIRROR)
117
119
return !(vlr->mat->mode & MA_ONLYCAST);
119
121
return (is->lay & obi->lay);
122
MALWAYS_INLINE int vlr_check_intersect_solid(Isect *UNUSED(is), ObjectInstanceRen* UNUSED(obi), VlakRen *vlr)
124
MALWAYS_INLINE int vlr_check_intersect_solid(Isect *UNUSED(is), ObjectInstanceRen *UNUSED(obi), VlakRen *vlr)
124
126
/* solid material types only */
125
127
if (vlr->mat->material_type == MA_TYPE_SURFACE)
154
156
sub_v3_v3v3(t1, co3, co1);
156
158
cross_v3_v3v3(x, r, t1);
157
divdet= dot_v3v3(t0, x);
159
divdet = dot_v3v3(t0, x);
159
161
sub_v3_v3v3(m, start, co3);
160
det1= dot_v3v3(m, x);
162
det1 = dot_v3v3(m, x);
162
164
if (divdet != 0.0f) {
165
divdet = 1.0f / divdet;
166
if (v < RE_RAYTRACE_EPSILON && v > -(1.0f+RE_RAYTRACE_EPSILON)) {
168
if (v < RE_RAYTRACE_EPSILON && v > -(1.0f + RE_RAYTRACE_EPSILON)) {
169
171
cross_v3_v3v3(cros, m, t0);
170
u= divdet*dot_v3v3(cros, r);
172
u = divdet * dot_v3v3(cros, r);
172
if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f+RE_RAYTRACE_EPSILON)) {
173
l= divdet*dot_v3v3(cros, t1);
174
if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f + RE_RAYTRACE_EPSILON)) {
175
l = divdet * dot_v3v3(cros, t1);
175
177
/* check if intersection is within ray length */
176
178
if (l > -RE_RAYTRACE_EPSILON && l < *lambda) {
188
190
copy_v3_v3(co4, face->v4);
189
191
sub_v3_v3v3(t0, co3, co4);
190
divdet= dot_v3v3(t0, x);
192
divdet = dot_v3v3(t0, x);
192
194
if (divdet != 0.0f) {
195
divdet = 1.0f / divdet;
196
if (v < RE_RAYTRACE_EPSILON && v > -(1.0f+RE_RAYTRACE_EPSILON)) {
198
if (v < RE_RAYTRACE_EPSILON && v > -(1.0f + RE_RAYTRACE_EPSILON)) {
199
201
cross_v3_v3v3(cros, m, t0);
200
u= divdet*dot_v3v3(cros, r);
202
u = divdet * dot_v3v3(cros, r);
202
if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f+RE_RAYTRACE_EPSILON)) {
203
l= divdet*dot_v3v3(cros, t1);
204
if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f + RE_RAYTRACE_EPSILON)) {
205
l = divdet * dot_v3v3(cros, t1);
205
if (l >- RE_RAYTRACE_EPSILON && l < *lambda) {
207
uv[1]= -(1.0f + v + u);
207
if (l > -RE_RAYTRACE_EPSILON && l < *lambda) {
209
uv[1] = -(1.0f + v + u);
237
239
sub_v3_v3v3(t1, co3, co1);
239
241
cross_v3_v3v3(x, r, t1);
240
divdet= dot_v3v3(t0, x);
242
divdet = dot_v3v3(t0, x);
242
244
sub_v3_v3v3(m, start, co3);
243
det1= dot_v3v3(m, x);
245
det1 = dot_v3v3(m, x);
245
247
if (divdet != 0.0f) {
248
divdet = 1.0f / divdet;
249
if (v < RE_RAYTRACE_EPSILON && v > -(1.0f+RE_RAYTRACE_EPSILON)) {
251
if (v < RE_RAYTRACE_EPSILON && v > -(1.0f + RE_RAYTRACE_EPSILON)) {
252
254
cross_v3_v3v3(cros, m, t0);
253
u= divdet*dot_v3v3(cros, r);
255
u = divdet * dot_v3v3(cros, r);
255
if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f+RE_RAYTRACE_EPSILON))
257
if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f + RE_RAYTRACE_EPSILON))
262
264
copy_v3_v3(co4, face->v4);
263
265
sub_v3_v3v3(t0, co3, co4);
264
divdet= dot_v3v3(t0, x);
266
divdet = dot_v3v3(t0, x);
266
268
if (divdet != 0.0f) {
269
divdet = 1.0f / divdet;
270
if (v < RE_RAYTRACE_EPSILON && v > -(1.0f+RE_RAYTRACE_EPSILON)) {
272
if (v < RE_RAYTRACE_EPSILON && v > -(1.0f + RE_RAYTRACE_EPSILON)) {
273
275
cross_v3_v3v3(cros, m, t0);
274
u= divdet*dot_v3v3(cros, r);
276
u = divdet * dot_v3v3(cros, r);
276
if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f+RE_RAYTRACE_EPSILON))
278
if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f + RE_RAYTRACE_EPSILON))
288
290
MALWAYS_INLINE int intersect_rayface(RayObject *hit_obj, RayFace *face, Isect *is)
290
292
float dist, uv[2];
293
295
/* avoid self-intersection */
294
296
if (is->orig.ob == face->ob && is->orig.face == face->face)
297
299
/* check if we should intersect this face */
298
if (is->check == RE_CHECK_VLR_RENDER)
300
if (vlr_check_intersect(is, (ObjectInstanceRen*)face->ob, (VlakRen*)face->face) == 0)
300
if (is->check == RE_CHECK_VLR_RENDER) {
301
if (vlr_check_intersect(is, (ObjectInstanceRen *)face->ob, (VlakRen *)face->face) == 0)
303
else if (is->check == RE_CHECK_VLR_NON_SOLID_MATERIAL)
305
if (vlr_check_intersect(is, (ObjectInstanceRen*)face->ob, (VlakRen*)face->face) == 0)
304
else if (is->check == RE_CHECK_VLR_NON_SOLID_MATERIAL) {
305
if (vlr_check_intersect(is, (ObjectInstanceRen *)face->ob, (VlakRen *)face->face) == 0)
307
if (vlr_check_intersect_solid(is, (ObjectInstanceRen*)face->ob, (VlakRen*)face->face) == 0)
307
if (vlr_check_intersect_solid(is, (ObjectInstanceRen *)face->ob, (VlakRen *)face->face) == 0)
310
310
else if (is->check == RE_CHECK_VLR_BAKE) {
311
if (vlr_check_bake(is, (ObjectInstanceRen*)face->ob, (VlakRen*)face->face) == 0)
311
if (vlr_check_bake(is, (ObjectInstanceRen *)face->ob, (VlakRen *)face->face) == 0)
315
315
/* ray counter */
316
316
RE_RC_COUNT(is->raycounter->faces.test);
319
ok= isec_tri_quad(is->start, is->dir, face, uv, &dist);
319
ok = isec_tri_quad(is->start, is->dir, face, uv, &dist);
323
323
/* when a shadow ray leaves a face, it can be little outside the edges
324
324
* of it, causing intersection to be detected in its neighbor face */
325
if (is->skip & RE_SKIP_VLR_NEIGHBOUR)
327
if (dist < 0.1f && is->orig.ob == face->ob)
329
VlakRen * a = (VlakRen*)is->orig.face;
330
VlakRen * b = (VlakRen*)face->face;
325
if (is->skip & RE_SKIP_VLR_NEIGHBOUR) {
326
if (dist < 0.1f && is->orig.ob == face->ob) {
327
VlakRen *a = (VlakRen *)is->orig.face;
328
VlakRen *b = (VlakRen *)face->face;
332
330
/* so there's a shared edge or vertex, let's intersect ray with
333
331
* face itself, if that's true we can safely return 1, otherwise
334
332
* we assume the intersection is invalid, 0 */
335
if (a->v1==b->v1 || a->v2==b->v1 || a->v3==b->v1 || a->v4==b->v1
336
|| a->v1==b->v2 || a->v2==b->v2 || a->v3==b->v2 || a->v4==b->v2
337
|| a->v1==b->v3 || a->v2==b->v3 || a->v3==b->v3 || a->v4==b->v3
338
|| (b->v4 && (a->v1==b->v4 || a->v2==b->v4 || a->v3==b->v4 || a->v4==b->v4))) {
333
if (a->v1 == b->v1 || a->v2 == b->v1 || a->v3 == b->v1 || a->v4 == b->v1 ||
334
a->v1 == b->v2 || a->v2 == b->v2 || a->v3 == b->v2 || a->v4 == b->v2 ||
335
a->v1 == b->v3 || a->v2 == b->v3 || a->v3 == b->v3 || a->v4 == b->v3 ||
336
(b->v4 && (a->v1 == b->v4 || a->v2 == b->v4 || a->v3 == b->v4 || a->v4 == b->v4)))
339
338
/* create RayFace from original face, transformed if necessary */
340
339
RayFace origface;
341
ObjectInstanceRen *ob= (ObjectInstanceRen*)is->orig.ob;
342
rayface_from_vlak(&origface, ob, (VlakRen*)is->orig.face);
340
ObjectInstanceRen *ob = (ObjectInstanceRen *)is->orig.ob;
341
rayface_from_vlak(&origface, ob, (VlakRen *)is->orig.face);
344
if (!isec_tri_quad_neighbour(is->start, is->dir, &origface))
343
if (!isec_tri_quad_neighbour(is->start, is->dir, &origface)) {
375
373
RE_RC_COUNT(isec->raycounter->raycast.test);
377
375
/* setup vars used on raycast */
380
isec->idot_axis[i] = 1.0f / isec->dir[i];
382
isec->bv_index[2*i] = isec->idot_axis[i] < 0.0 ? 1 : 0;
383
isec->bv_index[2*i+1] = 1 - isec->bv_index[2*i];
385
isec->bv_index[2*i] = i+3*isec->bv_index[2*i];
386
isec->bv_index[2*i+1] = i+3*isec->bv_index[2*i+1];
376
for (i = 0; i < 3; i++) {
377
isec->idot_axis[i] = 1.0f / isec->dir[i];
379
isec->bv_index[2 * i] = isec->idot_axis[i] < 0.0f ? 1 : 0;
380
isec->bv_index[2 * i + 1] = 1 - isec->bv_index[2 * i];
382
isec->bv_index[2 * i] = i + 3 * isec->bv_index[2 * i];
383
isec->bv_index[2 * i + 1] = i + 3 * isec->bv_index[2 * i + 1];
389
386
#ifdef RT_USE_LAST_HIT
390
387
/* last hit heuristic */
391
if (isec->mode==RE_RAY_SHADOW && isec->last_hit)
388
if (isec->mode == RE_RAY_SHADOW && isec->last_hit) {
393
389
RE_RC_COUNT(isec->raycounter->rayshadow_last_hit.test);
395
if (RE_rayobject_intersect(isec->last_hit, isec))
391
if (RE_rayobject_intersect(isec->last_hit, isec)) {
397
392
RE_RC_COUNT(isec->raycounter->raycast.hit);
398
393
RE_RC_COUNT(isec->raycounter->rayshadow_last_hit.hit);
421
415
int RE_rayobject_intersect(RayObject *r, Isect *i)
423
if (RE_rayobject_isRayFace(r))
425
return intersect_rayface(r, (RayFace*) RE_rayobject_align(r), i);
417
if (RE_rayobject_isRayFace(r)) {
418
return intersect_rayface(r, (RayFace *) RE_rayobject_align(r), i);
427
else if (RE_rayobject_isVlakPrimitive(r))
420
else if (RE_rayobject_isVlakPrimitive(r)) {
429
421
//TODO optimize (useless copy to RayFace to avoid duplicate code)
430
VlakPrimitive *face = (VlakPrimitive*) RE_rayobject_align(r);
422
VlakPrimitive *face = (VlakPrimitive *) RE_rayobject_align(r);
432
424
rayface_from_vlak(&nface, face->ob, face->face);
434
426
return intersect_rayface(r, &nface, i);
436
else if (RE_rayobject_isRayAPI(r))
428
else if (RE_rayobject_isRayAPI(r)) {
438
429
r = RE_rayobject_align(r);
439
430
return r->api->raycast(r, i);
484
473
/* Bounding Boxes */
486
void RE_rayobject_merge_bb(RayObject *r, float *min, float *max)
475
void RE_rayobject_merge_bb(RayObject *r, float min[3], float max[3])
488
if (RE_rayobject_isRayFace(r))
490
RayFace *face = (RayFace*) RE_rayobject_align(r);
477
if (RE_rayobject_isRayFace(r)) {
478
RayFace *face = (RayFace *) RE_rayobject_align(r);
492
480
DO_MINMAX(face->v1, min, max);
493
481
DO_MINMAX(face->v2, min, max);
494
482
DO_MINMAX(face->v3, min, max);
495
483
if (RE_rayface_isQuad(face)) DO_MINMAX(face->v4, min, max);
497
else if (RE_rayobject_isVlakPrimitive(r))
499
VlakPrimitive *face = (VlakPrimitive*) RE_rayobject_align(r);
485
else if (RE_rayobject_isVlakPrimitive(r)) {
486
VlakPrimitive *face = (VlakPrimitive *) RE_rayobject_align(r);
501
488
rayface_from_vlak(&nface, face->ob, face->face);