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
65
typedef struct InstanceRayObject
65
typedef struct InstanceRayObject {
76
75
} InstanceRayObject;
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)
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 */
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 */
84
83
obj->rayobj.api = &instance_api;
85
84
obj->target = target;
87
86
obj->target_ob = target_ob;
89
88
copy_m4_m4(obj->target2global, transform);
90
89
invert_m4_m4(obj->global2target, obj->target2global);
92
return RE_rayobject_unalignRayAPI((RayObject*) obj);
91
return RE_rayobject_unalignRayAPI((RayObject *) obj);
95
94
static int RE_rayobject_instance_intersect(RayObject *o, Isect *isec)
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;
101
100
// TODO - this is disabling self intersection on instances
102
if (isec->orig.ob == obj->ob && obj->ob)
101
if (isec->orig.ob == obj->ob && obj->ob) {
105
103
isec->orig.ob = obj->target_ob;
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);
119
117
// update idot_axis and bv_index
122
isec->idot_axis[i] = 1.0f / isec->dir[i];
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];
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];
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];
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];
132
129
res = RE_rayobject_intersect(obj->target, isec);
134
131
// map dist into original coordinate space
137
133
isec->dist = dist;
141
136
// note we don't just multiply dist, because of possible
142
137
// non-uniform scaling in the transform matrix
148
143
isec->dist = len_v3(vec);
149
144
isec->hit.ob = obj->ob;
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);
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);
165
160
isec->orig.ob = obj->ob;
167
162
// restore bv_index
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];
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];
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];
180
174
static void RE_rayobject_instance_free(RayObject *o)
182
InstanceRayObject *obj = (InstanceRayObject*)o;
176
InstanceRayObject *obj = (InstanceRayObject *)o;
186
180
static float RE_rayobject_instance_cost(RayObject *o)
188
InstanceRayObject *obj = (InstanceRayObject*)o;
182
InstanceRayObject *obj = (InstanceRayObject *)o;
189
183
return RE_rayobject_cost(obj->target) + RE_COST_INSTANCE;
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;
199
193
float m[3], M[3], t[3];
202
196
RE_rayobject_merge_bb(obj->target, m, M);
204
198
//There must be a faster way than rotating all the 8 vertexs of the BB
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);