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