Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/embree/kernels/geometry/linei.h
9905 views
1
// Copyright 2009-2021 Intel Corporation
2
// SPDX-License-Identifier: Apache-2.0
3
4
#pragma once
5
6
#include "primitive.h"
7
8
namespace embree
9
{
10
template<int M>
11
struct LineMi
12
{
13
/* Virtual interface to query information about the line segment type */
14
struct Type : public PrimitiveType
15
{
16
const char* name() const;
17
size_t sizeActive(const char* This) const;
18
size_t sizeTotal(const char* This) const;
19
size_t getBytes(const char* This) const;
20
};
21
static Type type;
22
23
public:
24
25
/* primitive supports multiple time segments */
26
static const bool singleTimeSegment = false;
27
28
/* Returns maximum number of stored line segments */
29
static __forceinline size_t max_size() { return M; }
30
31
/* Returns required number of primitive blocks for N line segments */
32
static __forceinline size_t blocks(size_t N) { return (N+max_size()-1)/max_size(); }
33
34
/* Returns required number of bytes for N line segments */
35
static __forceinline size_t bytes(size_t N) { return blocks(N)*sizeof(LineMi); }
36
37
public:
38
39
/* Default constructor */
40
__forceinline LineMi() { }
41
42
/* Construction from vertices and IDs */
43
__forceinline LineMi(const vuint<M>& v0, unsigned short leftExists, unsigned short rightExists, const vuint<M>& geomIDs, const vuint<M>& primIDs, Geometry::GType gtype)
44
: gtype((unsigned char)gtype), m((unsigned char)popcnt(vuint<M>(primIDs) != vuint<M>(-1))), sharedGeomID(geomIDs[0]), leftExists (leftExists), rightExists(rightExists), v0(v0), primIDs(primIDs)
45
{
46
assert(all(vuint<M>(geomID()) == geomIDs));
47
}
48
49
/* Returns a mask that tells which line segments are valid */
50
__forceinline vbool<M> valid() const { return primIDs != vuint<M>(-1); }
51
52
/* Returns if the specified line segment is valid */
53
__forceinline bool valid(const size_t i) const { assert(i<M); return primIDs[i] != -1; }
54
55
/* Returns the number of stored line segments */
56
__forceinline size_t size() const { return bsf(~movemask(valid())); }
57
58
/* Returns the geometry IDs */
59
//template<class T>
60
//static __forceinline T unmask(T &index) { return index & 0x3fffffff; }
61
62
__forceinline unsigned int geomID(unsigned int i = 0) const { return sharedGeomID; }
63
//__forceinline vuint<M> geomID() { return unmask(geomIDs); }
64
//__forceinline const vuint<M> geomID() const { return unmask(geomIDs); }
65
//__forceinline unsigned int geomID(const size_t i) const { assert(i<M); return unmask(geomIDs[i]); }
66
67
/* Returns the primitive IDs */
68
__forceinline vuint<M>& primID() { return primIDs; }
69
__forceinline const vuint<M>& primID() const { return primIDs; }
70
__forceinline unsigned int primID(const size_t i) const { assert(i<M); return primIDs[i]; }
71
72
/* gather the line segments */
73
__forceinline void gather(Vec4vf<M>& p0,
74
Vec4vf<M>& p1,
75
const LineSegments* geom) const;
76
77
__forceinline void gatheri(Vec4vf<M>& p0,
78
Vec4vf<M>& p1,
79
const LineSegments* geom,
80
const int itime) const;
81
82
__forceinline void gather(Vec4vf<M>& p0,
83
Vec4vf<M>& p1,
84
const LineSegments* geom,
85
float time) const;
86
87
/* gather the line segments with lateral info */
88
__forceinline void gather(Vec4vf<M>& p0,
89
Vec4vf<M>& p1,
90
Vec4vf<M>& pL,
91
Vec4vf<M>& pR,
92
const LineSegments* geom) const;
93
94
__forceinline void gatheri(Vec4vf<M>& p0,
95
Vec4vf<M>& p1,
96
Vec4vf<M>& pL,
97
Vec4vf<M>& pR,
98
const LineSegments* geom,
99
const int itime) const;
100
101
__forceinline void gather(Vec4vf<M>& p0,
102
Vec4vf<M>& p1,
103
Vec4vf<M>& pL,
104
Vec4vf<M>& pR,
105
const LineSegments* geom,
106
float time) const;
107
108
__forceinline void gather(Vec4vf<M>& p0,
109
Vec4vf<M>& p1,
110
vbool<M>& cL,
111
vbool<M>& cR,
112
const LineSegments* geom) const;
113
114
__forceinline void gatheri(Vec4vf<M>& p0,
115
Vec4vf<M>& p1,
116
vbool<M>& cL,
117
vbool<M>& cR,
118
const LineSegments* geom,
119
const int itime) const;
120
121
__forceinline void gather(Vec4vf<M>& p0,
122
Vec4vf<M>& p1,
123
vbool<M>& cL,
124
vbool<M>& cR,
125
const LineSegments* geom,
126
float time) const;
127
128
/* Calculate the bounds of the line segments */
129
__forceinline const BBox3fa bounds(const Scene* scene, size_t itime = 0) const
130
{
131
BBox3fa bounds = empty;
132
for (size_t i=0; i<M && valid(i); i++)
133
{
134
const LineSegments* geom = scene->get<LineSegments>(geomID(i));
135
const Vec3ff& p0 = geom->vertex(v0[i]+0,itime);
136
const Vec3ff& p1 = geom->vertex(v0[i]+1,itime);
137
BBox3fa b = merge(BBox3fa(p0),BBox3fa(p1));
138
b = enlarge(b,Vec3fa(max(p0.w,p1.w)));
139
bounds.extend(b);
140
}
141
return bounds;
142
}
143
144
/* Calculate the linear bounds of the primitive */
145
__forceinline LBBox3fa linearBounds(const Scene* scene, size_t itime) {
146
return LBBox3fa(bounds(scene,itime+0), bounds(scene,itime+1));
147
}
148
149
__forceinline LBBox3fa linearBounds(const Scene *const scene, size_t itime, size_t numTimeSteps) {
150
LBBox3fa allBounds = empty;
151
for (size_t i=0; i<M && valid(i); i++)
152
{
153
const LineSegments* geom = scene->get<LineSegments>(geomID(i));
154
allBounds.extend(geom->linearBounds(primID(i), itime, numTimeSteps));
155
}
156
return allBounds;
157
}
158
159
__forceinline LBBox3fa linearBounds(const Scene *const scene, const BBox1f time_range)
160
{
161
LBBox3fa allBounds = empty;
162
for (size_t i=0; i<M && valid(i); i++)
163
{
164
const LineSegments* geom = scene->get<LineSegments>(geomID((unsigned int)i));
165
allBounds.extend(geom->linearBounds(primID(i), time_range));
166
}
167
return allBounds;
168
}
169
170
/* Fill line segment from line segment list */
171
template<typename PrimRefT>
172
__forceinline void fill(const PrimRefT* prims, size_t& begin, size_t end, Scene* scene)
173
{
174
Geometry::GType gty = scene->get(prims[begin].geomID())->getType();
175
vuint<M> geomID, primID;
176
vuint<M> v0;
177
unsigned short leftExists = 0;
178
unsigned short rightExists = 0;
179
const PrimRefT* prim = &prims[begin];
180
181
for (size_t i=0; i<M; i++)
182
{
183
const LineSegments* geom = scene->get<LineSegments>(prim->geomID());
184
if (begin<end) {
185
geomID[i] = prim->geomID();
186
primID[i] = prim->primID();
187
v0[i] = geom->segment(prim->primID());
188
leftExists |= geom->segmentLeftExists(primID[i]) << i;
189
rightExists |= geom->segmentRightExists(primID[i]) << i;
190
begin++;
191
} else {
192
assert(i);
193
if (i>0) {
194
geomID[i] = geomID[i-1];
195
primID[i] = -1;
196
v0[i] = v0[i-1];
197
}
198
}
199
if (begin<end) prim = &prims[begin]; // FIXME: remove this line
200
}
201
new (this) LineMi(v0,leftExists,rightExists,geomID,primID,gty); // FIXME: use non temporal store
202
}
203
204
template<typename BVH, typename Allocator>
205
__forceinline static typename BVH::NodeRef createLeaf (BVH* bvh, const PrimRef* prims, const range<size_t>& set, const Allocator& alloc)
206
{
207
size_t start = set.begin();
208
size_t items = LineMi::blocks(set.size());
209
size_t numbytes = LineMi::bytes(set.size());
210
LineMi* accel = (LineMi*) alloc.malloc1(numbytes,M*sizeof(float));
211
for (size_t i=0; i<items; i++) {
212
accel[i].fill(prims,start,set.end(),bvh->scene);
213
}
214
return bvh->encodeLeaf((char*)accel,items);
215
};
216
217
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime)
218
{
219
fill(prims,begin,end,scene);
220
return linearBounds(scene,itime);
221
}
222
223
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range)
224
{
225
fill(prims,begin,end,scene);
226
return linearBounds(scene,time_range);
227
}
228
229
template<typename BVH, typename SetMB, typename Allocator>
230
__forceinline static typename BVH::NodeRecordMB4D createLeafMB(BVH* bvh, const SetMB& prims, const Allocator& alloc)
231
{
232
size_t start = prims.begin();
233
size_t end = prims.end();
234
size_t items = LineMi::blocks(prims.size());
235
size_t numbytes = LineMi::bytes(prims.size());
236
LineMi* accel = (LineMi*) alloc.malloc1(numbytes,M*sizeof(float));
237
const typename BVH::NodeRef node = bvh->encodeLeaf((char*)accel,items);
238
239
LBBox3fa bounds = empty;
240
for (size_t i=0; i<items; i++)
241
bounds.extend(accel[i].fillMB(prims.prims->data(),start,end,bvh->scene,prims.time_range));
242
243
return typename BVH::NodeRecordMB4D(node,bounds,prims.time_range);
244
};
245
246
/* Updates the primitive */
247
__forceinline BBox3fa update(LineSegments* geom)
248
{
249
BBox3fa bounds = empty;
250
for (size_t i=0; i<M && valid(i); i++)
251
{
252
const Vec3ff& p0 = geom->vertex(v0[i]+0);
253
const Vec3ff& p1 = geom->vertex(v0[i]+1);
254
BBox3fa b = merge(BBox3fa(p0),BBox3fa(p1));
255
b = enlarge(b,Vec3fa(max(p0.w,p1.w)));
256
bounds.extend(b);
257
}
258
return bounds;
259
}
260
261
/*! output operator */
262
friend __forceinline embree_ostream operator<<(embree_ostream cout, const LineMi& line) {
263
return cout << "Line" << M << "i {" << line.v0 << ", " << line.geomID() << ", " << line.primID() << "}";
264
}
265
266
public:
267
unsigned char gtype;
268
unsigned char m;
269
unsigned int sharedGeomID;
270
unsigned short leftExists, rightExists;
271
vuint<M> v0; // index of start vertex
272
private:
273
vuint<M> primIDs; // primitive ID
274
};
275
276
template<>
277
__forceinline void LineMi<4>::gather(Vec4vf4& p0,
278
Vec4vf4& p1,
279
const LineSegments* geom) const
280
{
281
const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(v0[0]));
282
const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(v0[1]));
283
const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(v0[2]));
284
const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(v0[3]));
285
transpose(a0,a1,a2,a3,p0.x,p0.y,p0.z,p0.w);
286
287
const vfloat4 b0 = vfloat4::loadu(geom->vertexPtr(v0[0]+1));
288
const vfloat4 b1 = vfloat4::loadu(geom->vertexPtr(v0[1]+1));
289
const vfloat4 b2 = vfloat4::loadu(geom->vertexPtr(v0[2]+1));
290
const vfloat4 b3 = vfloat4::loadu(geom->vertexPtr(v0[3]+1));
291
transpose(b0,b1,b2,b3,p1.x,p1.y,p1.z,p1.w);
292
}
293
294
template<>
295
__forceinline void LineMi<4>::gatheri(Vec4vf4& p0,
296
Vec4vf4& p1,
297
const LineSegments* geom,
298
const int itime) const
299
{
300
const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(v0[0],itime));
301
const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(v0[1],itime));
302
const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(v0[2],itime));
303
const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(v0[3],itime));
304
transpose(a0,a1,a2,a3,p0.x,p0.y,p0.z,p0.w);
305
306
const vfloat4 b0 = vfloat4::loadu(geom->vertexPtr(v0[0]+1,itime));
307
const vfloat4 b1 = vfloat4::loadu(geom->vertexPtr(v0[1]+1,itime));
308
const vfloat4 b2 = vfloat4::loadu(geom->vertexPtr(v0[2]+1,itime));
309
const vfloat4 b3 = vfloat4::loadu(geom->vertexPtr(v0[3]+1,itime));
310
transpose(b0,b1,b2,b3,p1.x,p1.y,p1.z,p1.w);
311
}
312
313
template<>
314
__forceinline void LineMi<4>::gather(Vec4vf4& p0,
315
Vec4vf4& p1,
316
const LineSegments* geom,
317
float time) const
318
{
319
float ftime;
320
const int itime = geom->timeSegment(time, ftime);
321
322
Vec4vf4 a0,a1;
323
gatheri(a0,a1,geom,itime);
324
Vec4vf4 b0,b1;
325
gatheri(b0,b1,geom,itime+1);
326
p0 = lerp(a0,b0,vfloat4(ftime));
327
p1 = lerp(a1,b1,vfloat4(ftime));
328
}
329
330
template<>
331
__forceinline void LineMi<4>::gather(Vec4vf4& p0,
332
Vec4vf4& p1,
333
vbool4& cL,
334
vbool4& cR,
335
const LineSegments* geom) const
336
{
337
gather(p0,p1,geom);
338
cL = !vbool4(leftExists);
339
cR = !vbool4(rightExists);
340
}
341
342
template<>
343
__forceinline void LineMi<4>::gatheri(Vec4vf4& p0,
344
Vec4vf4& p1,
345
vbool4& cL,
346
vbool4& cR,
347
const LineSegments* geom,
348
const int itime) const
349
{
350
gatheri(p0,p1,geom,itime);
351
cL = !vbool4(leftExists);
352
cR = !vbool4(rightExists);
353
}
354
355
template<>
356
__forceinline void LineMi<4>::gather(Vec4vf4& p0,
357
Vec4vf4& p1,
358
vbool4& cL,
359
vbool4& cR,
360
const LineSegments* geom,
361
float time) const
362
{
363
float ftime;
364
const int itime = geom->timeSegment(time, ftime);
365
366
Vec4vf4 a0,a1;
367
gatheri(a0,a1,geom,itime);
368
Vec4vf4 b0,b1;
369
gatheri(b0,b1,geom,itime+1);
370
p0 = lerp(a0,b0,vfloat4(ftime));
371
p1 = lerp(a1,b1,vfloat4(ftime));
372
cL = !vbool4(leftExists);
373
cR = !vbool4(rightExists);
374
}
375
376
template<>
377
__forceinline void LineMi<4>::gather(Vec4vf4& p0,
378
Vec4vf4& p1,
379
Vec4vf4& pL,
380
Vec4vf4& pR,
381
const LineSegments* geom) const
382
{
383
const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(v0[0]));
384
const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(v0[1]));
385
const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(v0[2]));
386
const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(v0[3]));
387
transpose(a0,a1,a2,a3,p0.x,p0.y,p0.z,p0.w);
388
389
const vfloat4 b0 = vfloat4::loadu(geom->vertexPtr(v0[0]+1));
390
const vfloat4 b1 = vfloat4::loadu(geom->vertexPtr(v0[1]+1));
391
const vfloat4 b2 = vfloat4::loadu(geom->vertexPtr(v0[2]+1));
392
const vfloat4 b3 = vfloat4::loadu(geom->vertexPtr(v0[3]+1));
393
transpose(b0,b1,b2,b3,p1.x,p1.y,p1.z,p1.w);
394
395
const vfloat4 l0 = (leftExists & (1<<0)) ? vfloat4::loadu(geom->vertexPtr(v0[0]-1)) : vfloat4(inf);
396
const vfloat4 l1 = (leftExists & (1<<1)) ? vfloat4::loadu(geom->vertexPtr(v0[1]-1)) : vfloat4(inf);
397
const vfloat4 l2 = (leftExists & (1<<2)) ? vfloat4::loadu(geom->vertexPtr(v0[2]-1)) : vfloat4(inf);
398
const vfloat4 l3 = (leftExists & (1<<3)) ? vfloat4::loadu(geom->vertexPtr(v0[3]-1)) : vfloat4(inf);
399
transpose(l0,l1,l2,l3,pL.x,pL.y,pL.z,pL.w);
400
401
const vfloat4 r0 = (rightExists & (1<<0)) ? vfloat4::loadu(geom->vertexPtr(v0[0]+2)) : vfloat4(inf);
402
const vfloat4 r1 = (rightExists & (1<<1)) ? vfloat4::loadu(geom->vertexPtr(v0[1]+2)) : vfloat4(inf);
403
const vfloat4 r2 = (rightExists & (1<<2)) ? vfloat4::loadu(geom->vertexPtr(v0[2]+2)) : vfloat4(inf);
404
const vfloat4 r3 = (rightExists & (1<<3)) ? vfloat4::loadu(geom->vertexPtr(v0[3]+2)) : vfloat4(inf);
405
transpose(r0,r1,r2,r3,pR.x,pR.y,pR.z,pR.w);
406
}
407
408
template<>
409
__forceinline void LineMi<4>::gatheri(Vec4vf4& p0,
410
Vec4vf4& p1,
411
Vec4vf4& pL,
412
Vec4vf4& pR,
413
const LineSegments* geom,
414
const int itime) const
415
{
416
const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(v0[0],itime));
417
const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(v0[1],itime));
418
const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(v0[2],itime));
419
const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(v0[3],itime));
420
transpose(a0,a1,a2,a3,p0.x,p0.y,p0.z,p0.w);
421
422
const vfloat4 b0 = vfloat4::loadu(geom->vertexPtr(v0[0]+1,itime));
423
const vfloat4 b1 = vfloat4::loadu(geom->vertexPtr(v0[1]+1,itime));
424
const vfloat4 b2 = vfloat4::loadu(geom->vertexPtr(v0[2]+1,itime));
425
const vfloat4 b3 = vfloat4::loadu(geom->vertexPtr(v0[3]+1,itime));
426
transpose(b0,b1,b2,b3,p1.x,p1.y,p1.z,p1.w);
427
428
const vfloat4 l0 = (leftExists & (1<<0)) ? vfloat4::loadu(geom->vertexPtr(v0[0]-1,itime)) : vfloat4(inf);
429
const vfloat4 l1 = (leftExists & (1<<1)) ? vfloat4::loadu(geom->vertexPtr(v0[1]-1,itime)) : vfloat4(inf);
430
const vfloat4 l2 = (leftExists & (1<<2)) ? vfloat4::loadu(geom->vertexPtr(v0[2]-1,itime)) : vfloat4(inf);
431
const vfloat4 l3 = (leftExists & (1<<3)) ? vfloat4::loadu(geom->vertexPtr(v0[3]-1,itime)) : vfloat4(inf);
432
transpose(l0,l1,l2,l3,pL.x,pL.y,pL.z,pL.w);
433
434
const vfloat4 r0 = (rightExists & (1<<0)) ? vfloat4::loadu(geom->vertexPtr(v0[0]+2,itime)) : vfloat4(inf);
435
const vfloat4 r1 = (rightExists & (1<<1)) ? vfloat4::loadu(geom->vertexPtr(v0[1]+2,itime)) : vfloat4(inf);
436
const vfloat4 r2 = (rightExists & (1<<2)) ? vfloat4::loadu(geom->vertexPtr(v0[2]+2,itime)) : vfloat4(inf);
437
const vfloat4 r3 = (rightExists & (1<<3)) ? vfloat4::loadu(geom->vertexPtr(v0[3]+2,itime)) : vfloat4(inf);
438
transpose(r0,r1,r2,r3,pR.x,pR.y,pR.z,pR.w);
439
}
440
441
template<>
442
__forceinline void LineMi<4>::gather(Vec4vf4& p0,
443
Vec4vf4& p1,
444
Vec4vf4& pL,
445
Vec4vf4& pR,
446
const LineSegments* geom,
447
float time) const
448
{
449
float ftime;
450
const int itime = geom->timeSegment(time, ftime);
451
452
Vec4vf4 a0,a1,aL,aR;
453
gatheri(a0,a1,aL,aR,geom,itime);
454
Vec4vf4 b0,b1,bL,bR;
455
gatheri(b0,b1,bL,bR,geom,itime+1);
456
p0 = lerp(a0,b0,vfloat4(ftime));
457
p1 = lerp(a1,b1,vfloat4(ftime));
458
pL = lerp(aL,bL,vfloat4(ftime));
459
pR = lerp(aR,bR,vfloat4(ftime));
460
461
pL = select(vboolf4(leftExists), pL, Vec4vf4(inf));
462
pR = select(vboolf4(rightExists), pR, Vec4vf4(inf));
463
}
464
465
#if defined(__AVX__)
466
467
template<>
468
__forceinline void LineMi<8>::gather(Vec4vf8& p0,
469
Vec4vf8& p1,
470
const LineSegments* geom) const
471
{
472
const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(v0[0]));
473
const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(v0[1]));
474
const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(v0[2]));
475
const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(v0[3]));
476
const vfloat4 a4 = vfloat4::loadu(geom->vertexPtr(v0[4]));
477
const vfloat4 a5 = vfloat4::loadu(geom->vertexPtr(v0[5]));
478
const vfloat4 a6 = vfloat4::loadu(geom->vertexPtr(v0[6]));
479
const vfloat4 a7 = vfloat4::loadu(geom->vertexPtr(v0[7]));
480
transpose(a0,a1,a2,a3,a4,a5,a6,a7,p0.x,p0.y,p0.z,p0.w);
481
482
const vfloat4 b0 = vfloat4::loadu(geom->vertexPtr(v0[0]+1));
483
const vfloat4 b1 = vfloat4::loadu(geom->vertexPtr(v0[1]+1));
484
const vfloat4 b2 = vfloat4::loadu(geom->vertexPtr(v0[2]+1));
485
const vfloat4 b3 = vfloat4::loadu(geom->vertexPtr(v0[3]+1));
486
const vfloat4 b4 = vfloat4::loadu(geom->vertexPtr(v0[4]+1));
487
const vfloat4 b5 = vfloat4::loadu(geom->vertexPtr(v0[5]+1));
488
const vfloat4 b6 = vfloat4::loadu(geom->vertexPtr(v0[6]+1));
489
const vfloat4 b7 = vfloat4::loadu(geom->vertexPtr(v0[7]+1));
490
transpose(b0,b1,b2,b3,b4,b5,b6,b7,p1.x,p1.y,p1.z,p1.w);
491
}
492
493
template<>
494
__forceinline void LineMi<8>::gatheri(Vec4vf8& p0,
495
Vec4vf8& p1,
496
const LineSegments* geom,
497
const int itime) const
498
{
499
const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(v0[0],itime));
500
const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(v0[1],itime));
501
const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(v0[2],itime));
502
const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(v0[3],itime));
503
const vfloat4 a4 = vfloat4::loadu(geom->vertexPtr(v0[4],itime));
504
const vfloat4 a5 = vfloat4::loadu(geom->vertexPtr(v0[5],itime));
505
const vfloat4 a6 = vfloat4::loadu(geom->vertexPtr(v0[6],itime));
506
const vfloat4 a7 = vfloat4::loadu(geom->vertexPtr(v0[7],itime));
507
transpose(a0,a1,a2,a3,a4,a5,a6,a7,p0.x,p0.y,p0.z,p0.w);
508
509
const vfloat4 b0 = vfloat4::loadu(geom->vertexPtr(v0[0]+1,itime));
510
const vfloat4 b1 = vfloat4::loadu(geom->vertexPtr(v0[1]+1,itime));
511
const vfloat4 b2 = vfloat4::loadu(geom->vertexPtr(v0[2]+1,itime));
512
const vfloat4 b3 = vfloat4::loadu(geom->vertexPtr(v0[3]+1,itime));
513
const vfloat4 b4 = vfloat4::loadu(geom->vertexPtr(v0[4]+1,itime));
514
const vfloat4 b5 = vfloat4::loadu(geom->vertexPtr(v0[5]+1,itime));
515
const vfloat4 b6 = vfloat4::loadu(geom->vertexPtr(v0[6]+1,itime));
516
const vfloat4 b7 = vfloat4::loadu(geom->vertexPtr(v0[7]+1,itime));
517
transpose(b0,b1,b2,b3,b4,b5,b6,b7,p1.x,p1.y,p1.z,p1.w);
518
}
519
520
template<>
521
__forceinline void LineMi<8>::gather(Vec4vf8& p0,
522
Vec4vf8& p1,
523
const LineSegments* geom,
524
float time) const
525
{
526
float ftime;
527
const int itime = geom->timeSegment(time, ftime);
528
529
Vec4vf8 a0,a1;
530
gatheri(a0,a1,geom,itime);
531
Vec4vf8 b0,b1;
532
gatheri(b0,b1,geom,itime+1);
533
p0 = lerp(a0,b0,vfloat8(ftime));
534
p1 = lerp(a1,b1,vfloat8(ftime));
535
}
536
537
template<>
538
__forceinline void LineMi<8>::gather(Vec4vf8& p0,
539
Vec4vf8& p1,
540
Vec4vf8& pL,
541
Vec4vf8& pR,
542
const LineSegments* geom) const
543
{
544
const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(v0[0]));
545
const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(v0[1]));
546
const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(v0[2]));
547
const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(v0[3]));
548
const vfloat4 a4 = vfloat4::loadu(geom->vertexPtr(v0[4]));
549
const vfloat4 a5 = vfloat4::loadu(geom->vertexPtr(v0[5]));
550
const vfloat4 a6 = vfloat4::loadu(geom->vertexPtr(v0[6]));
551
const vfloat4 a7 = vfloat4::loadu(geom->vertexPtr(v0[7]));
552
transpose(a0,a1,a2,a3,a4,a5,a6,a7,p0.x,p0.y,p0.z,p0.w);
553
554
const vfloat4 b0 = vfloat4::loadu(geom->vertexPtr(v0[0]+1));
555
const vfloat4 b1 = vfloat4::loadu(geom->vertexPtr(v0[1]+1));
556
const vfloat4 b2 = vfloat4::loadu(geom->vertexPtr(v0[2]+1));
557
const vfloat4 b3 = vfloat4::loadu(geom->vertexPtr(v0[3]+1));
558
const vfloat4 b4 = vfloat4::loadu(geom->vertexPtr(v0[4]+1));
559
const vfloat4 b5 = vfloat4::loadu(geom->vertexPtr(v0[5]+1));
560
const vfloat4 b6 = vfloat4::loadu(geom->vertexPtr(v0[6]+1));
561
const vfloat4 b7 = vfloat4::loadu(geom->vertexPtr(v0[7]+1));
562
transpose(b0,b1,b2,b3,b4,b5,b6,b7,p1.x,p1.y,p1.z,p1.w);
563
564
const vfloat4 l0 = (leftExists & (1<<0)) ? vfloat4::loadu(geom->vertexPtr(v0[0]-1)) : vfloat4(inf);
565
const vfloat4 l1 = (leftExists & (1<<1)) ? vfloat4::loadu(geom->vertexPtr(v0[1]-1)) : vfloat4(inf);
566
const vfloat4 l2 = (leftExists & (1<<2)) ? vfloat4::loadu(geom->vertexPtr(v0[2]-1)) : vfloat4(inf);
567
const vfloat4 l3 = (leftExists & (1<<3)) ? vfloat4::loadu(geom->vertexPtr(v0[3]-1)) : vfloat4(inf);
568
const vfloat4 l4 = (leftExists & (1<<4)) ? vfloat4::loadu(geom->vertexPtr(v0[4]-1)) : vfloat4(inf);
569
const vfloat4 l5 = (leftExists & (1<<5)) ? vfloat4::loadu(geom->vertexPtr(v0[5]-1)) : vfloat4(inf);
570
const vfloat4 l6 = (leftExists & (1<<6)) ? vfloat4::loadu(geom->vertexPtr(v0[6]-1)) : vfloat4(inf);
571
const vfloat4 l7 = (leftExists & (1<<7)) ? vfloat4::loadu(geom->vertexPtr(v0[7]-1)) : vfloat4(inf);
572
transpose(l0,l1,l2,l3,l4,l5,l6,l7,pL.x,pL.y,pL.z,pL.w);
573
574
const vfloat4 r0 = (rightExists & (1<<0)) ? vfloat4::loadu(geom->vertexPtr(v0[0]+2)) : vfloat4(inf);
575
const vfloat4 r1 = (rightExists & (1<<1)) ? vfloat4::loadu(geom->vertexPtr(v0[1]+2)) : vfloat4(inf);
576
const vfloat4 r2 = (rightExists & (1<<2)) ? vfloat4::loadu(geom->vertexPtr(v0[2]+2)) : vfloat4(inf);
577
const vfloat4 r3 = (rightExists & (1<<3)) ? vfloat4::loadu(geom->vertexPtr(v0[3]+2)) : vfloat4(inf);
578
const vfloat4 r4 = (rightExists & (1<<4)) ? vfloat4::loadu(geom->vertexPtr(v0[4]+2)) : vfloat4(inf);
579
const vfloat4 r5 = (rightExists & (1<<5)) ? vfloat4::loadu(geom->vertexPtr(v0[5]+2)) : vfloat4(inf);
580
const vfloat4 r6 = (rightExists & (1<<6)) ? vfloat4::loadu(geom->vertexPtr(v0[6]+2)) : vfloat4(inf);
581
const vfloat4 r7 = (rightExists & (1<<7)) ? vfloat4::loadu(geom->vertexPtr(v0[7]+2)) : vfloat4(inf);
582
transpose(r0,r1,r2,r3,r4,r5,r6,r7,pR.x,pR.y,pR.z,pR.w);
583
}
584
585
template<>
586
__forceinline void LineMi<8>::gatheri(Vec4vf8& p0,
587
Vec4vf8& p1,
588
Vec4vf8& pL,
589
Vec4vf8& pR,
590
const LineSegments* geom,
591
const int itime) const
592
{
593
const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(v0[0],itime));
594
const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(v0[1],itime));
595
const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(v0[2],itime));
596
const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(v0[3],itime));
597
const vfloat4 a4 = vfloat4::loadu(geom->vertexPtr(v0[4],itime));
598
const vfloat4 a5 = vfloat4::loadu(geom->vertexPtr(v0[5],itime));
599
const vfloat4 a6 = vfloat4::loadu(geom->vertexPtr(v0[6],itime));
600
const vfloat4 a7 = vfloat4::loadu(geom->vertexPtr(v0[7],itime));
601
transpose(a0,a1,a2,a3,a4,a5,a6,a7,p0.x,p0.y,p0.z,p0.w);
602
603
const vfloat4 b0 = vfloat4::loadu(geom->vertexPtr(v0[0]+1,itime));
604
const vfloat4 b1 = vfloat4::loadu(geom->vertexPtr(v0[1]+1,itime));
605
const vfloat4 b2 = vfloat4::loadu(geom->vertexPtr(v0[2]+1,itime));
606
const vfloat4 b3 = vfloat4::loadu(geom->vertexPtr(v0[3]+1,itime));
607
const vfloat4 b4 = vfloat4::loadu(geom->vertexPtr(v0[4]+1,itime));
608
const vfloat4 b5 = vfloat4::loadu(geom->vertexPtr(v0[5]+1,itime));
609
const vfloat4 b6 = vfloat4::loadu(geom->vertexPtr(v0[6]+1,itime));
610
const vfloat4 b7 = vfloat4::loadu(geom->vertexPtr(v0[7]+1,itime));
611
transpose(b0,b1,b2,b3,b4,b5,b6,b7,p1.x,p1.y,p1.z,p1.w);
612
613
const vfloat4 l0 = (leftExists & (1<<0)) ? vfloat4::loadu(geom->vertexPtr(v0[0]-1,itime)) : vfloat4(inf);
614
const vfloat4 l1 = (leftExists & (1<<1)) ? vfloat4::loadu(geom->vertexPtr(v0[1]-1,itime)) : vfloat4(inf);
615
const vfloat4 l2 = (leftExists & (1<<2)) ? vfloat4::loadu(geom->vertexPtr(v0[2]-1,itime)) : vfloat4(inf);
616
const vfloat4 l3 = (leftExists & (1<<3)) ? vfloat4::loadu(geom->vertexPtr(v0[3]-1,itime)) : vfloat4(inf);
617
const vfloat4 l4 = (leftExists & (1<<4)) ? vfloat4::loadu(geom->vertexPtr(v0[4]-1,itime)) : vfloat4(inf);
618
const vfloat4 l5 = (leftExists & (1<<5)) ? vfloat4::loadu(geom->vertexPtr(v0[5]-1,itime)) : vfloat4(inf);
619
const vfloat4 l6 = (leftExists & (1<<6)) ? vfloat4::loadu(geom->vertexPtr(v0[6]-1,itime)) : vfloat4(inf);
620
const vfloat4 l7 = (leftExists & (1<<7)) ? vfloat4::loadu(geom->vertexPtr(v0[7]-1,itime)) : vfloat4(inf);
621
transpose(l0,l1,l2,l3,l4,l5,l6,l7,pL.x,pL.y,pL.z,pL.w);
622
623
const vfloat4 r0 = (rightExists & (1<<0)) ? vfloat4::loadu(geom->vertexPtr(v0[0]+2,itime)) : vfloat4(inf);
624
const vfloat4 r1 = (rightExists & (1<<1)) ? vfloat4::loadu(geom->vertexPtr(v0[1]+2,itime)) : vfloat4(inf);
625
const vfloat4 r2 = (rightExists & (1<<2)) ? vfloat4::loadu(geom->vertexPtr(v0[2]+2,itime)) : vfloat4(inf);
626
const vfloat4 r3 = (rightExists & (1<<3)) ? vfloat4::loadu(geom->vertexPtr(v0[3]+2,itime)) : vfloat4(inf);
627
const vfloat4 r4 = (rightExists & (1<<4)) ? vfloat4::loadu(geom->vertexPtr(v0[4]+2,itime)) : vfloat4(inf);
628
const vfloat4 r5 = (rightExists & (1<<5)) ? vfloat4::loadu(geom->vertexPtr(v0[5]+2,itime)) : vfloat4(inf);
629
const vfloat4 r6 = (rightExists & (1<<6)) ? vfloat4::loadu(geom->vertexPtr(v0[6]+2,itime)) : vfloat4(inf);
630
const vfloat4 r7 = (rightExists & (1<<7)) ? vfloat4::loadu(geom->vertexPtr(v0[7]+2,itime)) : vfloat4(inf);
631
transpose(r0,r1,r2,r3,r4,r5,r6,r7,pR.x,pR.y,pR.z,pR.w);
632
}
633
634
template<>
635
__forceinline void LineMi<8>::gather(Vec4vf8& p0,
636
Vec4vf8& p1,
637
Vec4vf8& pL,
638
Vec4vf8& pR,
639
const LineSegments* geom,
640
float time) const
641
{
642
float ftime;
643
const int itime = geom->timeSegment(time, ftime);
644
645
Vec4vf8 a0,a1,aL,aR;
646
gatheri(a0,a1,aL,aR,geom,itime);
647
Vec4vf8 b0,b1,bL,bR;
648
gatheri(b0,b1,bL,bR,geom,itime+1);
649
p0 = lerp(a0,b0,vfloat8(ftime));
650
p1 = lerp(a1,b1,vfloat8(ftime));
651
pL = lerp(aL,bL,vfloat8(ftime));
652
pR = lerp(aR,bR,vfloat8(ftime));
653
654
pL = select(vboolf4(leftExists), pL, Vec4vf8(inf));
655
pR = select(vboolf4(rightExists), pR, Vec4vf8(inf));
656
}
657
658
template<>
659
__forceinline void LineMi<8>::gather(Vec4vf8& p0,
660
Vec4vf8& p1,
661
vbool8& cL,
662
vbool8& cR,
663
const LineSegments* geom) const
664
{
665
gather(p0,p1,geom);
666
cL = !vbool8(leftExists);
667
cR = !vbool8(rightExists);
668
}
669
670
template<>
671
__forceinline void LineMi<8>::gatheri(Vec4vf8& p0,
672
Vec4vf8& p1,
673
vbool8& cL,
674
vbool8& cR,
675
const LineSegments* geom,
676
const int itime) const
677
{
678
gatheri(p0,p1,geom,itime);
679
cL = !vbool8(leftExists);
680
cR = !vbool8(rightExists);
681
}
682
683
template<>
684
__forceinline void LineMi<8>::gather(Vec4vf8& p0,
685
Vec4vf8& p1,
686
vbool8& cL,
687
vbool8& cR,
688
const LineSegments* geom,
689
float time) const
690
{
691
float ftime;
692
const int itime = geom->timeSegment(time, ftime);
693
694
Vec4vf8 a0,a1;
695
gatheri(a0,a1,geom,itime);
696
Vec4vf8 b0,b1;
697
gatheri(b0,b1,geom,itime+1);
698
p0 = lerp(a0,b0,vfloat8(ftime));
699
p1 = lerp(a1,b1,vfloat8(ftime));
700
cL = !vbool8(leftExists);
701
cR = !vbool8(rightExists);
702
}
703
704
#endif
705
706
template<int M>
707
typename LineMi<M>::Type LineMi<M>::type;
708
709
typedef LineMi<4> Line4i;
710
typedef LineMi<8> Line8i;
711
}
712
713