c3babf99d5159cdbb5a1c8db50cdb77630980f22
[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
47 /* RayFace
48  *
49  * note we force always inline here, because compiler refuses to otherwise
50  * because function is too long. Since this is code that is called billions
51  * of times we really do want to inline. */
52
53 MALWAYS_INLINE RayObject *rayface_from_coords(RayFace *rayface, void *ob, void *face,
54                                               float *v1, float *v2, float *v3, float *v4)
55 {
56         rayface->ob = ob;
57         rayface->face = face;
58
59         copy_v3_v3(rayface->v1, v1);
60         copy_v3_v3(rayface->v2, v2);
61         copy_v3_v3(rayface->v3, v3);
62
63         if (v4) {
64                 copy_v3_v3(rayface->v4, v4);
65                 rayface->quad = 1;
66         }
67         else {
68                 rayface->quad = 0;
69         }
70
71         return RE_rayobject_unalignRayFace(rayface);
72 }
73
74 MALWAYS_INLINE void rayface_from_vlak(RayFace *rayface, ObjectInstanceRen *obi, VlakRen *vlr)
75 {
76         rayface_from_coords(rayface, obi, vlr, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4 ? vlr->v4->co : NULL);
77
78         if (obi->transform_primitives) {
79                 mul_m4_v3(obi->mat, rayface->v1);
80                 mul_m4_v3(obi->mat, rayface->v2);
81                 mul_m4_v3(obi->mat, rayface->v3);
82
83                 if (RE_rayface_isQuad(rayface))
84                         mul_m4_v3(obi->mat, rayface->v4);
85         }
86 }
87
88 RayObject *RE_rayface_from_vlak(RayFace *rayface, ObjectInstanceRen *obi, VlakRen *vlr)
89 {
90         return rayface_from_coords(rayface, obi, vlr, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4 ? vlr->v4->co : 0);
91 }
92
93 /* VlakPrimitive */
94
95 RayObject *RE_vlakprimitive_from_vlak(VlakPrimitive *face, struct ObjectInstanceRen *obi, struct VlakRen *vlr)
96 {
97         face->ob = obi;
98         face->face = vlr;
99
100         return RE_rayobject_unalignVlakPrimitive(face);
101 }
102
103 /* Checks for ignoring faces or materials */
104
105 MALWAYS_INLINE int vlr_check_intersect(Isect *is, ObjectInstanceRen *obi, VlakRen *vlr)
106 {
107         /* for baking selected to active non-traceable materials might still
108          * be in the raytree */
109         if (!(vlr->flag & R_TRACEBLE))
110                 return 0;
111
112         /* I know... cpu cycle waste, might do smarter once */
113         if (is->mode == RE_RAY_MIRROR)
114                 return !(vlr->mat->mode & MA_ONLYCAST);
115         else
116                 return (is->lay & obi->lay);
117 }
118
119 MALWAYS_INLINE int vlr_check_intersect_solid(Isect *UNUSED(is), ObjectInstanceRen *UNUSED(obi), VlakRen *vlr)
120 {
121         /* solid material types only */
122         if (vlr->mat->material_type == MA_TYPE_SURFACE)
123                 return 1;
124         else
125                 return 0;
126 }
127
128 MALWAYS_INLINE int vlr_check_bake(Isect *is, ObjectInstanceRen *obi, VlakRen *UNUSED(vlr))
129 {
130         return (obi->obr->ob != is->userdata) && (obi->obr->ob->flag & SELECT);
131 }
132
133 /* Ray Triangle/Quad Intersection */
134
135 MALWAYS_INLINE int isec_tri_quad(float start[3], float dir[3], RayFace *face, float uv[2], float *lambda)
136 {
137         float co1[3], co2[3], co3[3], co4[3];
138         float t0[3], t1[3], x[3], r[3], m[3], u, v, divdet, det1, l;
139         int quad;
140
141         quad = RE_rayface_isQuad(face);
142
143         copy_v3_v3(co1, face->v1);
144         copy_v3_v3(co2, face->v2);
145         copy_v3_v3(co3, face->v3);
146
147         copy_v3_v3(r, dir);
148
149         /* intersect triangle */
150         sub_v3_v3v3(t0, co3, co2);
151         sub_v3_v3v3(t1, co3, co1);
152
153         cross_v3_v3v3(x, r, t1);
154         divdet = dot_v3v3(t0, x);
155
156         sub_v3_v3v3(m, start, co3);
157         det1 = dot_v3v3(m, x);
158         
159         if (divdet != 0.0f) {
160                 divdet = 1.0f / divdet;
161                 v = det1 * divdet;
162
163                 if (v < RE_RAYTRACE_EPSILON && v > -(1.0f + RE_RAYTRACE_EPSILON)) {
164                         float cros[3];
165
166                         cross_v3_v3v3(cros, m, t0);
167                         u = divdet * dot_v3v3(cros, r);
168
169                         if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f + RE_RAYTRACE_EPSILON)) {
170                                 l = divdet * dot_v3v3(cros, t1);
171
172                                 /* check if intersection is within ray length */
173                                 if (l > -RE_RAYTRACE_EPSILON && l < *lambda) {
174                                         uv[0] = u;
175                                         uv[1] = v;
176                                         *lambda = l;
177                                         return 1;
178                                 }
179                         }
180                 }
181         }
182
183         /* intersect second triangle in quad */
184         if (quad) {
185                 copy_v3_v3(co4, face->v4);
186                 sub_v3_v3v3(t0, co3, co4);
187                 divdet = dot_v3v3(t0, x);
188
189                 if (divdet != 0.0f) {
190                         divdet = 1.0f / divdet;
191                         v = det1 * divdet;
192                         
193                         if (v < RE_RAYTRACE_EPSILON && v > -(1.0f + RE_RAYTRACE_EPSILON)) {
194                                 float cros[3];
195
196                                 cross_v3_v3v3(cros, m, t0);
197                                 u = divdet * dot_v3v3(cros, r);
198         
199                                 if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f + RE_RAYTRACE_EPSILON)) {
200                                         l = divdet * dot_v3v3(cros, t1);
201                                         
202                                         if (l > -RE_RAYTRACE_EPSILON && l < *lambda) {
203                                                 uv[0] = u;
204                                                 uv[1] = -(1.0f + v + u);
205                                                 *lambda = l;
206                                                 return 2;
207                                         }
208                                 }
209                         }
210                 }
211         }
212
213         return 0;
214 }
215
216 /* Simpler yes/no Ray Triangle/Quad Intersection */
217
218 MALWAYS_INLINE int isec_tri_quad_neighbour(float start[3], float dir[3], RayFace *face)
219 {
220         float co1[3], co2[3], co3[3], co4[3];
221         float t0[3], t1[3], x[3], r[3], m[3], u, v, divdet, det1;
222         int quad;
223
224         quad = RE_rayface_isQuad(face);
225
226         copy_v3_v3(co1, face->v1);
227         copy_v3_v3(co2, face->v2);
228         copy_v3_v3(co3, face->v3);
229
230         negate_v3_v3(r, dir); /* note, different than above function */
231
232         /* intersect triangle */
233         sub_v3_v3v3(t0, co3, co2);
234         sub_v3_v3v3(t1, co3, co1);
235
236         cross_v3_v3v3(x, r, t1);
237         divdet = dot_v3v3(t0, x);
238
239         sub_v3_v3v3(m, start, co3);
240         det1 = dot_v3v3(m, x);
241         
242         if (divdet != 0.0f) {
243                 divdet = 1.0f / divdet;
244                 v = det1 * divdet;
245
246                 if (v < RE_RAYTRACE_EPSILON && v > -(1.0f + RE_RAYTRACE_EPSILON)) {
247                         float cros[3];
248
249                         cross_v3_v3v3(cros, m, t0);
250                         u = divdet * dot_v3v3(cros, r);
251
252                         if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f + RE_RAYTRACE_EPSILON))
253                                 return 1;
254                 }
255         }
256
257         /* intersect second triangle in quad */
258         if (quad) {
259                 copy_v3_v3(co4, face->v4);
260                 sub_v3_v3v3(t0, co3, co4);
261                 divdet = dot_v3v3(t0, x);
262
263                 if (divdet != 0.0f) {
264                         divdet = 1.0f / divdet;
265                         v = det1 * divdet;
266                         
267                         if (v < RE_RAYTRACE_EPSILON && v > -(1.0f + RE_RAYTRACE_EPSILON)) {
268                                 float cros[3];
269
270                                 cross_v3_v3v3(cros, m, t0);
271                                 u = divdet * dot_v3v3(cros, r);
272         
273                                 if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f + RE_RAYTRACE_EPSILON))
274                                         return 2;
275                         }
276                 }
277         }
278
279         return 0;
280 }
281
282 /* RayFace intersection with checks and neighbor verifaction included,
283  * Isect is modified if the face is hit. */
284
285 MALWAYS_INLINE int intersect_rayface(RayObject *hit_obj, RayFace *face, Isect *is)
286 {
287         float dist, uv[2];
288         int ok = 0;
289         
290         /* avoid self-intersection */
291         if (is->orig.ob == face->ob && is->orig.face == face->face)
292                 return 0;
293                 
294         /* check if we should intersect this face */
295         if (is->check == RE_CHECK_VLR_RENDER) {
296                 if (vlr_check_intersect(is, (ObjectInstanceRen *)face->ob, (VlakRen *)face->face) == 0)
297                         return 0;
298         }
299         else if (is->check == RE_CHECK_VLR_NON_SOLID_MATERIAL) {
300                 if (vlr_check_intersect(is, (ObjectInstanceRen *)face->ob, (VlakRen *)face->face) == 0)
301                         return 0;
302                 if (vlr_check_intersect_solid(is, (ObjectInstanceRen *)face->ob, (VlakRen *)face->face) == 0)
303                         return 0;
304         }
305         else if (is->check == RE_CHECK_VLR_BAKE) {
306                 if (vlr_check_bake(is, (ObjectInstanceRen *)face->ob, (VlakRen *)face->face) == 0)
307                         return 0;
308         }
309
310         /* ray counter */
311         RE_RC_COUNT(is->raycounter->faces.test);
312
313         dist = is->dist;
314         ok = isec_tri_quad(is->start, is->dir, face, uv, &dist);
315
316         if (ok) {
317         
318                 /* when a shadow ray leaves a face, it can be little outside the edges
319                  * of it, causing intersection to be detected in its neighbor face */
320                 if (is->skip & RE_SKIP_VLR_NEIGHBOUR) {
321                         if (dist < 0.1f && is->orig.ob == face->ob) {
322                                 VlakRen *a = (VlakRen *)is->orig.face;
323                                 VlakRen *b = (VlakRen *)face->face;
324
325                                 /* so there's a shared edge or vertex, let's intersect ray with
326                                  * face itself, if that's true we can safely return 1, otherwise
327                                  * we assume the intersection is invalid, 0 */
328                                 if (a->v1 == b->v1 || a->v2 == b->v1 || a->v3 == b->v1 || a->v4 == b->v1 ||
329                                     a->v1 == b->v2 || a->v2 == b->v2 || a->v3 == b->v2 || a->v4 == b->v2 ||
330                                     a->v1 == b->v3 || a->v2 == b->v3 || a->v3 == b->v3 || a->v4 == b->v3 ||
331                                     (b->v4 && (a->v1 == b->v4 || a->v2 == b->v4 || a->v3 == b->v4 || a->v4 == b->v4)))
332                                 {
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         RE_RC_COUNT(isec->raycounter->raycast.test);
369
370         /* setup vars used on raycast */
371         for (i = 0; i < 3; i++) {
372                 isec->idot_axis[i]          = 1.0f / isec->dir[i];
373                 
374                 isec->bv_index[2 * i]       = isec->idot_axis[i] < 0.0f ? 1 : 0;
375                 isec->bv_index[2 * i + 1]   = 1 - isec->bv_index[2 * i];
376                 
377                 isec->bv_index[2 * i]       = i + 3 * isec->bv_index[2 * i];
378                 isec->bv_index[2 * i + 1]   = i + 3 * isec->bv_index[2 * i + 1];
379         }
380
381 #ifdef RT_USE_LAST_HIT  
382         /* last hit heuristic */
383         if (isec->mode == RE_RAY_SHADOW && isec->last_hit) {
384                 RE_RC_COUNT(isec->raycounter->rayshadow_last_hit.test);
385                 
386                 if (RE_rayobject_intersect(isec->last_hit, isec)) {
387                         RE_RC_COUNT(isec->raycounter->raycast.hit);
388                         RE_RC_COUNT(isec->raycounter->rayshadow_last_hit.hit);
389                         return 1;
390                 }
391         }
392 #endif
393
394 #ifdef RT_USE_HINT
395         isec->hit_hint = 0;
396 #endif
397
398         if (RE_rayobject_intersect(r, isec)) {
399                 RE_RC_COUNT(isec->raycounter->raycast.hit);
400
401 #ifdef RT_USE_HINT
402                 isec->hint = isec->hit_hint;
403 #endif
404                 return 1;
405         }
406
407         return 0;
408 }
409
410 int RE_rayobject_intersect(RayObject *r, Isect *i)
411 {
412         if (RE_rayobject_isRayFace(r)) {
413                 return intersect_rayface(r, (RayFace *) RE_rayobject_align(r), i);
414         }
415         else if (RE_rayobject_isVlakPrimitive(r)) {
416                 //TODO optimize (useless copy to RayFace to avoid duplicate code)
417                 VlakPrimitive *face = (VlakPrimitive *) RE_rayobject_align(r);
418                 RayFace nface;
419                 rayface_from_vlak(&nface, face->ob, face->face);
420
421                 return intersect_rayface(r, &nface, i);
422         }
423         else if (RE_rayobject_isRayAPI(r)) {
424                 r = RE_rayobject_align(r);
425                 return r->api->raycast(r, i);
426         }
427         else {
428                 assert(0);
429                 return 0;
430         }
431 }
432
433 /* Building */
434
435 void RE_rayobject_add(RayObject *r, RayObject *o)
436 {
437         r = RE_rayobject_align(r);
438         return r->api->add(r, o);
439 }
440
441 void RE_rayobject_done(RayObject *r)
442 {
443         r = RE_rayobject_align(r);
444         r->api->done(r);
445 }
446
447 void RE_rayobject_free(RayObject *r)
448 {
449         r = RE_rayobject_align(r);
450         r->api->free(r);
451 }
452
453 float RE_rayobject_cost(RayObject *r)
454 {
455         if (RE_rayobject_isRayFace(r) || RE_rayobject_isVlakPrimitive(r)) {
456                 return 1.0f;
457         }
458         else if (RE_rayobject_isRayAPI(r)) {
459                 r = RE_rayobject_align(r);
460                 return r->api->cost(r);
461         }
462         else {
463                 assert(0);
464                 return 1.0f;
465         }
466 }
467
468 /* Bounding Boxes */
469
470 void RE_rayobject_merge_bb(RayObject *r, float min[3], float max[3])
471 {
472         if (RE_rayobject_isRayFace(r)) {
473                 RayFace *face = (RayFace *) RE_rayobject_align(r);
474                 
475                 DO_MINMAX(face->v1, min, max);
476                 DO_MINMAX(face->v2, min, max);
477                 DO_MINMAX(face->v3, min, max);
478                 if (RE_rayface_isQuad(face)) DO_MINMAX(face->v4, min, max);
479         }
480         else if (RE_rayobject_isVlakPrimitive(r)) {
481                 VlakPrimitive *face = (VlakPrimitive *) RE_rayobject_align(r);
482                 RayFace nface;
483                 rayface_from_vlak(&nface, face->ob, face->face);
484
485                 DO_MINMAX(nface.v1, min, max);
486                 DO_MINMAX(nface.v2, min, max);
487                 DO_MINMAX(nface.v3, min, max);
488                 if (RE_rayface_isQuad(&nface)) DO_MINMAX(nface.v4, min, max);
489         }
490         else if (RE_rayobject_isRayAPI(r)) {
491                 r = RE_rayobject_align(r);
492                 r->api->bb(r, min, max);
493         }
494         else
495                 assert(0);
496 }
497
498 /* Hints */
499
500 void RE_rayobject_hint_bb(RayObject *r, RayHint *hint, float *min, float *max)
501 {
502         if (RE_rayobject_isRayFace(r) || RE_rayobject_isVlakPrimitive(r)) {
503                 return;
504         }
505         else if (RE_rayobject_isRayAPI(r)) {
506                 r = RE_rayobject_align(r);
507                 return r->api->hint_bb(r, hint, min, max);
508         }
509         else
510                 assert(0);
511 }
512
513 /* RayObjectControl */
514
515 int RE_rayobjectcontrol_test_break(RayObjectControl *control)
516 {
517         if (control->test_break)
518                 return control->test_break(control->data);
519
520         return 0;
521 }
522
523 void RE_rayobject_set_control(RayObject *r, void *data, RE_rayobjectcontrol_test_break_callback test_break)
524 {
525         if (RE_rayobject_isRayAPI(r)) {
526                 r = RE_rayobject_align(r);
527                 r->control.data = data;
528                 r->control.test_break = test_break;
529         }
530 }
531