~siretart/ubuntu/utopic/blender/libav10

« back to all changes in this revision

Viewing changes to source/blender/render/intern/raytrace/rayobject.cpp

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2012-07-23 08:54:18 UTC
  • mfrom: (14.2.16 sid)
  • mto: (14.2.19 sid)
  • mto: This revision was merged to the branch mainline in revision 42.
  • Revision ID: package-import@ubuntu.com-20120723085418-9foz30v6afaf5ffs
Tags: 2.63a-2
* debian/: Cycles support added (Closes: #658075)
  For now, this top feature has been enabled only
  on [any-amd64 any-i386] architectures because
  of OpenImageIO failing on all others
* debian/: scripts installation path changed
  from /usr/lib to /usr/share:
  + debian/patches/: patchset re-worked for path changing
  + debian/control: "Breaks" field added on yafaray-exporter

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
 * $Id: rayobject.cpp 28202 2010-04-15 10:28:32Z blendix $
3
 
 *
 
1
/*
4
2
 * ***** BEGIN GPL LICENSE BLOCK *****
5
3
 *
6
4
 * This program is free software; you can redistribute it and/or
26
24
 *
27
25
 * ***** END GPL LICENSE BLOCK *****
28
26
 */
 
27
 
 
28
/** \file blender/render/intern/raytrace/rayobject.cpp
 
29
 *  \ingroup render
 
30
 */
 
31
 
 
32
 
29
33
#include <assert.h>
30
34
 
31
 
#include "BKE_utildefines.h"
 
35
#include "MEM_guardedalloc.h"
 
36
 
32
37
#include "BLI_math.h"
 
38
#include "BLI_utildefines.h"
 
39
 
33
40
#include "DNA_material_types.h"
34
41
 
35
 
#include "RE_raytrace.h"
36
 
#include "render_types.h"
 
42
#include "rayintersection.h"
37
43
#include "rayobject.h"
38
44
#include "raycounter.h"
39
 
 
40
 
/*
41
 
 * Determines the distance that the ray must travel to hit the bounding volume of the given node
42
 
 * Based on Tactical Optimization of Ray/Box Intersection, by Graham Fyffe
43
 
 *  [http://tog.acm.org/resources/RTNews/html/rtnv21n1.html#art9]
44
 
 */
45
 
int RE_rayobject_bb_intersect_test(const Isect *isec, const float *_bb)
46
 
{
47
 
        const float *bb = _bb;
48
 
        
49
 
        float t1x = (bb[isec->bv_index[0]] - isec->start[0]) * isec->idot_axis[0];
50
 
        float t2x = (bb[isec->bv_index[1]] - isec->start[0]) * isec->idot_axis[0];
51
 
        float t1y = (bb[isec->bv_index[2]] - isec->start[1]) * isec->idot_axis[1];
52
 
        float t2y = (bb[isec->bv_index[3]] - isec->start[1]) * isec->idot_axis[1];
53
 
        float t1z = (bb[isec->bv_index[4]] - isec->start[2]) * isec->idot_axis[2];
54
 
        float t2z = (bb[isec->bv_index[5]] - isec->start[2]) * isec->idot_axis[2];
55
 
 
56
 
        RE_RC_COUNT(isec->raycounter->bb.test);
57
 
        
58
 
        if(t1x > t2y || t2x < t1y || t1x > t2z || t2x < t1z || t1y > t2z || t2y < t1z) return 0;
59
 
        if(t2x < 0.0 || t2y < 0.0 || t2z < 0.0) return 0;
60
 
        if(t1x > isec->labda || t1y > isec->labda || t1z > isec->labda) return 0;
61
 
        RE_RC_COUNT(isec->raycounter->bb.hit);  
62
 
 
63
 
        return 1;
64
 
}
65
 
 
66
 
 
67
 
/* only for self-intersecting test with current render face (where ray left) */
68
 
static int intersection2(VlakRen *face, float r0, float r1, float r2, float rx1, float ry1, float rz1)
69
 
{
70
 
        float co1[3], co2[3], co3[3], co4[3];
71
 
        float x0,x1,x2,t00,t01,t02,t10,t11,t12,t20,t21,t22;
72
 
        float m0, m1, m2, divdet, det, det1;
73
 
        float u1, v, u2;
74
 
 
75
 
        VECCOPY(co1, face->v1->co);
76
 
        VECCOPY(co2, face->v2->co);
77
 
        if(face->v4)
 
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)
78
64
        {
79
 
                VECCOPY(co3, face->v4->co);
80
 
                VECCOPY(co4, face->v3->co);
 
65
                copy_v3_v3(rayface->v4, v4);
 
66
                rayface->quad = 1;
81
67
        }
82
68
        else
83
69
        {
84
 
                VECCOPY(co3, face->v3->co);
85
 
        }
86
 
 
87
 
        t00= co3[0]-co1[0];
88
 
        t01= co3[1]-co1[1];
89
 
        t02= co3[2]-co1[2];
90
 
        t10= co3[0]-co2[0];
91
 
        t11= co3[1]-co2[1];
92
 
        t12= co3[2]-co2[2];
93
 
        
94
 
        x0= t11*r2-t12*r1;
95
 
        x1= t12*r0-t10*r2;
96
 
        x2= t10*r1-t11*r0;
97
 
 
98
 
        divdet= t00*x0+t01*x1+t02*x2;
99
 
 
100
 
        m0= rx1-co3[0];
101
 
        m1= ry1-co3[1];
102
 
        m2= rz1-co3[2];
103
 
        det1= m0*x0+m1*x1+m2*x2;
104
 
        
105
 
        if(divdet!=0.0f) {
106
 
                u1= det1/divdet;
107
 
 
108
 
                if(u1<ISECT_EPSILON) {
109
 
                        det= t00*(m1*r2-m2*r1);
110
 
                        det+= t01*(m2*r0-m0*r2);
111
 
                        det+= t02*(m0*r1-m1*r0);
112
 
                        v= det/divdet;
113
 
 
114
 
                        if(v<ISECT_EPSILON && (u1 + v) > -(1.0f+ISECT_EPSILON)) {
115
 
                                return 1;
116
 
                        }
117
 
                }
118
 
        }
119
 
 
120
 
        if(face->v4) {
121
 
 
122
 
                t20= co3[0]-co4[0];
123
 
                t21= co3[1]-co4[1];
124
 
                t22= co3[2]-co4[2];
125
 
 
126
 
                divdet= t20*x0+t21*x1+t22*x2;
127
 
                if(divdet!=0.0f) {
128
 
                        u2= det1/divdet;
129
 
                
130
 
                        if(u2<ISECT_EPSILON) {
131
 
                                det= t20*(m1*r2-m2*r1);
132
 
                                det+= t21*(m2*r0-m0*r2);
133
 
                                det+= t22*(m0*r1-m1*r0);
134
 
                                v= det/divdet;
135
 
        
136
 
                                if(v<ISECT_EPSILON && (u2 + v) >= -(1.0f+ISECT_EPSILON)) {
137
 
                                        return 2;
138
 
                                }
139
 
                        }
140
 
                }
141
 
        }
142
 
        return 0;
143
 
}
144
 
 
145
 
static inline int vlr_check_intersect(Isect *is, ObjectInstanceRen *obi, VlakRen *vlr)
 
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 : NULL);
 
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)
146
109
{
147
110
        /* for baking selected to active non-traceable materials might still
148
111
         * be in the raytree */
149
 
        if(!(vlr->mat->mode & MA_TRACEBLE))
 
112
        if (!(vlr->flag & R_TRACEBLE))
150
113
                return 0;
151
114
 
152
115
        /* I know... cpu cycle waste, might do smarter once */
153
 
        if(is->mode==RE_RAY_MIRROR)
 
116
        if (is->mode==RE_RAY_MIRROR)
154
117
                return !(vlr->mat->mode & MA_ONLYCAST);
155
118
        else
156
119
                return (is->lay & obi->lay);
157
120
}
158
121
 
159
 
static inline int vlr_check_intersect_solid(Isect *is, ObjectInstanceRen* obi, VlakRen *vlr)
 
122
MALWAYS_INLINE int vlr_check_intersect_solid(Isect *UNUSED(is), ObjectInstanceRen* UNUSED(obi), VlakRen *vlr)
160
123
{
161
124
        /* solid material types only */
162
125
        if (vlr->mat->material_type == MA_TYPE_SURFACE)
165
128
                return 0;
166
129
}
167
130
 
168
 
static inline int vlr_check_bake(Isect *is, ObjectInstanceRen* obi, VlakRen *vlr)
169
 
{
170
 
        return (obi->obr->ob != is->userdata);
171
 
}
172
 
 
173
 
static inline int rayface_check_cullface(RayFace *face, Isect *is)
174
 
{
175
 
        float nor[3];
176
 
        
177
 
        /* don't intersect if the ray faces along the face normal */
178
 
        if(face->quad) normal_quad_v3( nor,face->v1, face->v2, face->v3, face->v4);
179
 
        else normal_tri_v3( nor,face->v1, face->v2, face->v3);
180
 
 
181
 
        return (INPR(nor, is->vec) < 0);
182
 
}
183
 
 
184
 
/* ray - triangle or quad intersection */
185
 
/* this function shall only modify Isect if it detects an hit */
186
 
static int intersect_rayface(RayObject *hit_obj, RayFace *face, Isect *is)
187
 
{
188
 
        float co1[3],co2[3],co3[3],co4[3]={0};
189
 
        float x0,x1,x2,t00,t01,t02,t10,t11,t12,t20,t21,t22,r0,r1,r2;
190
 
        float m0, m1, m2, divdet, det1;
191
 
        float labda, u, v;
192
 
        short ok=0;
193
 
        
194
 
        if(is->orig.ob == face->ob && is->orig.face == face->face)
 
131
MALWAYS_INLINE int vlr_check_bake(Isect *is, ObjectInstanceRen* obi, VlakRen *UNUSED(vlr))
 
132
{
 
133
        return (obi->obr->ob != is->userdata) && (obi->obr->ob->flag & SELECT);
 
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)
195
295
                return 0;
196
296
                
197
297
        /* check if we should intersect this face */
198
 
        if(is->skip & RE_SKIP_VLR_RENDER_CHECK)
199
 
        {
200
 
                if(vlr_check_intersect(is, (ObjectInstanceRen*)face->ob, (VlakRen*)face->face ) == 0)
201
 
                        return 0;
202
 
        }
203
 
        else if(is->skip & RE_SKIP_VLR_NON_SOLID_MATERIAL)
204
 
        {
205
 
                if(vlr_check_intersect(is, (ObjectInstanceRen*)face->ob, (VlakRen*)face->face ) == 0)
206
 
                        return 0;
207
 
                if(vlr_check_intersect_solid(is, (ObjectInstanceRen*)face->ob, (VlakRen*)face->face) == 0)
208
 
                        return 0;
209
 
        }
210
 
        else if(is->skip & RE_SKIP_VLR_BAKE_CHECK) {
211
 
                if(vlr_check_bake(is, (ObjectInstanceRen*)face->ob, (VlakRen*)face->face ) == 0)
212
 
                        return 0;
213
 
        }
214
 
 
215
 
        if(is->skip & RE_SKIP_CULLFACE)
216
 
        {
217
 
                if(rayface_check_cullface(face, is) == 0)
218
 
                        return 0;
219
 
        }
220
 
 
 
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 */
221
316
        RE_RC_COUNT(is->raycounter->faces.test);
222
317
 
223
 
        //Load coords
224
 
        VECCOPY(co1, face->v1);
225
 
        VECCOPY(co2, face->v2);
226
 
        if(RE_rayface_isQuad(face))
227
 
        {
228
 
                VECCOPY(co3, face->v4);
229
 
                VECCOPY(co4, face->v3);
230
 
        }
231
 
        else
232
 
        {
233
 
                VECCOPY(co3, face->v3);
234
 
        }
235
 
 
236
 
        t00= co3[0]-co1[0];
237
 
        t01= co3[1]-co1[1];
238
 
        t02= co3[2]-co1[2];
239
 
        t10= co3[0]-co2[0];
240
 
        t11= co3[1]-co2[1];
241
 
        t12= co3[2]-co2[2];
242
 
        
243
 
        r0= is->vec[0];
244
 
        r1= is->vec[1];
245
 
        r2= is->vec[2];
246
 
        
247
 
        x0= t12*r1-t11*r2;
248
 
        x1= t10*r2-t12*r0;
249
 
        x2= t11*r0-t10*r1;
250
 
 
251
 
        divdet= t00*x0+t01*x1+t02*x2;
252
 
 
253
 
        m0= is->start[0]-co3[0];
254
 
        m1= is->start[1]-co3[1];
255
 
        m2= is->start[2]-co3[2];
256
 
        det1= m0*x0+m1*x1+m2*x2;
257
 
        
258
 
        if(divdet!=0.0f) {
259
 
 
260
 
                divdet= 1.0f/divdet;
261
 
                u= det1*divdet;
262
 
                if(u<ISECT_EPSILON && u>-(1.0f+ISECT_EPSILON)) {
263
 
                        float cros0, cros1, cros2;
264
 
                        
265
 
                        cros0= m1*t02-m2*t01;
266
 
                        cros1= m2*t00-m0*t02;
267
 
                        cros2= m0*t01-m1*t00;
268
 
                        v= divdet*(cros0*r0 + cros1*r1 + cros2*r2);
269
 
 
270
 
                        if(v<ISECT_EPSILON && (u + v) > -(1.0f+ISECT_EPSILON)) {
271
 
                                labda= divdet*(cros0*t10 + cros1*t11 + cros2*t12);
272
 
 
273
 
                                if(labda>-ISECT_EPSILON && labda<is->labda) {
274
 
                                        ok= 1;
275
 
                                }
276
 
                        }
277
 
                }
278
 
        }
279
 
 
280
 
        if(ok==0 && RE_rayface_isQuad(face)) {
281
 
 
282
 
                t20= co3[0]-co4[0];
283
 
                t21= co3[1]-co4[1];
284
 
                t22= co3[2]-co4[2];
285
 
 
286
 
                divdet= t20*x0+t21*x1+t22*x2;
287
 
                if(divdet!=0.0f) {
288
 
                        divdet= 1.0f/divdet;
289
 
                        u = det1*divdet;
290
 
                        
291
 
                        if(u<ISECT_EPSILON && u>-(1.0f+ISECT_EPSILON)) {
292
 
                                float cros0, cros1, cros2;
293
 
                                cros0= m1*t22-m2*t21;
294
 
                                cros1= m2*t20-m0*t22;
295
 
                                cros2= m0*t21-m1*t20;
296
 
                                v= divdet*(cros0*r0 + cros1*r1 + cros2*r2);
297
 
        
298
 
                                if(v<ISECT_EPSILON && (u + v) >-(1.0f+ISECT_EPSILON)) {
299
 
                                        labda= divdet*(cros0*t10 + cros1*t11 + cros2*t12);
300
 
                                        
301
 
                                        if(labda>-ISECT_EPSILON && labda<is->labda) {
302
 
                                                ok= 2;
303
 
                                        }
304
 
                                }
305
 
                        }
306
 
                }
307
 
        }
308
 
 
309
 
        if(ok) {
310
 
        
311
 
                /* when a shadow ray leaves a face, it can be little outside the edges of it, causing
312
 
                intersection to be detected in its neighbour face */
313
 
                if(is->skip & RE_SKIP_VLR_NEIGHBOUR)
 
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)
314
326
                {
315
 
                        if(labda < 0.1f && is->orig.ob == face->ob)
 
327
                        if (dist < 0.1f && is->orig.ob == face->ob)
316
328
                        {
317
329
                                VlakRen * a = (VlakRen*)is->orig.face;
318
330
                                VlakRen * b = (VlakRen*)face->face;
319
331
 
320
 
                                /* so there's a shared edge or vertex, let's intersect ray with face
321
 
                                itself, if that's true we can safely return 1, otherwise we assume
322
 
                                the intersection is invalid, 0 */
323
 
                                if(a->v1==b->v1 || a->v2==b->v1 || a->v3==b->v1 || a->v4==b->v1
 
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
324
336
                                || a->v1==b->v2 || a->v2==b->v2 || a->v3==b->v2 || a->v4==b->v2
325
337
                                || a->v1==b->v3 || a->v2==b->v3 || a->v3==b->v3 || a->v4==b->v3
326
 
                                || (b->v4 && (a->v1==b->v4 || a->v2==b->v4 || a->v3==b->v4 || a->v4==b->v4)))
327
 
                                if(!intersection2((VlakRen*)a, -r0, -r1, -r2, is->start[0], is->start[1], is->start[2]))
328
 
                                {
329
 
                                        return 0;
 
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
                                        }
330
348
                                }
331
349
                        }
332
350
                }
334
352
                RE_RC_COUNT(is->raycounter->faces.hit);
335
353
 
336
354
                is->isect= ok;  // which half of the quad
337
 
                is->labda= labda;
338
 
                is->u= u; is->v= v;
 
355
                is->dist= dist;
 
356
                is->u= uv[0]; is->v= uv[1];
339
357
 
340
358
                is->hit.ob   = face->ob;
341
359
                is->hit.face = face->face;
348
366
        return 0;
349
367
}
350
368
 
351
 
RayObject* RE_rayface_from_vlak(RayFace *rayface, ObjectInstanceRen *obi, VlakRen *vlr)
352
 
{
353
 
        return RE_rayface_from_coords(rayface, obi, vlr, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4 ? vlr->v4->co : 0 );
354
 
}
355
 
 
356
 
RayObject* RE_rayface_from_coords(RayFace *rayface, void *ob, void *face, float *v1, float *v2, float *v3, float *v4)
357
 
{
358
 
        rayface->ob = ob;
359
 
        rayface->face = face;
360
 
 
361
 
        VECCOPY(rayface->v1, v1);
362
 
        VECCOPY(rayface->v2, v2);
363
 
        VECCOPY(rayface->v3, v3);
364
 
        if(v4)
365
 
        {
366
 
                VECCOPY(rayface->v4, v4);
367
 
                rayface->quad = 1;
368
 
        }
369
 
        else
370
 
        {
371
 
                rayface->quad = 0;
372
 
        }
373
 
 
374
 
        return RE_rayobject_unalignRayFace(rayface);
375
 
}
376
 
 
377
 
RayObject* RE_vlakprimitive_from_vlak(VlakPrimitive *face, struct ObjectInstanceRen *obi, struct VlakRen *vlr)
378
 
{
379
 
        face->ob = obi;
380
 
        face->face = vlr;
381
 
        return RE_rayobject_unalignVlakPrimitive(face);
382
 
}
383
 
 
 
369
/* Intersection */
384
370
 
385
371
int RE_rayobject_raycast(RayObject *r, Isect *isec)
386
372
{
387
373
        int i;
 
374
 
388
375
        RE_RC_COUNT(isec->raycounter->raycast.test);
389
376
 
390
 
        /* Setup vars used on raycast */
391
 
        isec->dist = len_v3(isec->vec);
392
 
        
393
 
        for(i=0; i<3; i++)
 
377
        /* setup vars used on raycast */
 
378
        for (i=0; i<3; i++)
394
379
        {
395
 
                isec->idot_axis[i]              = 1.0f / isec->vec[i];
 
380
                isec->idot_axis[i]              = 1.0f / isec->dir[i];
396
381
                
397
382
                isec->bv_index[2*i]             = isec->idot_axis[i] < 0.0 ? 1 : 0;
398
383
                isec->bv_index[2*i+1]   = 1 - isec->bv_index[2*i];
402
387
        }
403
388
 
404
389
#ifdef RT_USE_LAST_HIT  
405
 
        /* Last hit heuristic */
406
 
        if(isec->mode==RE_RAY_SHADOW && isec->last_hit)
 
390
        /* last hit heuristic */
 
391
        if (isec->mode==RE_RAY_SHADOW && isec->last_hit)
407
392
        {
408
393
                RE_RC_COUNT(isec->raycounter->rayshadow_last_hit.test);
409
394
                
410
 
                if(RE_rayobject_intersect(isec->last_hit, isec))
 
395
                if (RE_rayobject_intersect(isec->last_hit, isec))
411
396
                {
412
397
                        RE_RC_COUNT(isec->raycounter->raycast.hit);
413
398
                        RE_RC_COUNT(isec->raycounter->rayshadow_last_hit.hit);
420
405
        isec->hit_hint = 0;
421
406
#endif
422
407
 
423
 
        if(RE_rayobject_intersect(r, isec))
 
408
        if (RE_rayobject_intersect(r, isec))
424
409
        {
425
410
                RE_RC_COUNT(isec->raycounter->raycast.hit);
426
411
 
429
414
#endif
430
415
                return 1;
431
416
        }
 
417
 
432
418
        return 0;
433
419
}
434
420
 
435
421
int RE_rayobject_intersect(RayObject *r, Isect *i)
436
422
{
437
 
        if(RE_rayobject_isRayFace(r))
 
423
        if (RE_rayobject_isRayFace(r))
438
424
        {
439
425
                return intersect_rayface(r, (RayFace*) RE_rayobject_align(r), i);
440
426
        }
441
 
        else if(RE_rayobject_isVlakPrimitive(r))
 
427
        else if (RE_rayobject_isVlakPrimitive(r))
442
428
        {
443
429
                //TODO optimize (useless copy to RayFace to avoid duplicate code)
444
430
                VlakPrimitive *face = (VlakPrimitive*) RE_rayobject_align(r);
445
431
                RayFace nface;
446
 
                RE_rayface_from_vlak(&nface, face->ob, face->face);
447
 
 
448
 
                if(face->ob->transform_primitives)
449
 
                {
450
 
                        mul_m4_v3(face->ob->mat, nface.v1);
451
 
                        mul_m4_v3(face->ob->mat, nface.v2);
452
 
                        mul_m4_v3(face->ob->mat, nface.v3);
453
 
                        if(RE_rayface_isQuad(&nface))
454
 
                                mul_m4_v3(face->ob->mat, nface.v4);
455
 
                }
 
432
                rayface_from_vlak(&nface, face->ob, face->face);
456
433
 
457
434
                return intersect_rayface(r, &nface, i);
458
435
        }
459
 
        else if(RE_rayobject_isRayAPI(r))
 
436
        else if (RE_rayobject_isRayAPI(r))
460
437
        {
461
 
                r = RE_rayobject_align( r );
462
 
                return r->api->raycast( r, i );
463
 
        }
464
 
        else assert(0);
465
 
    return 0; /* wont reach this, quiet compilers */
 
438
                r = RE_rayobject_align(r);
 
439
                return r->api->raycast(r, i);
 
440
        }
 
441
        else {
 
442
                assert(0);
 
443
                return 0;
 
444
        }
466
445
}
467
446
 
 
447
/* Building */
 
448
 
468
449
void RE_rayobject_add(RayObject *r, RayObject *o)
469
450
{
470
 
        r = RE_rayobject_align( r );
471
 
        return r->api->add( r, o );
 
451
        r = RE_rayobject_align(r);
 
452
        return r->api->add(r, o);
472
453
}
473
454
 
474
455
void RE_rayobject_done(RayObject *r)
475
456
{
476
 
        r = RE_rayobject_align( r );
477
 
        r->api->done( r );
 
457
        r = RE_rayobject_align(r);
 
458
        r->api->done(r);
478
459
}
479
460
 
480
461
void RE_rayobject_free(RayObject *r)
481
462
{
482
 
        r = RE_rayobject_align( r );
483
 
        r->api->free( r );
484
 
}
 
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
485
 
486
486
void RE_rayobject_merge_bb(RayObject *r, float *min, float *max)
487
487
{
488
 
        if(RE_rayobject_isRayFace(r))
 
488
        if (RE_rayobject_isRayFace(r))
489
489
        {
490
490
                RayFace *face = (RayFace*) RE_rayobject_align(r);
491
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 );
 
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
496
        }
497
 
        else if(RE_rayobject_isVlakPrimitive(r))
 
497
        else if (RE_rayobject_isVlakPrimitive(r))
498
498
        {
499
499
                VlakPrimitive *face = (VlakPrimitive*) RE_rayobject_align(r);
500
500
                RayFace nface;
501
 
                RE_rayface_from_vlak(&nface, face->ob, face->face);
502
 
 
503
 
                if(face->ob->transform_primitives)
504
 
                {
505
 
                        mul_m4_v3(face->ob->mat, nface.v1);
506
 
                        mul_m4_v3(face->ob->mat, nface.v2);
507
 
                        mul_m4_v3(face->ob->mat, nface.v3);
508
 
                        if(RE_rayface_isQuad(&nface))
509
 
                                mul_m4_v3(face->ob->mat, nface.v4);
510
 
                }
511
 
 
512
 
                DO_MINMAX( nface.v1, min, max );
513
 
                DO_MINMAX( nface.v2, min, max );
514
 
                DO_MINMAX( nface.v3, min, max );
515
 
                if(RE_rayface_isQuad(&nface)) DO_MINMAX( nface.v4, min, max );
516
 
        }
517
 
        else if(RE_rayobject_isRayAPI(r))
518
 
        {
519
 
                r = RE_rayobject_align( r );
520
 
                r->api->bb( r, min, max );
521
 
        }
522
 
        else assert(0);
523
 
}
524
 
 
525
 
float RE_rayobject_cost(RayObject *r)
526
 
{
527
 
        if(RE_rayobject_isRayFace(r) || RE_rayobject_isVlakPrimitive(r))
528
 
        {
529
 
                return 1.0;
530
 
        }
531
 
        else if(RE_rayobject_isRayAPI(r))
532
 
        {
533
 
                r = RE_rayobject_align( r );
534
 
                return r->api->cost( r );
535
 
        }
536
 
        else assert(0);
537
 
}
 
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 */
538
518
 
539
519
void RE_rayobject_hint_bb(RayObject *r, RayHint *hint, float *min, float *max)
540
520
{
541
 
        if(RE_rayobject_isRayFace(r) || RE_rayobject_isVlakPrimitive(r))
 
521
        if (RE_rayobject_isRayFace(r) || RE_rayobject_isVlakPrimitive(r))
542
522
        {
543
523
                return;
544
524
        }
545
 
        else if(RE_rayobject_isRayAPI(r))
 
525
        else if (RE_rayobject_isRayAPI(r))
546
526
        {
547
 
                r = RE_rayobject_align( r );
548
 
                return r->api->hint_bb( r, hint, min, max );
 
527
                r = RE_rayobject_align(r);
 
528
                return r->api->hint_bb(r, hint, min, max);
549
529
        }
550
 
        else assert(0);
 
530
        else
 
531
                assert(0);
551
532
}
552
533
 
 
534
/* RayObjectControl */
 
535
 
553
536
int RE_rayobjectcontrol_test_break(RayObjectControl *control)
554
537
{
555
 
        if(control->test_break)
556
 
                return control->test_break( control->data );
557
 
 
558
 
        return 0;
559
 
}
560
 
 
561
 
 
562
 
/*
563
 
 * Empty raytree
564
 
 */
565
 
static int RE_rayobject_empty_intersect(RayObject *o, Isect *is)
566
 
{
567
 
        return 0;
568
 
}
569
 
 
570
 
static void RE_rayobject_empty_free(RayObject *o)
571
 
{
572
 
}
573
 
 
574
 
static void RE_rayobject_empty_bb(RayObject *o, float *min, float *max)
575
 
{
576
 
        return;
577
 
}
578
 
 
579
 
static float RE_rayobject_empty_cost(RayObject *o)
580
 
{
581
 
        return 0.0;
582
 
}
583
 
 
584
 
static void RE_rayobject_empty_hint_bb(RayObject *o, RayHint *hint, float *min, float *max)
585
 
{}
586
 
 
587
 
static RayObjectAPI empty_api =
588
 
{
589
 
        RE_rayobject_empty_intersect,
590
 
        NULL, //static void RE_rayobject_instance_add(RayObject *o, RayObject *ob);
591
 
        NULL, //static void RE_rayobject_instance_done(RayObject *o);
592
 
        RE_rayobject_empty_free,
593
 
        RE_rayobject_empty_bb,
594
 
        RE_rayobject_empty_cost,
595
 
        RE_rayobject_empty_hint_bb
596
 
};
597
 
 
598
 
static RayObject empty_raytree = { &empty_api, {0, 0} };
599
 
 
600
 
RayObject *RE_rayobject_empty_create()
601
 
{
602
 
        return RE_rayobject_unalignRayAPI( &empty_raytree );
603
 
}
 
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