Blender Internal: Add material property "Cast" which can disable both ray and buffer...
[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 MALWAYS_INLINE int isec_tri_quad(float start[3], float dir[3], RayFace *face, float uv[2], float *lambda)
142 {
143         float co1[3], co2[3], co3[3], co4[3];
144         float t0[3], t1[3], x[3], r[3], m[3], u, v, divdet, det1, l;
145         int quad;
146
147         quad = RE_rayface_isQuad(face);
148
149         copy_v3_v3(co1, face->v1);
150         copy_v3_v3(co2, face->v2);
151         copy_v3_v3(co3, face->v3);
152
153         copy_v3_v3(r, dir);
154
155         /* intersect triangle */
156         sub_v3_v3v3(t0, co3, co2);
157         sub_v3_v3v3(t1, co3, co1);
158
159         cross_v3_v3v3(x, r, t1);
160         divdet = dot_v3v3(t0, x);
161
162         sub_v3_v3v3(m, start, co3);
163         det1 = dot_v3v3(m, x);
164         
165         if (divdet != 0.0f) {
166                 divdet = 1.0f / divdet;
167                 v = det1 * divdet;
168
169                 if (v < RE_RAYTRACE_EPSILON && v > -(1.0f + RE_RAYTRACE_EPSILON)) {
170                         float cros[3];
171
172                         cross_v3_v3v3(cros, m, t0);
173                         u = divdet * dot_v3v3(cros, r);
174
175                         if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f + RE_RAYTRACE_EPSILON)) {
176                                 l = divdet * dot_v3v3(cros, t1);
177
178                                 /* check if intersection is within ray length */
179                                 if (l > -RE_RAYTRACE_EPSILON && l < *lambda) {
180                                         uv[0] = u;
181                                         uv[1] = v;
182                                         *lambda = l;
183                                         return 1;
184                                 }
185                         }
186                 }
187         }
188
189         /* intersect second triangle in quad */
190         if (quad) {
191                 copy_v3_v3(co4, face->v4);
192                 sub_v3_v3v3(t0, co3, co4);
193                 divdet = dot_v3v3(t0, x);
194
195                 if (divdet != 0.0f) {
196                         divdet = 1.0f / divdet;
197                         v = det1 * divdet;
198                         
199                         if (v < RE_RAYTRACE_EPSILON && v > -(1.0f + RE_RAYTRACE_EPSILON)) {
200                                 float cros[3];
201
202                                 cross_v3_v3v3(cros, m, t0);
203                                 u = divdet * dot_v3v3(cros, r);
204         
205                                 if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f + RE_RAYTRACE_EPSILON)) {
206                                         l = divdet * dot_v3v3(cros, t1);
207                                         
208                                         if (l > -RE_RAYTRACE_EPSILON && l < *lambda) {
209                                                 uv[0] = u;
210                                                 uv[1] = -(1.0f + v + u);
211                                                 *lambda = l;
212                                                 return 2;
213                                         }
214                                 }
215                         }
216                 }
217         }
218
219         return 0;
220 }
221
222 /* Simpler yes/no Ray Triangle/Quad Intersection */
223
224 MALWAYS_INLINE int isec_tri_quad_neighbour(float start[3], float dir[3], RayFace *face)
225 {
226         float co1[3], co2[3], co3[3], co4[3];
227         float t0[3], t1[3], x[3], r[3], m[3], u, v, divdet, det1;
228         int quad;
229
230         quad = RE_rayface_isQuad(face);
231
232         copy_v3_v3(co1, face->v1);
233         copy_v3_v3(co2, face->v2);
234         copy_v3_v3(co3, face->v3);
235
236         negate_v3_v3(r, dir); /* note, different than above function */
237
238         /* intersect triangle */
239         sub_v3_v3v3(t0, co3, co2);
240         sub_v3_v3v3(t1, co3, co1);
241
242         cross_v3_v3v3(x, r, t1);
243         divdet = dot_v3v3(t0, x);
244
245         sub_v3_v3v3(m, start, co3);
246         det1 = dot_v3v3(m, x);
247         
248         if (divdet != 0.0f) {
249                 divdet = 1.0f / divdet;
250                 v = det1 * divdet;
251
252                 if (v < RE_RAYTRACE_EPSILON && v > -(1.0f + RE_RAYTRACE_EPSILON)) {
253                         float cros[3];
254
255                         cross_v3_v3v3(cros, m, t0);
256                         u = divdet * dot_v3v3(cros, r);
257
258                         if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f + RE_RAYTRACE_EPSILON))
259                                 return 1;
260                 }
261         }
262
263         /* intersect second triangle in quad */
264         if (quad) {
265                 copy_v3_v3(co4, face->v4);
266                 sub_v3_v3v3(t0, co3, co4);
267                 divdet = dot_v3v3(t0, x);
268
269                 if (divdet != 0.0f) {
270                         divdet = 1.0f / divdet;
271                         v = det1 * divdet;
272                         
273                         if (v < RE_RAYTRACE_EPSILON && v > -(1.0f + RE_RAYTRACE_EPSILON)) {
274                                 float cros[3];
275
276                                 cross_v3_v3v3(cros, m, t0);
277                                 u = divdet * dot_v3v3(cros, r);
278         
279                                 if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f + RE_RAYTRACE_EPSILON))
280                                         return 2;
281                         }
282                 }
283         }
284
285         return 0;
286 }
287
288 /* RayFace intersection with checks and neighbor verifaction included,
289  * Isect is modified if the face is hit. */
290
291 MALWAYS_INLINE int intersect_rayface(RayObject *hit_obj, RayFace *face, Isect *is)
292 {
293         float dist, uv[2];
294         int ok = 0;
295         
296         /* avoid self-intersection */
297         if (is->orig.ob == face->ob && is->orig.face == face->face)
298                 return 0;
299                 
300         /* check if we should intersect this face */
301         if (is->check == RE_CHECK_VLR_RENDER) {
302                 if (vlr_check_intersect(is, (ObjectInstanceRen *)face->ob, (VlakRen *)face->face) == 0)
303                         return 0;
304         }
305         else if (is->check == RE_CHECK_VLR_NON_SOLID_MATERIAL) {
306                 if (vlr_check_intersect(is, (ObjectInstanceRen *)face->ob, (VlakRen *)face->face) == 0)
307                         return 0;
308                 if (vlr_check_intersect_solid(is, (ObjectInstanceRen *)face->ob, (VlakRen *)face->face) == 0)
309                         return 0;
310         }
311         else if (is->check == RE_CHECK_VLR_BAKE) {
312                 if (vlr_check_bake(is, (ObjectInstanceRen *)face->ob, (VlakRen *)face->face) == 0)
313                         return 0;
314         }
315
316         /* ray counter */
317         RE_RC_COUNT(is->raycounter->faces.test);
318
319         dist = is->dist;
320         ok = isec_tri_quad(is->start, is->dir, face, uv, &dist);
321
322         if (ok) {
323         
324                 /* when a shadow ray leaves a face, it can be little outside the edges
325                  * of it, causing intersection to be detected in its neighbor face */
326                 if (is->skip & RE_SKIP_VLR_NEIGHBOUR) {
327                         if (dist < 0.1f && is->orig.ob == face->ob) {
328                                 VlakRen *a = (VlakRen *)is->orig.face;
329                                 VlakRen *b = (VlakRen *)face->face;
330                                 ObjectRen *obr = ((ObjectInstanceRen *)face->ob)->obr;
331
332                                 VertRen **va, **vb;
333                                 int *org_idx_a, *org_idx_b;
334                                 int i, j;
335                                 bool is_neighbor = false;
336
337                                 /* "same" vertex means either the actual same VertRen, or the same 'final org index', if available
338                                  * (autosmooth only, currently). */
339                                 for (i = 0, va = &a->v1; !is_neighbor && i < 4 && *va; ++i, ++va) {
340                                         org_idx_a = RE_vertren_get_origindex(obr, *va, false);
341                                         for (j = 0, vb = &b->v1; !is_neighbor && j < 4 && *vb; ++j, ++vb) {
342                                                 if (*va == *vb) {
343                                                         is_neighbor = true;
344                                                 }
345                                                 else if (org_idx_a) {
346                                                         org_idx_b = RE_vertren_get_origindex(obr, *vb, 0);
347                                                         if (org_idx_b && *org_idx_a == *org_idx_b) {
348                                                                 is_neighbor = true;
349                                                         }
350                                                 }
351                                         }
352                                 }
353
354                                 /* So there's a shared edge or vertex, let's intersect ray with self, if that's true
355                                  * we can safely return 1, otherwise we assume the intersection is invalid, 0 */
356                                 if (is_neighbor) {
357                                         /* create RayFace from original face, transformed if necessary */
358                                         RayFace origface;
359                                         ObjectInstanceRen *ob = (ObjectInstanceRen *)is->orig.ob;
360                                         rayface_from_vlak(&origface, ob, (VlakRen *)is->orig.face);
361
362                                         if (!isec_tri_quad_neighbour(is->start, is->dir, &origface)) {
363                                                 return 0;
364                                         }
365                                 }
366                         }
367                 }
368
369                 RE_RC_COUNT(is->raycounter->faces.hit);
370
371                 is->isect = ok;  // which half of the quad
372                 is->dist = dist;
373                 is->u = uv[0]; is->v = uv[1];
374
375                 is->hit.ob   = face->ob;
376                 is->hit.face = face->face;
377 #ifdef RT_USE_LAST_HIT
378                 is->last_hit = hit_obj;
379 #endif
380                 return 1;
381         }
382
383         return 0;
384 }
385
386 /* Intersection */
387
388 int RE_rayobject_raycast(RayObject *r, Isect *isec)
389 {
390         int i;
391
392         RE_RC_COUNT(isec->raycounter->raycast.test);
393
394         /* setup vars used on raycast */
395         for (i = 0; i < 3; i++) {
396                 isec->idot_axis[i]          = 1.0f / isec->dir[i];
397                 
398                 isec->bv_index[2 * i]       = isec->idot_axis[i] < 0.0f ? 1 : 0;
399                 isec->bv_index[2 * i + 1]   = 1 - isec->bv_index[2 * i];
400                 
401                 isec->bv_index[2 * i]       = i + 3 * isec->bv_index[2 * i];
402                 isec->bv_index[2 * i + 1]   = i + 3 * isec->bv_index[2 * i + 1];
403         }
404
405 #ifdef RT_USE_LAST_HIT  
406         /* last hit heuristic */
407         if (isec->mode == RE_RAY_SHADOW && isec->last_hit) {
408                 RE_RC_COUNT(isec->raycounter->rayshadow_last_hit.test);
409                 
410                 if (RE_rayobject_intersect(isec->last_hit, isec)) {
411                         RE_RC_COUNT(isec->raycounter->raycast.hit);
412                         RE_RC_COUNT(isec->raycounter->rayshadow_last_hit.hit);
413                         return 1;
414                 }
415         }
416 #endif
417
418 #ifdef RT_USE_HINT
419         isec->hit_hint = 0;
420 #endif
421
422         if (RE_rayobject_intersect(r, isec)) {
423                 RE_RC_COUNT(isec->raycounter->raycast.hit);
424
425 #ifdef RT_USE_HINT
426                 isec->hint = isec->hit_hint;
427 #endif
428                 return 1;
429         }
430
431         return 0;
432 }
433
434 int RE_rayobject_intersect(RayObject *r, Isect *i)
435 {
436         if (RE_rayobject_isRayFace(r)) {
437                 return intersect_rayface(r, (RayFace *) RE_rayobject_align(r), i);
438         }
439         else if (RE_rayobject_isVlakPrimitive(r)) {
440                 //TODO optimize (useless copy to RayFace to avoid duplicate code)
441                 VlakPrimitive *face = (VlakPrimitive *) RE_rayobject_align(r);
442                 RayFace nface;
443                 rayface_from_vlak(&nface, face->ob, face->face);
444
445                 return intersect_rayface(r, &nface, i);
446         }
447         else if (RE_rayobject_isRayAPI(r)) {
448                 r = RE_rayobject_align(r);
449                 return r->api->raycast(r, i);
450         }
451         else {
452                 assert(0);
453                 return 0;
454         }
455 }
456
457 /* Building */
458
459 void RE_rayobject_add(RayObject *r, RayObject *o)
460 {
461         r = RE_rayobject_align(r);
462         return r->api->add(r, o);
463 }
464
465 void RE_rayobject_done(RayObject *r)
466 {
467         r = RE_rayobject_align(r);
468         r->api->done(r);
469 }
470
471 void RE_rayobject_free(RayObject *r)
472 {
473         r = RE_rayobject_align(r);
474         r->api->free(r);
475 }
476
477 float RE_rayobject_cost(RayObject *r)
478 {
479         if (RE_rayobject_isRayFace(r) || RE_rayobject_isVlakPrimitive(r)) {
480                 return 1.0f;
481         }
482         else if (RE_rayobject_isRayAPI(r)) {
483                 r = RE_rayobject_align(r);
484                 return r->api->cost(r);
485         }
486         else {
487                 assert(0);
488                 return 1.0f;
489         }
490 }
491
492 /* Bounding Boxes */
493
494 void RE_rayobject_merge_bb(RayObject *r, float min[3], float max[3])
495 {
496         if (RE_rayobject_isRayFace(r)) {
497                 RayFace *face = (RayFace *) RE_rayobject_align(r);
498                 
499                 DO_MINMAX(face->v1, min, max);
500                 DO_MINMAX(face->v2, min, max);
501                 DO_MINMAX(face->v3, min, max);
502                 if (RE_rayface_isQuad(face)) DO_MINMAX(face->v4, min, max);
503         }
504         else if (RE_rayobject_isVlakPrimitive(r)) {
505                 VlakPrimitive *face = (VlakPrimitive *) RE_rayobject_align(r);
506                 RayFace nface;
507                 rayface_from_vlak(&nface, face->ob, face->face);
508
509                 DO_MINMAX(nface.v1, min, max);
510                 DO_MINMAX(nface.v2, min, max);
511                 DO_MINMAX(nface.v3, min, max);
512                 if (RE_rayface_isQuad(&nface)) DO_MINMAX(nface.v4, min, max);
513         }
514         else if (RE_rayobject_isRayAPI(r)) {
515                 r = RE_rayobject_align(r);
516                 r->api->bb(r, min, max);
517         }
518         else
519                 assert(0);
520 }
521
522 /* Hints */
523
524 void RE_rayobject_hint_bb(RayObject *r, RayHint *hint, float *min, float *max)
525 {
526         if (RE_rayobject_isRayFace(r) || RE_rayobject_isVlakPrimitive(r)) {
527                 return;
528         }
529         else if (RE_rayobject_isRayAPI(r)) {
530                 r = RE_rayobject_align(r);
531                 return r->api->hint_bb(r, hint, min, max);
532         }
533         else
534                 assert(0);
535 }
536
537 /* RayObjectControl */
538
539 int RE_rayobjectcontrol_test_break(RayObjectControl *control)
540 {
541         if (control->test_break)
542                 return control->test_break(control->data);
543
544         return 0;
545 }
546
547 void RE_rayobject_set_control(RayObject *r, void *data, RE_rayobjectcontrol_test_break_callback test_break)
548 {
549         if (RE_rayobject_isRayAPI(r)) {
550                 r = RE_rayobject_align(r);
551                 r->control.data = data;
552                 r->control.test_break = test_break;
553         }
554 }
555