~ubuntu-branches/ubuntu/trusty/blender/trusty

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha
  • Date: 2013-03-06 12:08:47 UTC
  • mfrom: (1.5.1) (14.1.8 experimental)
  • Revision ID: package-import@ubuntu.com-20130306120847-frjfaryb2zrotwcg
Tags: 2.66a-1ubuntu1
* Resynchronize with Debian (LP: #1076930, #1089256, #1052743, #999024,
  #1122888, #1147084)
* debian/control:
  - Lower build-depends on libavcodec-dev since we're not
    doing the libav9 transition in Ubuntu yet

Show diffs side-by-side

added added

removed removed

Lines of Context:
59
59
        RE_rayobject_instance_free,
60
60
        RE_rayobject_instance_bb,
61
61
        RE_rayobject_instance_cost,
62
 
        RE_rayobject_instance_hint_bb   
 
62
        RE_rayobject_instance_hint_bb
63
63
};
64
64
 
65
 
typedef struct InstanceRayObject
66
 
{
 
65
typedef struct InstanceRayObject {
67
66
        RayObject rayobj;
68
67
        RayObject *target;
69
68
 
76
75
} InstanceRayObject;
77
76
 
78
77
 
79
 
RayObject *RE_rayobject_instance_create(RayObject *target, float transform[][4], void *ob, void *target_ob)
 
78
RayObject *RE_rayobject_instance_create(RayObject *target, float transform[4][4], void *ob, void *target_ob)
80
79
{
81
 
        InstanceRayObject *obj= (InstanceRayObject*)MEM_callocN(sizeof(InstanceRayObject), "InstanceRayObject");
82
 
        assert( RE_rayobject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */       
83
 
        
 
80
        InstanceRayObject *obj = (InstanceRayObject *)MEM_callocN(sizeof(InstanceRayObject), "InstanceRayObject");
 
81
        assert(RE_rayobject_isAligned(obj) );  /* RayObject API assumes real data to be 4-byte aligned */
 
82
 
84
83
        obj->rayobj.api = &instance_api;
85
84
        obj->target = target;
86
85
        obj->ob = ob;
87
86
        obj->target_ob = target_ob;
88
 
        
 
87
 
89
88
        copy_m4_m4(obj->target2global, transform);
90
89
        invert_m4_m4(obj->global2target, obj->target2global);
91
 
        
92
 
        return RE_rayobject_unalignRayAPI((RayObject*) obj);
 
90
 
 
91
        return RE_rayobject_unalignRayAPI((RayObject *) obj);
93
92
}
94
93
 
95
94
static int  RE_rayobject_instance_intersect(RayObject *o, Isect *isec)
96
95
{
97
 
        InstanceRayObject *obj = (InstanceRayObject*)o;
 
96
        InstanceRayObject *obj = (InstanceRayObject *)o;
98
97
        float start[3], dir[3], idot_axis[3], dist;
99
98
        int changed = 0, i, res;
100
 
        
 
99
 
101
100
        // TODO - this is disabling self intersection on instances
102
 
        if (isec->orig.ob == obj->ob && obj->ob)
103
 
        {
 
101
        if (isec->orig.ob == obj->ob && obj->ob) {
104
102
                changed = 1;
105
103
                isec->orig.ob = obj->target_ob;
106
104
        }
107
 
        
 
105
 
108
106
        // backup old values
109
107
        copy_v3_v3(start, isec->start);
110
108
        copy_v3_v3(dir, isec->dir);
115
113
        mul_m4_v3(obj->global2target, isec->start);
116
114
        mul_mat3_m4_v3(obj->global2target, isec->dir);
117
115
        isec->dist *= normalize_v3(isec->dir);
118
 
        
 
116
 
119
117
        // update idot_axis and bv_index
120
 
        for (i=0; i<3; i++)
121
 
        {
122
 
                isec->idot_axis[i]              = 1.0f / isec->dir[i];
123
 
                
124
 
                isec->bv_index[2*i]             = isec->idot_axis[i] < 0.0 ? 1 : 0;
125
 
                isec->bv_index[2*i+1]   = 1 - isec->bv_index[2*i];
126
 
                
127
 
                isec->bv_index[2*i]             = i+3*isec->bv_index[2*i];
128
 
                isec->bv_index[2*i+1]   = i+3*isec->bv_index[2*i+1];
 
118
        for (i = 0; i < 3; i++) {
 
119
                isec->idot_axis[i]        = 1.0f / isec->dir[i];
 
120
 
 
121
                isec->bv_index[2 * i]     = isec->idot_axis[i] < 0.0f ? 1 : 0;
 
122
                isec->bv_index[2 * i + 1] = 1 - isec->bv_index[2 * i];
 
123
 
 
124
                isec->bv_index[2 * i]     = i + 3 * isec->bv_index[2 * i];
 
125
                isec->bv_index[2 * i + 1] = i + 3 * isec->bv_index[2 * i + 1];
129
126
        }
130
127
 
131
128
        // raycast
132
129
        res = RE_rayobject_intersect(obj->target, isec);
133
130
 
134
131
        // map dist into original coordinate space
135
 
        if (res == 0)
136
 
        {
 
132
        if (res == 0) {
137
133
                isec->dist = dist;
138
134
        }
139
 
        else
140
 
        {
 
135
        else {
141
136
                // note we don't just multiply dist, because of possible
142
137
                // non-uniform scaling in the transform matrix
143
138
                float vec[3];
148
143
                isec->dist = len_v3(vec);
149
144
                isec->hit.ob = obj->ob;
150
145
 
151
 
#ifdef RT_USE_LAST_HIT  
 
146
#ifdef RT_USE_LAST_HIT
152
147
                // TODO support for last hit optimization in instances that can jump
153
148
                // directly to the last hit face.
154
149
                // For now it jumps directly to the last-hit instance root node.
155
 
                isec->last_hit = RE_rayobject_unalignRayAPI((RayObject*) obj);
 
150
                isec->last_hit = RE_rayobject_unalignRayAPI((RayObject *) obj);
156
151
#endif
157
152
        }
158
153
 
160
155
        copy_v3_v3(isec->start, start);
161
156
        copy_v3_v3(isec->dir, dir);
162
157
        copy_v3_v3(isec->idot_axis, idot_axis);
163
 
        
 
158
 
164
159
        if (changed)
165
160
                isec->orig.ob = obj->ob;
166
161
 
167
162
        // restore bv_index
168
 
        for (i=0; i<3; i++)
169
 
        {
170
 
                isec->bv_index[2*i]             = isec->idot_axis[i] < 0.0 ? 1 : 0;
171
 
                isec->bv_index[2*i+1]   = 1 - isec->bv_index[2*i];
172
 
                
173
 
                isec->bv_index[2*i]             = i+3*isec->bv_index[2*i];
174
 
                isec->bv_index[2*i+1]   = i+3*isec->bv_index[2*i+1];
 
163
        for (i = 0; i < 3; i++) {
 
164
                isec->bv_index[2 * i]     = isec->idot_axis[i] < 0.0f ? 1 : 0;
 
165
                isec->bv_index[2 * i + 1] = 1 - isec->bv_index[2 * i];
 
166
 
 
167
                isec->bv_index[2 * i]     = i + 3 * isec->bv_index[2 * i];
 
168
                isec->bv_index[2 * i + 1] = i + 3 * isec->bv_index[2 * i + 1];
175
169
        }
176
 
                
 
170
 
177
171
        return res;
178
172
}
179
173
 
180
174
static void RE_rayobject_instance_free(RayObject *o)
181
175
{
182
 
        InstanceRayObject *obj = (InstanceRayObject*)o;
 
176
        InstanceRayObject *obj = (InstanceRayObject *)o;
183
177
        MEM_freeN(obj);
184
178
}
185
179
 
186
180
static float RE_rayobject_instance_cost(RayObject *o)
187
181
{
188
 
        InstanceRayObject *obj = (InstanceRayObject*)o;
 
182
        InstanceRayObject *obj = (InstanceRayObject *)o;
189
183
        return RE_rayobject_cost(obj->target) + RE_COST_INSTANCE;
190
184
}
191
185
 
194
188
        //TODO:
195
189
        // *better bb.. calculated without rotations of bb
196
190
        // *maybe cache that better-fitted-BB at the InstanceRayObject
197
 
        InstanceRayObject *obj = (InstanceRayObject*)o;
 
191
        InstanceRayObject *obj = (InstanceRayObject *)o;
198
192
 
199
193
        float m[3], M[3], t[3];
200
194
        int i, j;
202
196
        RE_rayobject_merge_bb(obj->target, m, M);
203
197
 
204
198
        //There must be a faster way than rotating all the 8 vertexs of the BB
205
 
        for (i=0; i<8; i++)
206
 
        {
207
 
                for (j=0; j<3; j++) t[j] = i&(1<<j) ? M[j] : m[j];
 
199
        for (i = 0; i < 8; i++) {
 
200
                for (j = 0; j < 3; j++) t[j] = i & (1 << j) ? M[j] : m[j];
208
201
                mul_m4_v3(obj->target2global, t);
209
202
                DO_MINMAX(t, min, max);
210
203
        }