Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/embree/kernels/geometry/curveNi_intersector.h
9905 views
1
// Copyright 2009-2021 Intel Corporation
2
// SPDX-License-Identifier: Apache-2.0
3
4
#pragma once
5
6
#include "curveNi.h"
7
8
#include "roundline_intersector.h"
9
#include "coneline_intersector.h"
10
#include "curve_intersector_ribbon.h"
11
#include "curve_intersector_oriented.h"
12
#include "curve_intersector_sweep.h"
13
14
namespace embree
15
{
16
namespace isa
17
{
18
template<int M>
19
struct CurveNiIntersector1
20
{
21
typedef CurveNi<M> Primitive;
22
typedef Vec3vf<M> Vec3vfM;
23
typedef LinearSpace3<Vec3vfM>LinearSpace3vfM;
24
typedef CurvePrecalculations1 Precalculations;
25
26
static __forceinline vbool<M> intersect(Ray& ray, const Primitive& prim, vfloat<M>& tNear_o)
27
{
28
const size_t N = prim.N;
29
#if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__)
30
const Vec3fa offset = *prim.offset(N);
31
const float scale = *prim.scale(N);
32
#else
33
const vfloat4 offset_scale = vfloat4::loadu(prim.offset(N));
34
const Vec3fa offset = Vec3fa(offset_scale);
35
const Vec3fa scale = Vec3fa(shuffle<3,3,3,3>(offset_scale));
36
#endif
37
const Vec3fa org1 = (ray.org-offset)*scale;
38
const Vec3fa dir1 = ray.dir*scale;
39
40
const LinearSpace3vfM space(vfloat<M>::load(prim.bounds_vx_x(N)), vfloat<M>::load(prim.bounds_vx_y(N)), vfloat<M>::load(prim.bounds_vx_z(N)),
41
vfloat<M>::load(prim.bounds_vy_x(N)), vfloat<M>::load(prim.bounds_vy_y(N)), vfloat<M>::load(prim.bounds_vy_z(N)),
42
vfloat<M>::load(prim.bounds_vz_x(N)), vfloat<M>::load(prim.bounds_vz_y(N)), vfloat<M>::load(prim.bounds_vz_z(N)));
43
44
const Vec3vfM dir2 = xfmVector(space,Vec3vfM(dir1));
45
const Vec3vfM org2 = xfmPoint (space,Vec3vfM(org1));
46
const Vec3vfM rcp_dir2 = rcp_safe(dir2);
47
48
const vfloat<M> t_lower_x = (vfloat<M>::load(prim.bounds_vx_lower(N))-vfloat<M>(org2.x))*vfloat<M>(rcp_dir2.x);
49
const vfloat<M> t_upper_x = (vfloat<M>::load(prim.bounds_vx_upper(N))-vfloat<M>(org2.x))*vfloat<M>(rcp_dir2.x);
50
const vfloat<M> t_lower_y = (vfloat<M>::load(prim.bounds_vy_lower(N))-vfloat<M>(org2.y))*vfloat<M>(rcp_dir2.y);
51
const vfloat<M> t_upper_y = (vfloat<M>::load(prim.bounds_vy_upper(N))-vfloat<M>(org2.y))*vfloat<M>(rcp_dir2.y);
52
const vfloat<M> t_lower_z = (vfloat<M>::load(prim.bounds_vz_lower(N))-vfloat<M>(org2.z))*vfloat<M>(rcp_dir2.z);
53
const vfloat<M> t_upper_z = (vfloat<M>::load(prim.bounds_vz_upper(N))-vfloat<M>(org2.z))*vfloat<M>(rcp_dir2.z);
54
55
const vfloat<M> round_up (1.0f+3.0f*float(ulp));
56
const vfloat<M> round_down(1.0f-3.0f*float(ulp));
57
const vfloat<M> tNear = round_down*max(mini(t_lower_x,t_upper_x),mini(t_lower_y,t_upper_y),mini(t_lower_z,t_upper_z),vfloat<M>(ray.tnear()));
58
const vfloat<M> tFar = round_up *min(maxi(t_lower_x,t_upper_x),maxi(t_lower_y,t_upper_y),maxi(t_lower_z,t_upper_z),vfloat<M>(ray.tfar));
59
tNear_o = tNear;
60
return (vint<M>(step) < vint<M>(prim.N)) & (tNear <= tFar);
61
}
62
63
template<typename Intersector, typename Epilog>
64
static __forceinline void intersect_t(const Precalculations& pre, RayHit& ray, RayQueryContext* context, const Primitive& prim)
65
{
66
vfloat<M> tNear;
67
vbool<M> valid = intersect(ray,prim,tNear);
68
69
const size_t N = prim.N;
70
size_t mask = movemask(valid);
71
while (mask)
72
{
73
const size_t i = bscf(mask);
74
STAT3(normal.trav_prims,1,1,1);
75
const unsigned int geomID = prim.geomID(N);
76
const unsigned int primID = prim.primID(N)[i];
77
const CurveGeometry* geom = context->scene->get<CurveGeometry>(geomID);
78
Vec3ff a0,a1,a2,a3; geom->gather(a0,a1,a2,a3,geom->curve(primID));
79
80
size_t mask1 = mask;
81
const size_t i1 = bscf(mask1);
82
if (mask) {
83
const unsigned int primID1 = prim.primID(N)[i1];
84
geom->prefetchL1_vertices(geom->curve(primID1));
85
if (mask1) {
86
const size_t i2 = bsf(mask1);
87
const unsigned int primID2 = prim.primID(N)[i2];
88
geom->prefetchL2_vertices(geom->curve(primID2));
89
}
90
}
91
92
Intersector().intersect(pre,ray,context,geom,primID,a0,a1,a2,a3,Epilog(ray,context,geomID,primID));
93
mask &= movemask(tNear <= vfloat<M>(ray.tfar));
94
}
95
}
96
97
template<typename Intersector, typename Epilog>
98
static __forceinline bool occluded_t(const Precalculations& pre, Ray& ray, RayQueryContext* context, const Primitive& prim)
99
{
100
vfloat<M> tNear;
101
vbool<M> valid = intersect(ray,prim,tNear);
102
103
const size_t N = prim.N;
104
size_t mask = movemask(valid);
105
while (mask)
106
{
107
const size_t i = bscf(mask);
108
STAT3(shadow.trav_prims,1,1,1);
109
const unsigned int geomID = prim.geomID(N);
110
const unsigned int primID = prim.primID(N)[i];
111
const CurveGeometry* geom = context->scene->get<CurveGeometry>(geomID);
112
Vec3ff a0,a1,a2,a3; geom->gather(a0,a1,a2,a3,geom->curve(primID));
113
114
size_t mask1 = mask;
115
const size_t i1 = bscf(mask1);
116
if (mask) {
117
const unsigned int primID1 = prim.primID(N)[i1];
118
geom->prefetchL1_vertices(geom->curve(primID1));
119
if (mask1) {
120
const size_t i2 = bsf(mask1);
121
const unsigned int primID2 = prim.primID(N)[i2];
122
geom->prefetchL2_vertices(geom->curve(primID2));
123
}
124
}
125
126
if (Intersector().intersect(pre,ray,context,geom,primID,a0,a1,a2,a3,Epilog(ray,context,geomID,primID)))
127
return true;
128
129
mask &= movemask(tNear <= vfloat<M>(ray.tfar));
130
}
131
return false;
132
}
133
134
template<typename Intersector, typename Epilog>
135
static __forceinline void intersect_n(const Precalculations& pre, RayHit& ray, RayQueryContext* context, const Primitive& prim)
136
{
137
vfloat<M> tNear;
138
vbool<M> valid = intersect(ray,prim,tNear);
139
140
const size_t N = prim.N;
141
size_t mask = movemask(valid);
142
while (mask)
143
{
144
const size_t i = bscf(mask);
145
STAT3(normal.trav_prims,1,1,1);
146
const unsigned int geomID = prim.geomID(N);
147
const unsigned int primID = prim.primID(N)[i];
148
const CurveGeometry* geom = context->scene->get<CurveGeometry>(geomID);
149
150
unsigned int vertexID = geom->curve(primID);
151
Vec3ff a0,a1,a2,a3; Vec3fa n0,n1,n2,n3; geom->gather(a0,a1,a2,a3,n0,n1,n2,n3,vertexID);
152
153
size_t mask1 = mask;
154
const size_t i1 = bscf(mask1);
155
if (mask) {
156
const unsigned int primID1 = prim.primID(N)[i1];
157
geom->prefetchL1_vertices(geom->curve(primID1));
158
if (mask1) {
159
const size_t i2 = bsf(mask1);
160
const unsigned int primID2 = prim.primID(N)[i2];
161
geom->prefetchL2_vertices(geom->curve(primID2));
162
}
163
}
164
165
Intersector().intersect(pre,ray,context,geom,primID,a0,a1,a2,a3,n0,n1,n2,n3,Epilog(ray,context,geomID,primID));
166
mask &= movemask(tNear <= vfloat<M>(ray.tfar));
167
}
168
}
169
170
template<typename Intersector, typename Epilog>
171
static __forceinline bool occluded_n(const Precalculations& pre, Ray& ray, RayQueryContext* context, const Primitive& prim)
172
{
173
vfloat<M> tNear;
174
vbool<M> valid = intersect(ray,prim,tNear);
175
176
const size_t N = prim.N;
177
size_t mask = movemask(valid);
178
while (mask)
179
{
180
const size_t i = bscf(mask);
181
STAT3(shadow.trav_prims,1,1,1);
182
const unsigned int geomID = prim.geomID(N);
183
const unsigned int primID = prim.primID(N)[i];
184
const CurveGeometry* geom = context->scene->get<CurveGeometry>(geomID);
185
186
unsigned int vertexID = geom->curve(primID);
187
Vec3ff a0,a1,a2,a3; Vec3fa n0,n1,n2,n3; geom->gather(a0,a1,a2,a3,n0,n1,n2,n3,vertexID);
188
189
size_t mask1 = mask;
190
const size_t i1 = bscf(mask1);
191
if (mask) {
192
const unsigned int primID1 = prim.primID(N)[i1];
193
geom->prefetchL1_vertices(geom->curve(primID1));
194
if (mask1) {
195
const size_t i2 = bsf(mask1);
196
const unsigned int primID2 = prim.primID(N)[i2];
197
geom->prefetchL2_vertices(geom->curve(primID2));
198
}
199
}
200
201
if (Intersector().intersect(pre,ray,context,geom,primID,a0,a1,a2,a3,n0,n1,n2,n3,Epilog(ray,context,geomID,primID)))
202
return true;
203
204
mask &= movemask(tNear <= vfloat<M>(ray.tfar));
205
}
206
return false;
207
}
208
209
template<typename Intersector, typename Epilog>
210
static __forceinline void intersect_h(const Precalculations& pre, RayHit& ray, RayQueryContext* context, const Primitive& prim)
211
{
212
vfloat<M> tNear;
213
vbool<M> valid = intersect(ray,prim,tNear);
214
215
const size_t N = prim.N;
216
size_t mask = movemask(valid);
217
while (mask)
218
{
219
const size_t i = bscf(mask);
220
STAT3(normal.trav_prims,1,1,1);
221
const unsigned int geomID = prim.geomID(N);
222
const unsigned int primID = prim.primID(N)[i];
223
const CurveGeometry* geom = context->scene->get<CurveGeometry>(geomID);
224
Vec3ff p0,t0,p1,t1; geom->gather_hermite(p0,t0,p1,t1,geom->curve(primID));
225
Intersector().intersect(pre,ray,context,geom,primID,p0,t0,p1,t1,Epilog(ray,context,geomID,primID));
226
mask &= movemask(tNear <= vfloat<M>(ray.tfar));
227
}
228
}
229
230
template<typename Intersector, typename Epilog>
231
static __forceinline bool occluded_h(const Precalculations& pre, Ray& ray, RayQueryContext* context, const Primitive& prim)
232
{
233
vfloat<M> tNear;
234
vbool<M> valid = intersect(ray,prim,tNear);
235
236
const size_t N = prim.N;
237
size_t mask = movemask(valid);
238
while (mask)
239
{
240
const size_t i = bscf(mask);
241
STAT3(shadow.trav_prims,1,1,1);
242
const unsigned int geomID = prim.geomID(N);
243
const unsigned int primID = prim.primID(N)[i];
244
const CurveGeometry* geom = context->scene->get<CurveGeometry>(geomID);
245
Vec3ff p0,t0,p1,t1; geom->gather_hermite(p0,t0,p1,t1,geom->curve(primID));
246
if (Intersector().intersect(pre,ray,context,geom,primID,p0,t0,p1,t1,Epilog(ray,context,geomID,primID)))
247
return true;
248
249
mask &= movemask(tNear <= vfloat<M>(ray.tfar));
250
}
251
return false;
252
}
253
254
template<typename Intersector, typename Epilog>
255
static __forceinline void intersect_hn(const Precalculations& pre, RayHit& ray, RayQueryContext* context, const Primitive& prim)
256
{
257
vfloat<M> tNear;
258
vbool<M> valid = intersect(ray,prim,tNear);
259
260
const size_t N = prim.N;
261
size_t mask = movemask(valid);
262
while (mask)
263
{
264
const size_t i = bscf(mask);
265
STAT3(normal.trav_prims,1,1,1);
266
const unsigned int geomID = prim.geomID(N);
267
const unsigned int primID = prim.primID(N)[i];
268
const CurveGeometry* geom = context->scene->get<CurveGeometry>(geomID);
269
Vec3ff p0,t0,p1,t1; Vec3fa n0,dn0,n1,dn1; geom->gather_hermite(p0,t0,n0,dn0,p1,t1,n1,dn1,geom->curve(primID));
270
Intersector().intersect(pre,ray,context,geom,primID,p0,t0,p1,t1,n0,dn0,n1,dn1,Epilog(ray,context,geomID,primID));
271
mask &= movemask(tNear <= vfloat<M>(ray.tfar));
272
}
273
}
274
275
template<typename Intersector, typename Epilog>
276
static __forceinline bool occluded_hn(const Precalculations& pre, Ray& ray, RayQueryContext* context, const Primitive& prim)
277
{
278
vfloat<M> tNear;
279
vbool<M> valid = intersect(ray,prim,tNear);
280
281
const size_t N = prim.N;
282
size_t mask = movemask(valid);
283
while (mask)
284
{
285
const size_t i = bscf(mask);
286
STAT3(shadow.trav_prims,1,1,1);
287
const unsigned int geomID = prim.geomID(N);
288
const unsigned int primID = prim.primID(N)[i];
289
const CurveGeometry* geom = context->scene->get<CurveGeometry>(geomID);
290
Vec3ff p0,t0,p1,t1; Vec3fa n0,dn0,n1,dn1; geom->gather_hermite(p0,t0,n0,dn0,p1,t1,n1,dn1,geom->curve(primID));
291
if (Intersector().intersect(pre,ray,context,geom,primID,p0,t0,p1,t1,n0,dn0,n1,dn1,Epilog(ray,context,geomID,primID)))
292
return true;
293
294
mask &= movemask(tNear <= vfloat<M>(ray.tfar));
295
}
296
return false;
297
}
298
};
299
300
template<int M, int K>
301
struct CurveNiIntersectorK
302
{
303
typedef CurveNi<M> Primitive;
304
typedef Vec3vf<M> Vec3vfM;
305
typedef LinearSpace3<Vec3vfM>LinearSpace3vfM;
306
typedef CurvePrecalculationsK<K> Precalculations;
307
308
static __forceinline vbool<M> intersect(RayK<K>& ray, const size_t k, const Primitive& prim, vfloat<M>& tNear_o)
309
{
310
const size_t N = prim.N;
311
#if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__)
312
const Vec3fa offset = *prim.offset(N);
313
const float scale = *prim.scale(N);
314
#else
315
const vfloat4 offset_scale = vfloat4::loadu(prim.offset(N));
316
const Vec3fa offset = Vec3fa(offset_scale);
317
const Vec3fa scale = Vec3fa(shuffle<3,3,3,3>(offset_scale));
318
#endif
319
const Vec3fa ray_org(ray.org.x[k],ray.org.y[k],ray.org.z[k]);
320
const Vec3fa ray_dir(ray.dir.x[k],ray.dir.y[k],ray.dir.z[k]);
321
const Vec3fa org1 = (ray_org-offset)*scale;
322
const Vec3fa dir1 = ray_dir*scale;
323
324
const LinearSpace3vfM space(vfloat<M>::load(prim.bounds_vx_x(N)), vfloat<M>::load(prim.bounds_vx_y(N)), vfloat<M>::load(prim.bounds_vx_z(N)),
325
vfloat<M>::load(prim.bounds_vy_x(N)), vfloat<M>::load(prim.bounds_vy_y(N)), vfloat<M>::load(prim.bounds_vy_z(N)),
326
vfloat<M>::load(prim.bounds_vz_x(N)), vfloat<M>::load(prim.bounds_vz_y(N)), vfloat<M>::load(prim.bounds_vz_z(N)));
327
328
const Vec3vfM dir2 = xfmVector(space,Vec3vfM(dir1));
329
const Vec3vfM org2 = xfmPoint (space,Vec3vfM(org1));
330
const Vec3vfM rcp_dir2 = rcp_safe(dir2);
331
332
const vfloat<M> t_lower_x = (vfloat<M>::load(prim.bounds_vx_lower(N))-vfloat<M>(org2.x))*vfloat<M>(rcp_dir2.x);
333
const vfloat<M> t_upper_x = (vfloat<M>::load(prim.bounds_vx_upper(N))-vfloat<M>(org2.x))*vfloat<M>(rcp_dir2.x);
334
const vfloat<M> t_lower_y = (vfloat<M>::load(prim.bounds_vy_lower(N))-vfloat<M>(org2.y))*vfloat<M>(rcp_dir2.y);
335
const vfloat<M> t_upper_y = (vfloat<M>::load(prim.bounds_vy_upper(N))-vfloat<M>(org2.y))*vfloat<M>(rcp_dir2.y);
336
const vfloat<M> t_lower_z = (vfloat<M>::load(prim.bounds_vz_lower(N))-vfloat<M>(org2.z))*vfloat<M>(rcp_dir2.z);
337
const vfloat<M> t_upper_z = (vfloat<M>::load(prim.bounds_vz_upper(N))-vfloat<M>(org2.z))*vfloat<M>(rcp_dir2.z);
338
339
const vfloat<M> round_up (1.0f+3.0f*float(ulp));
340
const vfloat<M> round_down(1.0f-3.0f*float(ulp));
341
const vfloat<M> tNear = round_down*max(mini(t_lower_x,t_upper_x),mini(t_lower_y,t_upper_y),mini(t_lower_z,t_upper_z),vfloat<M>(ray.tnear()[k]));
342
const vfloat<M> tFar = round_up *min(maxi(t_lower_x,t_upper_x),maxi(t_lower_y,t_upper_y),maxi(t_lower_z,t_upper_z),vfloat<M>(ray.tfar[k]));
343
tNear_o = tNear;
344
return (vint<M>(step) < vint<M>(prim.N)) & (tNear <= tFar);
345
}
346
347
template<typename Intersector, typename Epilog>
348
static __forceinline void intersect_t(Precalculations& pre, RayHitK<K>& ray, const size_t k, RayQueryContext* context, const Primitive& prim)
349
{
350
vfloat<M> tNear;
351
vbool<M> valid = intersect(ray,k,prim,tNear);
352
353
const size_t N = prim.N;
354
size_t mask = movemask(valid);
355
while (mask)
356
{
357
const size_t i = bscf(mask);
358
STAT3(normal.trav_prims,1,1,1);
359
const unsigned int geomID = prim.geomID(N);
360
const unsigned int primID = prim.primID(N)[i];
361
const CurveGeometry* geom = context->scene->get<CurveGeometry>(geomID);
362
Vec3ff a0,a1,a2,a3; geom->gather(a0,a1,a2,a3,geom->curve(primID));
363
364
size_t mask1 = mask;
365
const size_t i1 = bscf(mask1);
366
if (mask) {
367
const unsigned int primID1 = prim.primID(N)[i1];
368
geom->prefetchL1_vertices(geom->curve(primID1));
369
if (mask1) {
370
const size_t i2 = bsf(mask1);
371
const unsigned int primID2 = prim.primID(N)[i2];
372
geom->prefetchL2_vertices(geom->curve(primID2));
373
}
374
}
375
376
Intersector().intersect(pre,ray,k,context,geom,primID,a0,a1,a2,a3,Epilog(ray,k,context,geomID,primID));
377
mask &= movemask(tNear <= vfloat<M>(ray.tfar[k]));
378
}
379
}
380
381
template<typename Intersector, typename Epilog>
382
static __forceinline bool occluded_t(Precalculations& pre, RayK<K>& ray, const size_t k, RayQueryContext* context, const Primitive& prim)
383
{
384
vfloat<M> tNear;
385
vbool<M> valid = intersect(ray,k,prim,tNear);
386
387
const size_t N = prim.N;
388
size_t mask = movemask(valid);
389
while (mask)
390
{
391
const size_t i = bscf(mask);
392
STAT3(shadow.trav_prims,1,1,1);
393
const unsigned int geomID = prim.geomID(N);
394
const unsigned int primID = prim.primID(N)[i];
395
const CurveGeometry* geom = context->scene->get<CurveGeometry>(geomID);
396
Vec3ff a0,a1,a2,a3; geom->gather(a0,a1,a2,a3,geom->curve(primID));
397
398
size_t mask1 = mask;
399
const size_t i1 = bscf(mask1);
400
if (mask) {
401
const unsigned int primID1 = prim.primID(N)[i1];
402
geom->prefetchL1_vertices(geom->curve(primID1));
403
if (mask1) {
404
const size_t i2 = bsf(mask1);
405
const unsigned int primID2 = prim.primID(N)[i2];
406
geom->prefetchL2_vertices(geom->curve(primID2));
407
}
408
}
409
410
if (Intersector().intersect(pre,ray,k,context,geom,primID,a0,a1,a2,a3,Epilog(ray,k,context,geomID,primID)))
411
return true;
412
413
mask &= movemask(tNear <= vfloat<M>(ray.tfar[k]));
414
}
415
return false;
416
}
417
418
template<typename Intersector, typename Epilog>
419
static __forceinline void intersect_n(Precalculations& pre, RayHitK<K>& ray, const size_t k, RayQueryContext* context, const Primitive& prim)
420
{
421
vfloat<M> tNear;
422
vbool<M> valid = intersect(ray,k,prim,tNear);
423
424
const size_t N = prim.N;
425
size_t mask = movemask(valid);
426
while (mask)
427
{
428
const size_t i = bscf(mask);
429
STAT3(normal.trav_prims,1,1,1);
430
const unsigned int geomID = prim.geomID(N);
431
const unsigned int primID = prim.primID(N)[i];
432
const CurveGeometry* geom = context->scene->get<CurveGeometry>(geomID);
433
434
unsigned int vertexID = geom->curve(primID);
435
Vec3ff a0,a1,a2,a3; Vec3fa n0,n1,n2,n3; geom->gather(a0,a1,a2,a3,n0,n1,n2,n3,vertexID);
436
437
size_t mask1 = mask;
438
const size_t i1 = bscf(mask1);
439
if (mask) {
440
const unsigned int primID1 = prim.primID(N)[i1];
441
geom->prefetchL1_vertices(geom->curve(primID1));
442
if (mask1) {
443
const size_t i2 = bsf(mask1);
444
const unsigned int primID2 = prim.primID(N)[i2];
445
geom->prefetchL2_vertices(geom->curve(primID2));
446
}
447
}
448
449
Intersector().intersect(pre,ray,k,context,geom,primID,a0,a1,a2,a3,n0,n1,n2,n3,Epilog(ray,k,context,geomID,primID));
450
mask &= movemask(tNear <= vfloat<M>(ray.tfar[k]));
451
}
452
}
453
454
template<typename Intersector, typename Epilog>
455
static __forceinline bool occluded_n(Precalculations& pre, RayK<K>& ray, const size_t k, RayQueryContext* context, const Primitive& prim)
456
{
457
vfloat<M> tNear;
458
vbool<M> valid = intersect(ray,k,prim,tNear);
459
460
const size_t N = prim.N;
461
size_t mask = movemask(valid);
462
while (mask)
463
{
464
const size_t i = bscf(mask);
465
STAT3(shadow.trav_prims,1,1,1);
466
const unsigned int geomID = prim.geomID(N);
467
const unsigned int primID = prim.primID(N)[i];
468
const CurveGeometry* geom = context->scene->get<CurveGeometry>(geomID);
469
470
unsigned int vertexID = geom->curve(primID);
471
Vec3ff a0,a1,a2,a3; Vec3fa n0,n1,n2,n3; geom->gather(a0,a1,a2,a3,n0,n1,n2,n3,vertexID);
472
473
size_t mask1 = mask;
474
const size_t i1 = bscf(mask1);
475
if (mask) {
476
const unsigned int primID1 = prim.primID(N)[i1];
477
geom->prefetchL1_vertices(geom->curve(primID1));
478
if (mask1) {
479
const size_t i2 = bsf(mask1);
480
const unsigned int primID2 = prim.primID(N)[i2];
481
geom->prefetchL2_vertices(geom->curve(primID2));
482
}
483
}
484
485
if (Intersector().intersect(pre,ray,k,context,geom,primID,a0,a1,a2,a3,n0,n1,n2,n3,Epilog(ray,k,context,geomID,primID)))
486
return true;
487
488
mask &= movemask(tNear <= vfloat<M>(ray.tfar[k]));
489
}
490
return false;
491
}
492
493
template<typename Intersector, typename Epilog>
494
static __forceinline void intersect_h(Precalculations& pre, RayHitK<K>& ray, const size_t k, RayQueryContext* context, const Primitive& prim)
495
{
496
vfloat<M> tNear;
497
vbool<M> valid = intersect(ray,k,prim,tNear);
498
499
const size_t N = prim.N;
500
size_t mask = movemask(valid);
501
while (mask)
502
{
503
const size_t i = bscf(mask);
504
STAT3(normal.trav_prims,1,1,1);
505
const unsigned int geomID = prim.geomID(N);
506
const unsigned int primID = prim.primID(N)[i];
507
const CurveGeometry* geom = context->scene->get<CurveGeometry>(geomID);
508
Vec3ff p0,t0,p1,t1; geom->gather_hermite(p0,t0,p1,t1,geom->curve(primID));
509
Intersector().intersect(pre,ray,k,context,geom,primID,p0,t0,p1,t1,Epilog(ray,k,context,geomID,primID));
510
mask &= movemask(tNear <= vfloat<M>(ray.tfar[k]));
511
}
512
}
513
514
template<typename Intersector, typename Epilog>
515
static __forceinline bool occluded_h(Precalculations& pre, RayK<K>& ray, const size_t k, RayQueryContext* context, const Primitive& prim)
516
{
517
vfloat<M> tNear;
518
vbool<M> valid = intersect(ray,k,prim,tNear);
519
520
const size_t N = prim.N;
521
size_t mask = movemask(valid);
522
while (mask)
523
{
524
const size_t i = bscf(mask);
525
STAT3(shadow.trav_prims,1,1,1);
526
const unsigned int geomID = prim.geomID(N);
527
const unsigned int primID = prim.primID(N)[i];
528
const CurveGeometry* geom = context->scene->get<CurveGeometry>(geomID);
529
Vec3ff p0,t0,p1,t1; geom->gather_hermite(p0,t0,p1,t1,geom->curve(primID));
530
if (Intersector().intersect(pre,ray,k,context,geom,primID,p0,t0,p1,t1,Epilog(ray,k,context,geomID,primID)))
531
return true;
532
533
mask &= movemask(tNear <= vfloat<M>(ray.tfar[k]));
534
}
535
return false;
536
}
537
538
template<typename Intersector, typename Epilog>
539
static __forceinline void intersect_hn(Precalculations& pre, RayHitK<K>& ray, const size_t k, RayQueryContext* context, const Primitive& prim)
540
{
541
vfloat<M> tNear;
542
vbool<M> valid = intersect(ray,k,prim,tNear);
543
544
const size_t N = prim.N;
545
size_t mask = movemask(valid);
546
while (mask)
547
{
548
const size_t i = bscf(mask);
549
STAT3(normal.trav_prims,1,1,1);
550
const unsigned int geomID = prim.geomID(N);
551
const unsigned int primID = prim.primID(N)[i];
552
const CurveGeometry* geom = context->scene->get<CurveGeometry>(geomID);
553
Vec3ff p0,t0,p1,t1; Vec3fa n0,dn0,n1,dn1; geom->gather_hermite(p0,t0,n0,dn0,p1,t1,n1,dn1,geom->curve(primID));
554
Intersector().intersect(pre,ray,k,context,geom,primID,p0,t0,p1,t1,n0,dn0,n1,dn1,Epilog(ray,k,context,geomID,primID));
555
mask &= movemask(tNear <= vfloat<M>(ray.tfar[k]));
556
}
557
}
558
559
template<typename Intersector, typename Epilog>
560
static __forceinline bool occluded_hn(Precalculations& pre, RayK<K>& ray, const size_t k, RayQueryContext* context, const Primitive& prim)
561
{
562
vfloat<M> tNear;
563
vbool<M> valid = intersect(ray,k,prim,tNear);
564
565
const size_t N = prim.N;
566
size_t mask = movemask(valid);
567
while (mask)
568
{
569
const size_t i = bscf(mask);
570
STAT3(shadow.trav_prims,1,1,1);
571
const unsigned int geomID = prim.geomID(N);
572
const unsigned int primID = prim.primID(N)[i];
573
const CurveGeometry* geom = context->scene->get<CurveGeometry>(geomID);
574
Vec3ff p0,t0,p1,t1; Vec3fa n0,dn0,n1,dn1; geom->gather_hermite(p0,t0,n0,dn0,p1,t1,n1,dn1,geom->curve(primID));
575
if (Intersector().intersect(pre,ray,k,context,geom,primID,p0,t0,p1,t1,n0,dn0,n1,dn1,Epilog(ray,k,context,geomID,primID)))
576
return true;
577
578
mask &= movemask(tNear <= vfloat<M>(ray.tfar[k]));
579
}
580
return false;
581
}
582
};
583
584
__forceinline void convert_to_bezier(const Geometry::GType gtype,
585
Vec3ff& v0, Vec3ff& v1, Vec3ff& v2, Vec3ff& v3,
586
Vec3fa& n0, Vec3fa& n1, Vec3fa& n2, Vec3fa& n3)
587
{
588
const Geometry::GType basis = (Geometry::GType)(gtype & Geometry::GTY_BASIS_MASK);
589
const Geometry::GType stype = (Geometry::GType)(gtype & Geometry::GTY_SUBTYPE_MASK);
590
591
if (basis == Geometry::GTY_BASIS_BSPLINE) {
592
BezierCurveT<Vec3ff> bezier;
593
convert(BSplineCurveT<Vec3ff>(v0,v1,v2,v3),bezier);
594
v0 = bezier.v0; v1 = bezier.v1; v2 = bezier.v2; v3 = bezier.v3;
595
}
596
else if (basis == Geometry::GTY_BASIS_HERMITE) {
597
BezierCurveT<Vec3ff> bezier;
598
convert(HermiteCurveT<Vec3ff>(v0,v1,v2,v3),bezier);
599
v0 = bezier.v0; v1 = bezier.v1; v2 = bezier.v2; v3 = bezier.v3;
600
}
601
else if (basis == Geometry::GTY_BASIS_CATMULL_ROM) {
602
BezierCurveT<Vec3ff> bezier;
603
convert(CatmullRomCurveT<Vec3ff>(v0,v1,v2,v3),bezier);
604
v0 = bezier.v0; v1 = bezier.v1; v2 = bezier.v2; v3 = bezier.v3;
605
}
606
607
if (stype == Geometry::GTY_SUBTYPE_ORIENTED_CURVE)
608
{
609
if (basis == Geometry::GTY_BASIS_BSPLINE) {
610
BezierCurveT<Vec3fa> bezier;
611
convert(BSplineCurveT<Vec3fa>(n0,n1,n2,n3),bezier);
612
n0 = bezier.v0; n1 = bezier.v1; n2 = bezier.v2; n3 = bezier.v3;
613
}
614
else if (basis == Geometry::GTY_BASIS_HERMITE) {
615
BezierCurveT<Vec3fa> bezier;
616
convert(HermiteCurveT<Vec3fa>(n0,n1,n2,n3),bezier);
617
n0 = bezier.v0; n1 = bezier.v1; n2 = bezier.v2; n3 = bezier.v3;
618
}
619
else if (basis == Geometry::GTY_BASIS_CATMULL_ROM) {
620
BezierCurveT<Vec3fa> bezier;
621
convert(CatmullRomCurveT<Vec3fa>(n0,n1,n2,n3),bezier);
622
n0 = bezier.v0; n1 = bezier.v1; n2 = bezier.v2; n3 = bezier.v3;
623
}
624
}
625
}
626
627
__forceinline void convert_to_bezier(const Geometry::GType gtype, Vec3ff& v0, Vec3ff& v1, Vec3ff& v2, Vec3ff& v3)
628
{
629
const Geometry::GType basis = (Geometry::GType)(gtype & Geometry::GTY_BASIS_MASK);
630
631
if (basis == Geometry::GTY_BASIS_BSPLINE) {
632
BezierCurveT<Vec3ff> bezier;
633
convert(BSplineCurveT<Vec3ff>(v0,v1,v2,v3),bezier);
634
v0 = bezier.v0; v1 = bezier.v1; v2 = bezier.v2; v3 = bezier.v3;
635
}
636
else if (basis == Geometry::GTY_BASIS_HERMITE) {
637
BezierCurveT<Vec3ff> bezier;
638
convert(HermiteCurveT<Vec3ff>(v0,v1,v2,v3),bezier);
639
v0 = bezier.v0; v1 = bezier.v1; v2 = bezier.v2; v3 = bezier.v3;
640
}
641
else if (basis == Geometry::GTY_BASIS_CATMULL_ROM) {
642
BezierCurveT<Vec3ff> bezier;
643
convert(CatmullRomCurveT<Vec3ff>(v0,v1,v2,v3),bezier);
644
v0 = bezier.v0; v1 = bezier.v1; v2 = bezier.v2; v3 = bezier.v3;
645
}
646
}
647
}
648
}
649
650