Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/embree/kernels/geometry/grid_soa_intersector_packet.h
9905 views
1
// Copyright 2009-2021 Intel Corporation
2
// SPDX-License-Identifier: Apache-2.0
3
4
#pragma once
5
6
#include "grid_soa.h"
7
#include "../common/ray.h"
8
#include "triangle_intersector_pluecker.h"
9
10
namespace embree
11
{
12
namespace isa
13
{
14
template<int K>
15
struct MapUV0
16
{
17
const float* const grid_uv;
18
size_t ofs00, ofs01, ofs10, ofs11;
19
20
__forceinline MapUV0(const float* const grid_uv, size_t ofs00, size_t ofs01, size_t ofs10, size_t ofs11)
21
: grid_uv(grid_uv), ofs00(ofs00), ofs01(ofs01), ofs10(ofs10), ofs11(ofs11) {}
22
23
__forceinline void operator() (vfloat<K>& u, vfloat<K>& v, Vec3vf<K>& Ng) const {
24
const vfloat<K> uv00(grid_uv[ofs00]);
25
const vfloat<K> uv01(grid_uv[ofs01]);
26
const vfloat<K> uv10(grid_uv[ofs10]);
27
const vfloat<K> uv11(grid_uv[ofs11]);
28
const Vec2vf<K> uv0 = GridSOA::decodeUV(uv00);
29
const Vec2vf<K> uv1 = GridSOA::decodeUV(uv01);
30
const Vec2vf<K> uv2 = GridSOA::decodeUV(uv10);
31
const Vec2vf<K> uv = madd(u,uv1,madd(v,uv2,(1.0f-u-v)*uv0));
32
u = uv[0]; v = uv[1];
33
}
34
};
35
36
template<int K>
37
struct MapUV1
38
{
39
const float* const grid_uv;
40
size_t ofs00, ofs01, ofs10, ofs11;
41
42
__forceinline MapUV1(const float* const grid_uv, size_t ofs00, size_t ofs01, size_t ofs10, size_t ofs11)
43
: grid_uv(grid_uv), ofs00(ofs00), ofs01(ofs01), ofs10(ofs10), ofs11(ofs11) {}
44
45
__forceinline void operator() (vfloat<K>& u, vfloat<K>& v, Vec3vf<K>& Ng) const {
46
const vfloat<K> uv00(grid_uv[ofs00]);
47
const vfloat<K> uv01(grid_uv[ofs01]);
48
const vfloat<K> uv10(grid_uv[ofs10]);
49
const vfloat<K> uv11(grid_uv[ofs11]);
50
const Vec2vf<K> uv0 = GridSOA::decodeUV(uv10);
51
const Vec2vf<K> uv1 = GridSOA::decodeUV(uv01);
52
const Vec2vf<K> uv2 = GridSOA::decodeUV(uv11);
53
const Vec2vf<K> uv = madd(u,uv1,madd(v,uv2,(1.0f-u-v)*uv0));
54
u = uv[0]; v = uv[1];
55
}
56
};
57
58
template<int K>
59
class GridSOAIntersectorK
60
{
61
public:
62
typedef void Primitive;
63
64
class Precalculations
65
{
66
#if defined(__AVX__)
67
static const int M = 8;
68
#else
69
static const int M = 4;
70
#endif
71
72
public:
73
__forceinline Precalculations (const vbool<K>& valid, const RayK<K>& ray)
74
: grid(nullptr), intersector(valid,ray) {}
75
76
public:
77
GridSOA* grid;
78
PlueckerIntersectorK<M,K> intersector; // FIXME: use quad intersector
79
};
80
81
/*! Intersect a ray with the primitive. */
82
static __forceinline void intersect(const vbool<K>& valid_i, Precalculations& pre, RayHitK<K>& ray, RayQueryContext* context, const Primitive* prim, size_t& lazy_node)
83
{
84
const size_t dim_offset = pre.grid->dim_offset;
85
const size_t line_offset = pre.grid->width;
86
const float* const grid_x = pre.grid->decodeLeaf(0,prim);
87
const float* const grid_y = grid_x + 1 * dim_offset;
88
const float* const grid_z = grid_x + 2 * dim_offset;
89
const float* const grid_uv = grid_x + 3 * dim_offset;
90
91
const size_t max_x = pre.grid->width == 2 ? 1 : 2;
92
const size_t max_y = pre.grid->height == 2 ? 1 : 2;
93
for (size_t y=0; y<max_y; y++)
94
{
95
for (size_t x=0; x<max_x; x++)
96
{
97
const size_t ofs00 = (y+0)*line_offset+(x+0);
98
const size_t ofs01 = (y+0)*line_offset+(x+1);
99
const size_t ofs10 = (y+1)*line_offset+(x+0);
100
const size_t ofs11 = (y+1)*line_offset+(x+1);
101
const Vec3vf<K> p00(grid_x[ofs00],grid_y[ofs00],grid_z[ofs00]);
102
const Vec3vf<K> p01(grid_x[ofs01],grid_y[ofs01],grid_z[ofs01]);
103
const Vec3vf<K> p10(grid_x[ofs10],grid_y[ofs10],grid_z[ofs10]);
104
const Vec3vf<K> p11(grid_x[ofs11],grid_y[ofs11],grid_z[ofs11]);
105
106
pre.intersector.intersectK(valid_i,ray,p00,p01,p10,MapUV0<K>(grid_uv,ofs00,ofs01,ofs10,ofs11),IntersectKEpilogMU<1,K,true>(ray,context,pre.grid->geomID(),pre.grid->primID()));
107
pre.intersector.intersectK(valid_i,ray,p10,p01,p11,MapUV1<K>(grid_uv,ofs00,ofs01,ofs10,ofs11),IntersectKEpilogMU<1,K,true>(ray,context,pre.grid->geomID(),pre.grid->primID()));
108
}
109
}
110
}
111
112
/*! Test if the ray is occluded by the primitive */
113
static __forceinline vbool<K> occluded(const vbool<K>& valid_i, Precalculations& pre, RayK<K>& ray, RayQueryContext* context, const Primitive* prim, size_t& lazy_node)
114
{
115
const size_t dim_offset = pre.grid->dim_offset;
116
const size_t line_offset = pre.grid->width;
117
const float* const grid_x = pre.grid->decodeLeaf(0,prim);
118
const float* const grid_y = grid_x + 1 * dim_offset;
119
const float* const grid_z = grid_x + 2 * dim_offset;
120
const float* const grid_uv = grid_x + 3 * dim_offset;
121
122
vbool<K> valid = valid_i;
123
const size_t max_x = pre.grid->width == 2 ? 1 : 2;
124
const size_t max_y = pre.grid->height == 2 ? 1 : 2;
125
for (size_t y=0; y<max_y; y++)
126
{
127
for (size_t x=0; x<max_x; x++)
128
{
129
const size_t ofs00 = (y+0)*line_offset+(x+0);
130
const size_t ofs01 = (y+0)*line_offset+(x+1);
131
const size_t ofs10 = (y+1)*line_offset+(x+0);
132
const size_t ofs11 = (y+1)*line_offset+(x+1);
133
const Vec3vf<K> p00(grid_x[ofs00],grid_y[ofs00],grid_z[ofs00]);
134
const Vec3vf<K> p01(grid_x[ofs01],grid_y[ofs01],grid_z[ofs01]);
135
const Vec3vf<K> p10(grid_x[ofs10],grid_y[ofs10],grid_z[ofs10]);
136
const Vec3vf<K> p11(grid_x[ofs11],grid_y[ofs11],grid_z[ofs11]);
137
138
pre.intersector.intersectK(valid,ray,p00,p01,p10,MapUV0<K>(grid_uv,ofs00,ofs01,ofs10,ofs11),OccludedKEpilogMU<1,K,true>(valid,ray,context,pre.grid->geomID(),pre.grid->primID()));
139
if (none(valid)) break;
140
pre.intersector.intersectK(valid,ray,p10,p01,p11,MapUV1<K>(grid_uv,ofs00,ofs01,ofs10,ofs11),OccludedKEpilogMU<1,K,true>(valid,ray,context,pre.grid->geomID(),pre.grid->primID()));
141
if (none(valid)) break;
142
}
143
}
144
return !valid;
145
}
146
147
template<typename Loader>
148
static __forceinline void intersect(RayHitK<K>& ray, size_t k,
149
RayQueryContext* context,
150
const float* const grid_x,
151
const size_t line_offset,
152
const size_t lines,
153
Precalculations& pre)
154
{
155
typedef typename Loader::vfloat vfloat;
156
const size_t dim_offset = pre.grid->dim_offset;
157
const float* const grid_y = grid_x + 1 * dim_offset;
158
const float* const grid_z = grid_x + 2 * dim_offset;
159
const float* const grid_uv = grid_x + 3 * dim_offset;
160
Vec3<vfloat> v0, v1, v2; Loader::gather(grid_x,grid_y,grid_z,line_offset,lines,v0,v1,v2);
161
pre.intersector.intersect(ray,k,v0,v1,v2,GridSOA::MapUV<Loader>(grid_uv,line_offset,lines),Intersect1KEpilogMU<Loader::M,K,true>(ray,k,context,pre.grid->geomID(),pre.grid->primID()));
162
};
163
164
template<typename Loader>
165
static __forceinline bool occluded(RayK<K>& ray, size_t k,
166
RayQueryContext* context,
167
const float* const grid_x,
168
const size_t line_offset,
169
const size_t lines,
170
Precalculations& pre)
171
{
172
typedef typename Loader::vfloat vfloat;
173
const size_t dim_offset = pre.grid->dim_offset;
174
const float* const grid_y = grid_x + 1 * dim_offset;
175
const float* const grid_z = grid_x + 2 * dim_offset;
176
const float* const grid_uv = grid_x + 3 * dim_offset;
177
Vec3<vfloat> v0, v1, v2; Loader::gather(grid_x,grid_y,grid_z,line_offset,lines,v0,v1,v2);
178
return pre.intersector.intersect(ray,k,v0,v1,v2,GridSOA::MapUV<Loader>(grid_uv,line_offset,lines),Occluded1KEpilogMU<Loader::M,K,true>(ray,k,context,pre.grid->geomID(),pre.grid->primID()));
179
}
180
181
/*! Intersect a ray with the primitive. */
182
static __forceinline void intersect(Precalculations& pre, RayHitK<K>& ray, size_t k, RayQueryContext* context, const Primitive* prim, size_t& lazy_node)
183
{
184
const size_t line_offset = pre.grid->width;
185
const size_t lines = pre.grid->height;
186
const float* const grid_x = pre.grid->decodeLeaf(0,prim);
187
#if defined(__AVX__)
188
intersect<GridSOA::Gather3x3>( ray, k, context, grid_x, line_offset, lines, pre);
189
#else
190
intersect<GridSOA::Gather2x3>(ray, k, context, grid_x , line_offset, lines, pre);
191
if (likely(lines > 2))
192
intersect<GridSOA::Gather2x3>(ray, k, context, grid_x+line_offset, line_offset, lines, pre);
193
#endif
194
}
195
196
/*! Test if the ray is occluded by the primitive */
197
static __forceinline bool occluded(Precalculations& pre, RayK<K>& ray, size_t k, RayQueryContext* context, const Primitive* prim, size_t& lazy_node)
198
{
199
const size_t line_offset = pre.grid->width;
200
const size_t lines = pre.grid->height;
201
const float* const grid_x = pre.grid->decodeLeaf(0,prim);
202
203
#if defined(__AVX__)
204
return occluded<GridSOA::Gather3x3>( ray, k, context, grid_x, line_offset, lines, pre);
205
#else
206
if (occluded<GridSOA::Gather2x3>(ray, k, context, grid_x , line_offset, lines, pre)) return true;
207
if (likely(lines > 2))
208
if (occluded<GridSOA::Gather2x3>(ray, k, context, grid_x+line_offset, line_offset, lines, pre)) return true;
209
#endif
210
return false;
211
}
212
};
213
214
template<int K>
215
class GridSOAMBIntersectorK
216
{
217
public:
218
typedef void Primitive;
219
typedef typename GridSOAIntersectorK<K>::Precalculations Precalculations;
220
221
/*! Intersect a ray with the primitive. */
222
static __forceinline void intersect(const vbool<K>& valid_i, Precalculations& pre, RayHitK<K>& ray, RayQueryContext* context, const Primitive* prim, size_t& lazy_node)
223
{
224
vfloat<K> vftime;
225
vint<K> vitime = getTimeSegment<K>(ray.time(), vfloat<K>((float)(pre.grid->time_steps-1)), vftime);
226
227
vbool<K> valid1 = valid_i;
228
while (any(valid1)) {
229
const size_t j = bsf(movemask(valid1));
230
const int itime = vitime[j];
231
const vbool<K> valid2 = valid1 & (itime == vitime);
232
valid1 = valid1 & !valid2;
233
intersect(valid2,pre,ray,vftime,itime,context,prim,lazy_node);
234
}
235
}
236
237
/*! Intersect a ray with the primitive. */
238
static __forceinline void intersect(const vbool<K>& valid_i, Precalculations& pre, RayHitK<K>& ray, const vfloat<K>& ftime, int itime, RayQueryContext* context, const Primitive* prim, size_t& lazy_node)
239
{
240
const size_t grid_offset = pre.grid->gridBytes >> 2;
241
const size_t dim_offset = pre.grid->dim_offset;
242
const size_t line_offset = pre.grid->width;
243
const float* const grid_x = pre.grid->decodeLeaf(itime,prim);
244
const float* const grid_y = grid_x + 1 * dim_offset;
245
const float* const grid_z = grid_x + 2 * dim_offset;
246
const float* const grid_uv = grid_x + 3 * dim_offset;
247
248
const size_t max_x = pre.grid->width == 2 ? 1 : 2;
249
const size_t max_y = pre.grid->height == 2 ? 1 : 2;
250
for (size_t y=0; y<max_y; y++)
251
{
252
for (size_t x=0; x<max_x; x++)
253
{
254
size_t ofs00 = (y+0)*line_offset+(x+0);
255
size_t ofs01 = (y+0)*line_offset+(x+1);
256
size_t ofs10 = (y+1)*line_offset+(x+0);
257
size_t ofs11 = (y+1)*line_offset+(x+1);
258
const Vec3vf<K> a00(grid_x[ofs00],grid_y[ofs00],grid_z[ofs00]);
259
const Vec3vf<K> a01(grid_x[ofs01],grid_y[ofs01],grid_z[ofs01]);
260
const Vec3vf<K> a10(grid_x[ofs10],grid_y[ofs10],grid_z[ofs10]);
261
const Vec3vf<K> a11(grid_x[ofs11],grid_y[ofs11],grid_z[ofs11]);
262
ofs00 += grid_offset;
263
ofs01 += grid_offset;
264
ofs10 += grid_offset;
265
ofs11 += grid_offset;
266
const Vec3vf<K> b00(grid_x[ofs00],grid_y[ofs00],grid_z[ofs00]);
267
const Vec3vf<K> b01(grid_x[ofs01],grid_y[ofs01],grid_z[ofs01]);
268
const Vec3vf<K> b10(grid_x[ofs10],grid_y[ofs10],grid_z[ofs10]);
269
const Vec3vf<K> b11(grid_x[ofs11],grid_y[ofs11],grid_z[ofs11]);
270
const Vec3vf<K> p00 = lerp(a00,b00,ftime);
271
const Vec3vf<K> p01 = lerp(a01,b01,ftime);
272
const Vec3vf<K> p10 = lerp(a10,b10,ftime);
273
const Vec3vf<K> p11 = lerp(a11,b11,ftime);
274
275
pre.intersector.intersectK(valid_i,ray,p00,p01,p10,MapUV0<K>(grid_uv,ofs00,ofs01,ofs10,ofs11),IntersectKEpilogMU<1,K,true>(ray,context,pre.grid->geomID(),pre.grid->primID()));
276
pre.intersector.intersectK(valid_i,ray,p10,p01,p11,MapUV1<K>(grid_uv,ofs00,ofs01,ofs10,ofs11),IntersectKEpilogMU<1,K,true>(ray,context,pre.grid->geomID(),pre.grid->primID()));
277
}
278
}
279
}
280
281
/*! Test if the ray is occluded by the primitive */
282
static __forceinline vbool<K> occluded(const vbool<K>& valid_i, Precalculations& pre, RayK<K>& ray, RayQueryContext* context, const Primitive* prim, size_t& lazy_node)
283
{
284
vfloat<K> vftime;
285
vint<K> vitime = getTimeSegment<K>(ray.time(), vfloat<K>((float)(pre.grid->time_steps-1)), vftime);
286
287
vbool<K> valid_o = valid_i;
288
vbool<K> valid1 = valid_i;
289
while (any(valid1)) {
290
const int j = int(bsf(movemask(valid1)));
291
const int itime = vitime[j];
292
const vbool<K> valid2 = valid1 & (itime == vitime);
293
valid1 = valid1 & !valid2;
294
valid_o &= !valid2 | occluded(valid2,pre,ray,vftime,itime,context,prim,lazy_node);
295
}
296
return !valid_o;
297
}
298
299
/*! Test if the ray is occluded by the primitive */
300
static __forceinline vbool<K> occluded(const vbool<K>& valid_i, Precalculations& pre, RayK<K>& ray, const vfloat<K>& ftime, int itime, RayQueryContext* context, const Primitive* prim, size_t& lazy_node)
301
{
302
const size_t grid_offset = pre.grid->gridBytes >> 2;
303
const size_t dim_offset = pre.grid->dim_offset;
304
const size_t line_offset = pre.grid->width;
305
const float* const grid_x = pre.grid->decodeLeaf(itime,prim);
306
const float* const grid_y = grid_x + 1 * dim_offset;
307
const float* const grid_z = grid_x + 2 * dim_offset;
308
const float* const grid_uv = grid_x + 3 * dim_offset;
309
310
vbool<K> valid = valid_i;
311
const size_t max_x = pre.grid->width == 2 ? 1 : 2;
312
const size_t max_y = pre.grid->height == 2 ? 1 : 2;
313
for (size_t y=0; y<max_y; y++)
314
{
315
for (size_t x=0; x<max_x; x++)
316
{
317
size_t ofs00 = (y+0)*line_offset+(x+0);
318
size_t ofs01 = (y+0)*line_offset+(x+1);
319
size_t ofs10 = (y+1)*line_offset+(x+0);
320
size_t ofs11 = (y+1)*line_offset+(x+1);
321
const Vec3vf<K> a00(grid_x[ofs00],grid_y[ofs00],grid_z[ofs00]);
322
const Vec3vf<K> a01(grid_x[ofs01],grid_y[ofs01],grid_z[ofs01]);
323
const Vec3vf<K> a10(grid_x[ofs10],grid_y[ofs10],grid_z[ofs10]);
324
const Vec3vf<K> a11(grid_x[ofs11],grid_y[ofs11],grid_z[ofs11]);
325
ofs00 += grid_offset;
326
ofs01 += grid_offset;
327
ofs10 += grid_offset;
328
ofs11 += grid_offset;
329
const Vec3vf<K> b00(grid_x[ofs00],grid_y[ofs00],grid_z[ofs00]);
330
const Vec3vf<K> b01(grid_x[ofs01],grid_y[ofs01],grid_z[ofs01]);
331
const Vec3vf<K> b10(grid_x[ofs10],grid_y[ofs10],grid_z[ofs10]);
332
const Vec3vf<K> b11(grid_x[ofs11],grid_y[ofs11],grid_z[ofs11]);
333
const Vec3vf<K> p00 = lerp(a00,b00,ftime);
334
const Vec3vf<K> p01 = lerp(a01,b01,ftime);
335
const Vec3vf<K> p10 = lerp(a10,b10,ftime);
336
const Vec3vf<K> p11 = lerp(a11,b11,ftime);
337
338
pre.intersector.intersectK(valid,ray,p00,p01,p10,MapUV0<K>(grid_uv,ofs00,ofs01,ofs10,ofs11),OccludedKEpilogMU<1,K,true>(valid,ray,context,pre.grid->geomID(),pre.grid->primID()));
339
if (none(valid)) break;
340
pre.intersector.intersectK(valid,ray,p10,p01,p11,MapUV1<K>(grid_uv,ofs00,ofs01,ofs10,ofs11),OccludedKEpilogMU<1,K,true>(valid,ray,context,pre.grid->geomID(),pre.grid->primID()));
341
if (none(valid)) break;
342
}
343
}
344
return valid;
345
}
346
347
template<typename Loader>
348
static __forceinline void intersect(RayHitK<K>& ray, size_t k,
349
const float ftime,
350
RayQueryContext* context,
351
const float* const grid_x,
352
const size_t line_offset,
353
const size_t lines,
354
Precalculations& pre)
355
{
356
typedef typename Loader::vfloat vfloat;
357
const size_t grid_offset = pre.grid->gridBytes >> 2;
358
const size_t dim_offset = pre.grid->dim_offset;
359
const float* const grid_y = grid_x + 1 * dim_offset;
360
const float* const grid_z = grid_x + 2 * dim_offset;
361
const float* const grid_uv = grid_x + 3 * dim_offset;
362
363
Vec3<vfloat> a0, a1, a2;
364
Loader::gather(grid_x,grid_y,grid_z,line_offset,lines,a0,a1,a2);
365
366
Vec3<vfloat> b0, b1, b2;
367
Loader::gather(grid_x+grid_offset,grid_y+grid_offset,grid_z+grid_offset,line_offset,lines,b0,b1,b2);
368
369
Vec3<vfloat> v0 = lerp(a0,b0,vfloat(ftime));
370
Vec3<vfloat> v1 = lerp(a1,b1,vfloat(ftime));
371
Vec3<vfloat> v2 = lerp(a2,b2,vfloat(ftime));
372
373
pre.intersector.intersect(ray,k,v0,v1,v2,GridSOA::MapUV<Loader>(grid_uv,line_offset,lines),Intersect1KEpilogMU<Loader::M,K,true>(ray,k,context,pre.grid->geomID(),pre.grid->primID()));
374
};
375
376
template<typename Loader>
377
static __forceinline bool occluded(RayK<K>& ray, size_t k,
378
const float ftime,
379
RayQueryContext* context,
380
const float* const grid_x,
381
const size_t line_offset,
382
const size_t lines,
383
Precalculations& pre)
384
{
385
typedef typename Loader::vfloat vfloat;
386
const size_t grid_offset = pre.grid->gridBytes >> 2;
387
const size_t dim_offset = pre.grid->dim_offset;
388
const float* const grid_y = grid_x + 1 * dim_offset;
389
const float* const grid_z = grid_x + 2 * dim_offset;
390
const float* const grid_uv = grid_x + 3 * dim_offset;
391
392
Vec3<vfloat> a0, a1, a2;
393
Loader::gather(grid_x,grid_y,grid_z,line_offset,lines,a0,a1,a2);
394
395
Vec3<vfloat> b0, b1, b2;
396
Loader::gather(grid_x+grid_offset,grid_y+grid_offset,grid_z+grid_offset,line_offset,lines,b0,b1,b2);
397
398
Vec3<vfloat> v0 = lerp(a0,b0,vfloat(ftime));
399
Vec3<vfloat> v1 = lerp(a1,b1,vfloat(ftime));
400
Vec3<vfloat> v2 = lerp(a2,b2,vfloat(ftime));
401
402
return pre.intersector.intersect(ray,k,v0,v1,v2,GridSOA::MapUV<Loader>(grid_uv,line_offset,lines),Occluded1KEpilogMU<Loader::M,K,true>(ray,k,context,pre.grid->geomID(),pre.grid->primID()));
403
}
404
405
/*! Intersect a ray with the primitive. */
406
static __forceinline void intersect(Precalculations& pre, RayHitK<K>& ray, size_t k, RayQueryContext* context, const Primitive* prim, size_t& lazy_node)
407
{
408
float ftime;
409
int itime = getTimeSegment(ray.time()[k], float(pre.grid->time_steps-1), ftime);
410
411
const size_t line_offset = pre.grid->width;
412
const size_t lines = pre.grid->height;
413
const float* const grid_x = pre.grid->decodeLeaf(itime,prim);
414
415
#if defined(__AVX__)
416
intersect<GridSOA::Gather3x3>( ray, k, ftime, context, grid_x, line_offset, lines, pre);
417
#else
418
intersect<GridSOA::Gather2x3>(ray, k, ftime, context, grid_x, line_offset, lines, pre);
419
if (likely(lines > 2))
420
intersect<GridSOA::Gather2x3>(ray, k, ftime, context, grid_x+line_offset, line_offset, lines, pre);
421
#endif
422
}
423
424
/*! Test if the ray is occluded by the primitive */
425
static __forceinline bool occluded(Precalculations& pre, RayK<K>& ray, size_t k, RayQueryContext* context, const Primitive* prim, size_t& lazy_node)
426
{
427
float ftime;
428
int itime = getTimeSegment(ray.time()[k], float(pre.grid->time_steps-1), ftime);
429
430
const size_t line_offset = pre.grid->width;
431
const size_t lines = pre.grid->height;
432
const float* const grid_x = pre.grid->decodeLeaf(itime,prim);
433
434
#if defined(__AVX__)
435
return occluded<GridSOA::Gather3x3>( ray, k, ftime, context, grid_x, line_offset, lines, pre);
436
#else
437
if (occluded<GridSOA::Gather2x3>(ray, k, ftime, context, grid_x, line_offset, lines, pre)) return true;
438
if (likely(lines > 2))
439
if (occluded<GridSOA::Gather2x3>(ray, k, ftime, context, grid_x+line_offset, line_offset, lines, pre)) return true;
440
#endif
441
return false;
442
}
443
};
444
}
445
}
446
447