fee877b311de7fa2b9a2f1e9cb64a537f18826ac
[blender.git] / source / blender / render / intern / raytrace / rayobject.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2009 Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): AndrĂ© Pinto.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/render/intern/raytrace/rayobject.cpp
29  *  \ingroup render
30  */
31
32
33 #include <assert.h>
34
35 #include "MEM_guardedalloc.h"
36
37 #include "BLI_math.h"
38 #include "BLI_utildefines.h"
39
40 #include "DNA_material_types.h"
41
42 #include "rayintersection.h"
43 #include "rayobject.h"
44 #include "raycounter.h"
45 #include "render_types.h"
46 #include "renderdatabase.h"
47
48 /* RayFace
49  *
50  * note we force always inline here, because compiler refuses to otherwise
51  * because function is too long. Since this is code that is called billions
52  * of times we really do want to inline. */
53
54 MALWAYS_INLINE RayObject *rayface_from_coords(RayFace *rayface, void *ob, void *face,
55                                               float *v1, float *v2, float *v3, float *v4)
56 {
57         rayface->ob = ob;
58         rayface->face = face;
59
60         copy_v3_v3(rayface->v1, v1);
61         copy_v3_v3(rayface->v2, v2);
62         copy_v3_v3(rayface->v3, v3);
63
64         if (v4) {
65                 copy_v3_v3(rayface->v4, v4);
66                 rayface->quad = 1;
67         }
68         else {
69                 rayface->quad = 0;
70         }
71
72         return RE_rayobject_unalignRayFace(rayface);
73 }
74
75 MALWAYS_INLINE void rayface_from_vlak(RayFace *rayface, ObjectInstanceRen *obi, VlakRen *vlr)
76 {
77         rayface_from_coords(rayface, obi, vlr, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4 ? vlr->v4->co : NULL);
78
79         if (obi->transform_primitives) {
80                 mul_m4_v3(obi->mat, rayface->v1);
81                 mul_m4_v3(obi->mat, rayface->v2);
82                 mul_m4_v3(obi->mat, rayface->v3);
83
84                 if (RE_rayface_isQuad(rayface))
85                         mul_m4_v3(obi->mat, rayface->v4);
86         }
87 }
88
89 RayObject *RE_rayface_from_vlak(RayFace *rayface, ObjectInstanceRen *obi, VlakRen *vlr)
90 {
91         return rayface_from_coords(rayface, obi, vlr, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4 ? vlr->v4->co : NULL);
92 }
93
94 RayObject *RE_rayface_from_coords(RayFace *rayface, void *ob, void *face, float *v1, float *v2, float *v3, float *v4)
95 {
96         return rayface_from_coords(rayface, ob, face, v1, v2, v3, v4);
97 }
98
99 /* VlakPrimitive */
100
101 RayObject *RE_vlakprimitive_from_vlak(VlakPrimitive *face, struct ObjectInstanceRen *obi, struct VlakRen *vlr)
102 {
103         face->ob = obi;
104         face->face = vlr;
105
106         return RE_rayobject_unalignVlakPrimitive(face);
107 }
108
109 /* Checks for ignoring faces or materials */
110
111 MALWAYS_INLINE int vlr_check_intersect(Isect *is, ObjectInstanceRen *obi, VlakRen *vlr)
112 {
113         /* for baking selected to active non-traceable materials might still
114          * be in the raytree */
115         if (!(vlr->flag & R_TRACEBLE))
116                 return 0;
117
118         /* I know... cpu cycle waste, might do smarter once */
119         if (is->mode == RE_RAY_MIRROR)
120                 return !(vlr->mat->mode & MA_ONLYCAST);
121         else
122                 return (vlr->mat->mode2 & MA_CASTSHADOW) && (is->lay & obi->lay);
123 }
124
125 MALWAYS_INLINE int vlr_check_intersect_solid(Isect *UNUSED(is), ObjectInstanceRen *UNUSED(obi), VlakRen *vlr)
126 {
127         /* solid material types only */
128         if (vlr->mat->material_type == MA_TYPE_SURFACE)
129                 return 1;
130         else
131                 return 0;
132 }
133
134 MALWAYS_INLINE int vlr_check_bake(Isect *is, ObjectInstanceRen *obi, VlakRen *UNUSED(vlr))
135 {
136         return (obi->obr->ob != is->userdata) && (obi->obr->ob->flag & SELECT);
137 }
138
139 /* Ray Triangle/Quad Intersection */
140
141 static bool isect_ray_tri_watertight_no_sign_check_v3(
142         const float ray_origin[3], const struct IsectRayPrecalc *isect_precalc,
143         const float v0[3], const float v1[3], const float v2[3],
144         float *r_lambda, float r_uv[2])
145 {
146         const int kx = isect_precalc->kx;
147         const int ky = isect_precalc->ky;
148         const int kz = isect_precalc->kz;
149         const float sx = isect_precalc->sx;
150         const float sy = isect_precalc->sy;
151         const float sz = isect_precalc->sz;
152
153         /* Calculate vertices relative to ray origin. */
154         const float a[3] = {v0[0] - ray_origin[0], v0[1] - ray_origin[1], v0[2] - ray_origin[2]};
155         const float b[3] = {v1[0] - ray_origin[0], v1[1] - ray_origin[1], v1[2] - ray_origin[2]};
156         const float c[3] = {v2[0] - ray_origin[0], v2[1] - ray_origin[1], v2[2] - ray_origin[2]};
157
158         const float a_kx = a[kx], a_ky = a[ky], a_kz = a[kz];
159         const float b_kx = b[kx], b_ky = b[ky], b_kz = b[kz];
160         const float c_kx = c[kx], c_ky = c[ky], c_kz = c[kz];
161
162         /* Perform shear and scale of vertices. */
163         const float ax = a_kx - sx * a_kz;
164         const float ay = a_ky - sy * a_kz;
165         const float bx = b_kx - sx * b_kz;
166         const float by = b_ky - sy * b_kz;
167         const float cx = c_kx - sx * c_kz;
168         const float cy = c_ky - sy * c_kz;
169
170         /* Calculate scaled barycentric coordinates. */
171         const float u = cx * by - cy * bx;
172         const float v = ax * cy - ay * cx;
173         const float w = bx * ay - by * ax;
174         float det;
175
176         if ((u < 0.0f || v < 0.0f || w < 0.0f) &&
177             (u > 0.0f || v > 0.0f || w > 0.0f))
178         {
179                 return false;
180         }
181
182         /* Calculate determinant. */
183         det = u + v + w;
184         if (UNLIKELY(det == 0.0f)) {
185                 return false;
186         }
187         else {
188                 /* Calculate scaled z-coordinates of vertices and use them to calculate
189                  * the hit distance.
190                  */
191                 const float t = (u * a_kz + v * b_kz + w * c_kz) * sz;
192                 /* Normalize u, v and t. */
193                 const float inv_det = 1.0f / det;
194                 if (r_uv) {
195                         r_uv[0] = u * inv_det;
196                         r_uv[1] = v * inv_det;
197                 }
198                 *r_lambda = t * inv_det;
199                 return true;
200         }
201 }
202
203 MALWAYS_INLINE int isec_tri_quad(const float start[3],
204                                  const struct IsectRayPrecalc *isect_precalc,
205                                  const RayFace *face,
206                                  float r_uv[2], float *r_lambda)
207 {
208         float uv[2], l;
209
210         if (isect_ray_tri_watertight_v3(start, isect_precalc, face->v1, face->v2, face->v3, &l, uv)) {
211                 /* check if intersection is within ray length */
212                 if (l > -RE_RAYTRACE_EPSILON && l < *r_lambda) {
213                         r_uv[0] = -uv[0];
214                         r_uv[1] = -uv[1];
215                         *r_lambda = l;
216                         return 1;
217                 }
218         }
219
220         /* intersect second triangle in quad */
221         if (RE_rayface_isQuad(face)) {
222                 if (isect_ray_tri_watertight_v3(start, isect_precalc, face->v1, face->v3, face->v4, &l, uv)) {
223                         /* check if intersection is within ray length */
224                         if (l > -RE_RAYTRACE_EPSILON && l < *r_lambda) {
225                                 r_uv[0] = -uv[0];
226                                 r_uv[1] = -uv[1];
227                                 *r_lambda = l;
228                                 return 2;
229                         }
230                 }
231         }
232
233         return 0;
234 }
235
236 /* Simpler yes/no Ray Triangle/Quad Intersection */
237
238 MALWAYS_INLINE int isec_tri_quad_neighbour(const float start[3],
239                                            const float dir[3],
240                                            const RayFace *face)
241 {
242         float r[3];
243         struct IsectRayPrecalc isect_precalc;
244         float uv[2], l;
245
246         negate_v3_v3(r, dir); /* note, different than above function */
247
248         isect_ray_tri_watertight_v3_precalc(&isect_precalc, r);
249
250         if (isect_ray_tri_watertight_no_sign_check_v3(start, &isect_precalc, face->v1, face->v2, face->v3, &l, uv)) {
251                 return 1;
252         }
253
254         /* intersect second triangle in quad */
255         if (RE_rayface_isQuad(face)) {
256                 if (isect_ray_tri_watertight_no_sign_check_v3(start, &isect_precalc, face->v1, face->v3, face->v4, &l, uv)) {
257                         return 2;
258                 }
259         }
260
261         return 0;
262 }
263
264 /* RayFace intersection with checks and neighbor verifaction included,
265  * Isect is modified if the face is hit. */
266
267 MALWAYS_INLINE int intersect_rayface(RayObject *hit_obj, RayFace *face, Isect *is)
268 {
269         float dist, uv[2];
270         int ok = 0;
271
272         /* avoid self-intersection */
273         if (is->orig.ob == face->ob && is->orig.face == face->face)
274                 return 0;
275
276         /* check if we should intersect this face */
277         if (is->check == RE_CHECK_VLR_RENDER) {
278                 if (vlr_check_intersect(is, (ObjectInstanceRen *)face->ob, (VlakRen *)face->face) == 0)
279                         return 0;
280         }
281         else if (is->check == RE_CHECK_VLR_NON_SOLID_MATERIAL) {
282                 if (vlr_check_intersect(is, (ObjectInstanceRen *)face->ob, (VlakRen *)face->face) == 0)
283                         return 0;
284                 if (vlr_check_intersect_solid(is, (ObjectInstanceRen *)face->ob, (VlakRen *)face->face) == 0)
285                         return 0;
286         }
287         else if (is->check == RE_CHECK_VLR_BAKE) {
288                 if (vlr_check_bake(is, (ObjectInstanceRen *)face->ob, (VlakRen *)face->face) == 0)
289                         return 0;
290         }
291
292         /* ray counter */
293         RE_RC_COUNT(is->raycounter->faces.test);
294
295         dist = is->dist;
296         ok = isec_tri_quad(is->start, &is->isect_precalc, face, uv, &dist);
297
298         if (ok) {
299
300                 /* when a shadow ray leaves a face, it can be little outside the edges
301                  * of it, causing intersection to be detected in its neighbor face */
302                 if (is->skip & RE_SKIP_VLR_NEIGHBOUR) {
303                         if (dist < 0.1f && is->orig.ob == face->ob) {
304                                 VlakRen *a = (VlakRen *)is->orig.face;
305                                 VlakRen *b = (VlakRen *)face->face;
306                                 ObjectRen *obr = ((ObjectInstanceRen *)face->ob)->obr;
307
308                                 VertRen **va, **vb;
309                                 int *org_idx_a, *org_idx_b;
310                                 int i, j;
311                                 bool is_neighbor = false;
312
313                                 /* "same" vertex means either the actual same VertRen, or the same 'final org index', if available
314                                  * (autosmooth only, currently). */
315                                 for (i = 0, va = &a->v1; !is_neighbor && i < 4 && *va; ++i, ++va) {
316                                         org_idx_a = RE_vertren_get_origindex(obr, *va, false);
317                                         for (j = 0, vb = &b->v1; !is_neighbor && j < 4 && *vb; ++j, ++vb) {
318                                                 if (*va == *vb) {
319                                                         is_neighbor = true;
320                                                 }
321                                                 else if (org_idx_a) {
322                                                         org_idx_b = RE_vertren_get_origindex(obr, *vb, 0);
323                                                         if (org_idx_b && *org_idx_a == *org_idx_b) {
324                                                                 is_neighbor = true;
325                                                         }
326                                                 }
327                                         }
328                                 }
329
330                                 /* So there's a shared edge or vertex, let's intersect ray with self, if that's true
331                                  * we can safely return 1, otherwise we assume the intersection is invalid, 0 */
332                                 if (is_neighbor) {
333                                         /* create RayFace from original face, transformed if necessary */
334                                         RayFace origface;
335                                         ObjectInstanceRen *ob = (ObjectInstanceRen *)is->orig.ob;
336                                         rayface_from_vlak(&origface, ob, (VlakRen *)is->orig.face);
337
338                                         if (!isec_tri_quad_neighbour(is->start, is->dir, &origface)) {
339                                                 return 0;
340                                         }
341                                 }
342                         }
343                 }
344
345                 RE_RC_COUNT(is->raycounter->faces.hit);
346
347                 is->isect = ok;  // which half of the quad
348                 is->dist = dist;
349                 is->u = uv[0]; is->v = uv[1];
350
351                 is->hit.ob   = face->ob;
352                 is->hit.face = face->face;
353 #ifdef RT_USE_LAST_HIT
354                 is->last_hit = hit_obj;
355 #endif
356                 return 1;
357         }
358
359         return 0;
360 }
361
362 /* Intersection */
363
364 int RE_rayobject_raycast(RayObject *r, Isect *isec)
365 {
366         int i;
367
368         /* Pre-calculate orientation for watertight intersection checks. */
369         isect_ray_tri_watertight_v3_precalc(&isec->isect_precalc, isec->dir);
370
371         RE_RC_COUNT(isec->raycounter->raycast.test);
372
373         /* setup vars used on raycast */
374         for (i = 0; i < 3; i++) {
375                 isec->idot_axis[i]          = 1.0f / isec->dir[i];
376
377                 isec->bv_index[2 * i]       = isec->idot_axis[i] < 0.0f ? 1 : 0;
378                 isec->bv_index[2 * i + 1]   = 1 - isec->bv_index[2 * i];
379
380                 isec->bv_index[2 * i]       = i + 3 * isec->bv_index[2 * i];
381                 isec->bv_index[2 * i + 1]   = i + 3 * isec->bv_index[2 * i + 1];
382         }
383
384 #ifdef RT_USE_LAST_HIT
385         /* last hit heuristic */
386         if (isec->mode == RE_RAY_SHADOW && isec->last_hit) {
387                 RE_RC_COUNT(isec->raycounter->rayshadow_last_hit.test);
388
389                 if (RE_rayobject_intersect(isec->last_hit, isec)) {
390                         RE_RC_COUNT(isec->raycounter->raycast.hit);
391                         RE_RC_COUNT(isec->raycounter->rayshadow_last_hit.hit);
392                         return 1;
393                 }
394         }
395 #endif
396
397 #ifdef RT_USE_HINT
398         isec->hit_hint = 0;
399 #endif
400
401         if (RE_rayobject_intersect(r, isec)) {
402                 RE_RC_COUNT(isec->raycounter->raycast.hit);
403
404 #ifdef RT_USE_HINT
405                 isec->hint = isec->hit_hint;
406 #endif
407                 return 1;
408         }
409
410         return 0;
411 }
412
413 int RE_rayobject_intersect(RayObject *r, Isect *i)
414 {
415         if (RE_rayobject_isRayFace(r)) {
416                 return intersect_rayface(r, (RayFace *) RE_rayobject_align(r), i);
417         }
418         else if (RE_rayobject_isVlakPrimitive(r)) {
419                 //TODO optimize (useless copy to RayFace to avoid duplicate code)
420                 VlakPrimitive *face = (VlakPrimitive *) RE_rayobject_align(r);
421                 RayFace nface;
422                 rayface_from_vlak(&nface, face->ob, face->face);
423
424                 return intersect_rayface(r, &nface, i);
425         }
426         else if (RE_rayobject_isRayAPI(r)) {
427                 r = RE_rayobject_align(r);
428                 return r->api->raycast(r, i);
429         }
430         else {
431                 assert(0);
432                 return 0;
433         }
434 }
435
436 /* Building */
437
438 void RE_rayobject_add(RayObject *r, RayObject *o)
439 {
440         r = RE_rayobject_align(r);
441         return r->api->add(r, o);
442 }
443
444 void RE_rayobject_done(RayObject *r)
445 {
446         r = RE_rayobject_align(r);
447         r->api->done(r);
448 }
449
450 void RE_rayobject_free(RayObject *r)
451 {
452         r = RE_rayobject_align(r);
453         r->api->free(r);
454 }
455
456 float RE_rayobject_cost(RayObject *r)
457 {
458         if (RE_rayobject_isRayFace(r) || RE_rayobject_isVlakPrimitive(r)) {
459                 return 1.0f;
460         }
461         else if (RE_rayobject_isRayAPI(r)) {
462                 r = RE_rayobject_align(r);
463                 return r->api->cost(r);
464         }
465         else {
466                 assert(0);
467                 return 1.0f;
468         }
469 }
470
471 /* Bounding Boxes */
472
473 void RE_rayobject_merge_bb(RayObject *r, float min[3], float max[3])
474 {
475         if (RE_rayobject_isRayFace(r)) {
476                 RayFace *face = (RayFace *) RE_rayobject_align(r);
477
478                 DO_MINMAX(face->v1, min, max);
479                 DO_MINMAX(face->v2, min, max);
480                 DO_MINMAX(face->v3, min, max);
481                 if (RE_rayface_isQuad(face)) DO_MINMAX(face->v4, min, max);
482         }
483         else if (RE_rayobject_isVlakPrimitive(r)) {
484                 VlakPrimitive *face = (VlakPrimitive *) RE_rayobject_align(r);
485                 RayFace nface;
486                 rayface_from_vlak(&nface, face->ob, face->face);
487
488                 DO_MINMAX(nface.v1, min, max);
489                 DO_MINMAX(nface.v2, min, max);
490                 DO_MINMAX(nface.v3, min, max);
491                 if (RE_rayface_isQuad(&nface)) DO_MINMAX(nface.v4, min, max);
492         }
493         else if (RE_rayobject_isRayAPI(r)) {
494                 r = RE_rayobject_align(r);
495                 r->api->bb(r, min, max);
496         }
497         else
498                 assert(0);
499 }
500
501 /* Hints */
502
503 void RE_rayobject_hint_bb(RayObject *r, RayHint *hint, float *min, float *max)
504 {
505         if (RE_rayobject_isRayFace(r) || RE_rayobject_isVlakPrimitive(r)) {
506                 return;
507         }
508         else if (RE_rayobject_isRayAPI(r)) {
509                 r = RE_rayobject_align(r);
510                 return r->api->hint_bb(r, hint, min, max);
511         }
512         else
513                 assert(0);
514 }
515
516 /* RayObjectControl */
517
518 int RE_rayobjectcontrol_test_break(RayObjectControl *control)
519 {
520         if (control->test_break)
521                 return control->test_break(control->data);
522
523         return 0;
524 }
525
526 void RE_rayobject_set_control(RayObject *r, void *data, RE_rayobjectcontrol_test_break_callback test_break)
527 {
528         if (RE_rayobject_isRayAPI(r)) {
529                 r = RE_rayobject_align(r);
530                 r->control.data = data;
531                 r->control.test_break = test_break;
532         }
533 }
534