Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/embree/kernels/common/scene_line_segments.h
9905 views
1
// Copyright 2009-2021 Intel Corporation
2
// SPDX-License-Identifier: Apache-2.0
3
4
#pragma once
5
6
#include "default.h"
7
#include "geometry.h"
8
#include "buffer.h"
9
10
namespace embree
11
{
12
/*! represents an array of line segments */
13
struct LineSegments : public Geometry
14
{
15
/*! type of this geometry */
16
static const Geometry::GTypeMask geom_type = Geometry::MTY_CURVE2;
17
18
public:
19
20
/*! line segments construction */
21
LineSegments (Device* device, Geometry::GType gtype);
22
23
public:
24
void setMask (unsigned mask);
25
void setNumTimeSteps (unsigned int numTimeSteps);
26
void setVertexAttributeCount (unsigned int N);
27
void setBuffer(RTCBufferType type, unsigned int slot, RTCFormat format, const Ref<Buffer>& buffer, size_t offset, size_t stride, unsigned int num);
28
void* getBufferData(RTCBufferType type, unsigned int slot, BufferDataPointerType pointerType);
29
void updateBuffer(RTCBufferType type, unsigned int slot);
30
void commit();
31
bool verify ();
32
void interpolate(const RTCInterpolateArguments* const args);
33
void setTessellationRate(float N);
34
void setMaxRadiusScale(float s);
35
void addElementsToCount (GeometryCounts & counts) const;
36
size_t getGeometryDataDeviceByteSize() const;
37
void convertToDeviceRepresentation(size_t offset, char* data_host, char* data_device) const;
38
39
template<int N>
40
void interpolate_impl(const RTCInterpolateArguments* const args)
41
{
42
unsigned int primID = args->primID;
43
float u = args->u;
44
RTCBufferType bufferType = args->bufferType;
45
unsigned int bufferSlot = args->bufferSlot;
46
float* P = args->P;
47
float* dPdu = args->dPdu;
48
float* ddPdudu = args->ddPdudu;
49
unsigned int valueCount = args->valueCount;
50
51
/* calculate base pointer and stride */
52
assert((bufferType == RTC_BUFFER_TYPE_VERTEX && bufferSlot < numTimeSteps) ||
53
(bufferType == RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE && bufferSlot <= vertexAttribs.size()));
54
const char* src = nullptr;
55
size_t stride = 0;
56
if (bufferType == RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE) {
57
src = vertexAttribs[bufferSlot].getPtr();
58
stride = vertexAttribs[bufferSlot].getStride();
59
} else {
60
src = vertices[bufferSlot].getPtr();
61
stride = vertices[bufferSlot].getStride();
62
}
63
64
for (unsigned int i=0; i<valueCount; i+=N)
65
{
66
const size_t ofs = i*sizeof(float);
67
const size_t segment = segments[primID];
68
const vbool<N> valid = vint<N>((int)i)+vint<N>(step) < vint<N>(int(valueCount));
69
const vfloat<N> p0 = mem<vfloat<N>>::loadu(valid,(float*)&src[(segment+0)*stride+ofs]);
70
const vfloat<N> p1 = mem<vfloat<N>>::loadu(valid,(float*)&src[(segment+1)*stride+ofs]);
71
if (P ) mem<vfloat<N>>::storeu(valid,P+i,lerp(p0,p1,u));
72
if (dPdu ) mem<vfloat<N>>::storeu(valid,dPdu+i,p1-p0);
73
if (ddPdudu) mem<vfloat<N>>::storeu(valid,dPdu+i,vfloat<N>(zero));
74
}
75
}
76
77
public:
78
79
/*! returns the number of vertices */
80
__forceinline size_t numVertices() const {
81
return vertices[0].size();
82
}
83
84
/*! returns the i'th segment */
85
__forceinline const unsigned int& segment(size_t i) const {
86
return segments[i];
87
}
88
89
#if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__)
90
/*! returns the i'th segment */
91
template<int M>
92
__forceinline const vuint<M> vsegment(const vuint<M>& i) const {
93
return segments[i.v];
94
}
95
#endif
96
97
/*! returns the segment to the left of the i'th segment */
98
__forceinline bool segmentLeftExists(size_t i) const {
99
assert (flags);
100
return (flags[i] & RTC_CURVE_FLAG_NEIGHBOR_LEFT) != 0;
101
}
102
103
/*! returns the segment to the right of the i'th segment */
104
__forceinline bool segmentRightExists(size_t i) const {
105
assert (flags);
106
return (flags[i] & RTC_CURVE_FLAG_NEIGHBOR_RIGHT) != 0;
107
}
108
109
/*! returns i'th vertex of the first time step */
110
__forceinline Vec3ff vertex(size_t i) const {
111
return vertices0[i];
112
}
113
114
/*! returns i'th vertex of the first time step */
115
__forceinline const char* vertexPtr(size_t i) const {
116
return vertices0.getPtr(i);
117
}
118
119
/*! returns i'th normal of the first time step */
120
__forceinline Vec3fa normal(size_t i) const {
121
return normals0[i];
122
}
123
124
/*! returns i'th radius of the first time step */
125
__forceinline float radius(size_t i) const {
126
return vertices0[i].w;
127
}
128
129
/*! returns i'th vertex of itime'th timestep */
130
__forceinline Vec3ff vertex(size_t i, size_t itime) const {
131
return vertices[itime][i];
132
}
133
134
/*! returns i'th vertex of itime'th timestep */
135
__forceinline const char* vertexPtr(size_t i, size_t itime) const {
136
return vertices[itime].getPtr(i);
137
}
138
139
/*! returns i'th normal of itime'th timestep */
140
__forceinline Vec3fa normal(size_t i, size_t itime) const {
141
return normals[itime][i];
142
}
143
144
/*! returns i'th radius of itime'th timestep */
145
__forceinline float radius(size_t i, size_t itime) const {
146
return vertices[itime][i].w;
147
}
148
149
/*! gathers the curve starting with i'th vertex */
150
__forceinline void gather(Vec3ff& p0, Vec3ff& p1, unsigned int vid) const
151
{
152
p0 = vertex(vid+0);
153
p1 = vertex(vid+1);
154
}
155
156
#if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__)
157
template<int M>
158
__forceinline void vgather(Vec4vf<M>& p0, Vec4vf<M>& p1, const vuint<M>& vid) const
159
{
160
p0 = vertex(vid.v+0);
161
p1 = vertex(vid.v+1);
162
}
163
#endif
164
165
/*! gathers the curve starting with i'th vertex of itime'th timestep */
166
__forceinline void gather(Vec3ff& p0, Vec3ff& p1, unsigned int vid, size_t itime) const
167
{
168
p0 = vertex(vid+0,itime);
169
p1 = vertex(vid+1,itime);
170
}
171
172
#if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__)
173
template<int M>
174
__forceinline void vgather(Vec4vf<M>& p0, Vec4vf<M>& p1, const vuint<M>& vid, const vint<M>& itime) const
175
{
176
p0 = vertex(vid.v+0,itime.v);
177
p1 = vertex(vid.v+1,itime.v);
178
}
179
#endif
180
181
/*! loads curve vertices for specified time */
182
__forceinline void gather(Vec3ff& p0, Vec3ff& p1, unsigned int vid, float time) const
183
{
184
float ftime;
185
const size_t itime = timeSegment(time, ftime);
186
187
const float t0 = 1.0f - ftime;
188
const float t1 = ftime;
189
Vec3ff a0,a1; gather(a0,a1,vid,itime);
190
Vec3ff b0,b1; gather(b0,b1,vid,itime+1);
191
p0 = madd(Vec3ff(t0),a0,t1*b0);
192
p1 = madd(Vec3ff(t0),a1,t1*b1);
193
}
194
195
/*! loads curve vertices for specified time for mblur and non-mblur case */
196
__forceinline void gather_safe(Vec3ff& p0, Vec3ff& p1, unsigned int vid, float time) const
197
{
198
if (hasMotionBlur()) gather(p0,p1,vid,time);
199
else gather(p0,p1,vid);
200
}
201
202
#if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__)
203
template<int M>
204
__forceinline void vgather(Vec4vf<M>& p0, Vec4vf<M>& p1, const vuint<M>& vid, const vfloat<M>& time) const
205
{
206
vfloat<M> ftime;
207
const vint<M> itime = timeSegment<M>(time, ftime);
208
209
const vfloat<M> t0 = 1.0f - ftime;
210
const vfloat<M> t1 = ftime;
211
Vec4vf<M> a0,a1; vgather<M>(a0,a1,vid,itime);
212
Vec4vf<M> b0,b1; vgather<M>(b0,b1,vid,itime+1);
213
p0 = madd(Vec4vf<M>(t0),a0,t1*b0);
214
p1 = madd(Vec4vf<M>(t0),a1,t1*b1);
215
}
216
#endif
217
218
/*! gathers the cone curve starting with i'th vertex */
219
__forceinline void gather(Vec3ff& p0, Vec3ff& p1, bool& cL, bool& cR, unsigned int primID, unsigned int vid) const
220
{
221
gather(p0,p1,vid);
222
cL = !segmentLeftExists (primID);
223
cR = !segmentRightExists(primID);
224
}
225
226
#if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__)
227
template<int M>
228
__forceinline void vgather(Vec4vf<M>& p0, Vec4vf<M>& p1, vbool<M>& cL, vbool<M>& cR, const vuint<M>& primID, const vuint<M>& vid) const
229
{
230
vgather<M>(p0,p1,vid);
231
cL = !segmentLeftExists (primID.v);
232
cR = !segmentRightExists(primID.v);
233
}
234
#endif
235
236
/*! gathers the cone curve starting with i'th vertex of itime'th timestep */
237
__forceinline void gather(Vec3ff& p0, Vec3ff& p1, bool& cL, bool& cR, unsigned int primID, size_t vid, size_t itime) const
238
{
239
gather(p0,p1,vid,itime);
240
cL = !segmentLeftExists (primID);
241
cR = !segmentRightExists(primID);
242
}
243
244
/*! loads cone curve vertices for specified time */
245
__forceinline void gather(Vec3ff& p0, Vec3ff& p1, bool& cL, bool& cR, unsigned int primID, size_t vid, float time) const
246
{
247
gather(p0,p1,vid,time);
248
cL = !segmentLeftExists (primID);
249
cR = !segmentRightExists(primID);
250
}
251
252
/*! loads cone curve vertices for specified time for mblur and non-mblur geometry */
253
__forceinline void gather_safe(Vec3ff& p0, Vec3ff& p1, bool& cL, bool& cR, unsigned int primID, size_t vid, float time) const
254
{
255
if (hasMotionBlur()) gather(p0,p1,cL,cR,primID,vid,time);
256
else gather(p0,p1,cL,cR,primID,vid);
257
}
258
259
#if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__)
260
template<int M>
261
__forceinline void vgather(Vec4vf<M>& p0, Vec4vf<M>& p1, vbool<M>& cL, vbool<M>& cR, const vuint<M>& primID, const vuint<M>& vid, const vfloat<M>& time) const
262
{
263
vgather<M>(p0,p1,vid,time);
264
cL = !segmentLeftExists (primID.v);
265
cR = !segmentRightExists(primID.v);
266
}
267
#endif
268
269
/*! gathers the curve starting with i'th vertex */
270
__forceinline void gather(Vec3ff& p0, Vec3ff& p1, Vec3ff& p2, Vec3ff& p3, unsigned int primID, size_t vid) const
271
{
272
p0 = vertex(vid+0);
273
p1 = vertex(vid+1);
274
p2 = segmentLeftExists (primID) ? vertex(vid-1) : Vec3ff(inf);
275
p3 = segmentRightExists(primID) ? vertex(vid+2) : Vec3ff(inf);
276
}
277
278
#if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__)
279
template<int M>
280
__forceinline void vgather(Vec4vf<M>& p0, Vec4vf<M>& p1, Vec4vf<M>& p2, Vec4vf<M>& p3, const vuint<M>& primID, const vuint<M>& vid) const
281
{
282
p0 = vertex(vid.v+0);
283
p1 = vertex(vid.v+1);
284
vbool<M> left = segmentLeftExists (primID.v);
285
vbool<M> right = segmentRightExists(primID.v);
286
vuint<M> i2 = select(left, vid-1,vid+0);
287
vuint<M> i3 = select(right,vid+2,vid+1);
288
p2 = vertex(i2.v);
289
p3 = vertex(i3.v);
290
p2 = select(left, p2,Vec4vf<M>(inf));
291
p3 = select(right,p3,Vec4vf<M>(inf));
292
}
293
#endif
294
295
/*! gathers the curve starting with i'th vertex of itime'th timestep */
296
__forceinline void gather(Vec3ff& p0, Vec3ff& p1, Vec3ff& p2, Vec3ff& p3, unsigned int primID, size_t vid, size_t itime) const
297
{
298
p0 = vertex(vid+0,itime);
299
p1 = vertex(vid+1,itime);
300
p2 = segmentLeftExists (primID) ? vertex(vid-1,itime) : Vec3ff(inf);
301
p3 = segmentRightExists(primID) ? vertex(vid+2,itime) : Vec3ff(inf);
302
}
303
304
#if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__)
305
template<int M>
306
__forceinline void vgather(Vec4vf<M>& p0, Vec4vf<M>& p1, Vec4vf<M>& p2, Vec4vf<M>& p3, const vuint<M>& primID, const vuint<M>& vid, const vint<M>& itime) const
307
{
308
p0 = vertex(vid.v+0, itime.v);
309
p1 = vertex(vid.v+1, itime.v);
310
vbool<M> left = segmentLeftExists (primID.v);
311
vbool<M> right = segmentRightExists(primID.v);
312
vuint<M> i2 = select(left, vid-1,vid+0);
313
vuint<M> i3 = select(right,vid+2,vid+1);
314
p2 = vertex(i2.v, itime.v);
315
p3 = vertex(i3.v, itime.v);
316
p2 = select(left, p2,Vec4vf<M>(inf));
317
p3 = select(right,p3,Vec4vf<M>(inf));
318
}
319
#endif
320
321
/*! loads curve vertices for specified time */
322
__forceinline void gather(Vec3ff& p0, Vec3ff& p1, Vec3ff& p2, Vec3ff& p3, unsigned int primID, size_t vid, float time) const
323
{
324
float ftime;
325
const size_t itime = timeSegment(time, ftime);
326
327
const float t0 = 1.0f - ftime;
328
const float t1 = ftime;
329
Vec3ff a0,a1,a2,a3; gather(a0,a1,a2,a3,primID,vid,itime);
330
Vec3ff b0,b1,b2,b3; gather(b0,b1,b2,b3,primID,vid,itime+1);
331
p0 = madd(Vec3ff(t0),a0,t1*b0);
332
p1 = madd(Vec3ff(t0),a1,t1*b1);
333
p2 = madd(Vec3ff(t0),a2,t1*b2);
334
p3 = madd(Vec3ff(t0),a3,t1*b3);
335
}
336
337
/*! loads curve vertices for specified time for mblur and non-mblur geometry */
338
__forceinline void gather_safe(Vec3ff& p0, Vec3ff& p1, Vec3ff& p2, Vec3ff& p3, unsigned int primID, size_t vid, float time) const
339
{
340
if (hasMotionBlur()) gather(p0,p1,p2,p3,primID,vid,time);
341
else gather(p0,p1,p2,p3,primID,vid);
342
}
343
344
#if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__)
345
template<int M>
346
__forceinline void vgather(Vec4vf<M>& p0, Vec4vf<M>& p1, Vec4vf<M>& p2, Vec4vf<M>& p3, const vuint<M>& primID, const vuint<M>& vid, const vfloat<M>& time) const
347
{
348
vfloat<M> ftime;
349
const vint<M> itime = timeSegment<M>(time, ftime);
350
351
const vfloat<M> t0 = 1.0f - ftime;
352
const vfloat<M> t1 = ftime;
353
Vec4vf<M> a0,a1,a2,a3; vgather<M>(a0,a1,a2,a3,primID,vid,itime);
354
Vec4vf<M> b0,b1,b2,b3; vgather<M>(b0,b1,b2,b3,primID,vid,itime+1);
355
p0 = madd(Vec4vf<M>(t0),a0,t1*b0);
356
p1 = madd(Vec4vf<M>(t0),a1,t1*b1);
357
p2 = madd(Vec4vf<M>(t0),a2,t1*b2);
358
p3 = madd(Vec4vf<M>(t0),a3,t1*b3);
359
}
360
#endif
361
362
/*! calculates bounding box of i'th line segment */
363
__forceinline BBox3fa bounds(const Vec3ff& v0, const Vec3ff& v1) const
364
{
365
const BBox3ff b = merge(BBox3ff(v0),BBox3ff(v1));
366
return enlarge((BBox3fa)b,maxRadiusScale*Vec3fa(max(v0.w,v1.w)));
367
}
368
369
/*! calculates bounding box of i'th line segment */
370
__forceinline BBox3fa bounds(size_t i) const
371
{
372
const unsigned int index = segment(i);
373
const Vec3ff v0 = vertex(index+0);
374
const Vec3ff v1 = vertex(index+1);
375
return bounds(v0,v1);
376
}
377
378
/*! calculates bounding box of i'th line segment for the itime'th time step */
379
__forceinline BBox3fa bounds(size_t i, size_t itime) const
380
{
381
const unsigned int index = segment(i);
382
const Vec3ff v0 = vertex(index+0,itime);
383
const Vec3ff v1 = vertex(index+1,itime);
384
return bounds(v0,v1);
385
}
386
387
/*! calculates bounding box of i'th line segment */
388
__forceinline BBox3fa bounds(const LinearSpace3fa& space, size_t i) const
389
{
390
const unsigned int index = segment(i);
391
const Vec3ff v0 = vertex(index+0);
392
const Vec3ff v1 = vertex(index+1);
393
const Vec3ff w0(xfmVector(space,(Vec3fa)v0),v0.w);
394
const Vec3ff w1(xfmVector(space,(Vec3fa)v1),v1.w);
395
return bounds(w0,w1);
396
}
397
398
/*! calculates bounding box of i'th line segment for the itime'th time step */
399
__forceinline BBox3fa bounds(const LinearSpace3fa& space, size_t i, size_t itime) const
400
{
401
const unsigned int index = segment(i);
402
const Vec3ff v0 = vertex(index+0,itime);
403
const Vec3ff v1 = vertex(index+1,itime);
404
const Vec3ff w0(xfmVector(space,(Vec3fa)v0),v0.w);
405
const Vec3ff w1(xfmVector(space,(Vec3fa)v1),v1.w);
406
return bounds(w0,w1);
407
}
408
409
/*! calculates bounding box of i'th segment */
410
__forceinline BBox3fa bounds(const Vec3fa& ofs, const float scale, const float r_scale0, const LinearSpace3fa& space, size_t i, size_t itime = 0) const
411
{
412
const float r_scale = r_scale0*scale;
413
const unsigned int index = segment(i);
414
const Vec3ff v0 = vertex(index+0,itime);
415
const Vec3ff v1 = vertex(index+1,itime);
416
const Vec3ff w0(xfmVector(space,(v0-ofs)*Vec3fa(scale)),maxRadiusScale*v0.w*r_scale);
417
const Vec3ff w1(xfmVector(space,(v1-ofs)*Vec3fa(scale)),maxRadiusScale*v1.w*r_scale);
418
return bounds(w0,w1);
419
}
420
421
/*! check if the i'th primitive is valid at the itime'th timestep */
422
__forceinline bool valid(size_t i, size_t itime) const {
423
return valid(i, make_range(itime, itime));
424
}
425
426
/*! check if the i'th primitive is valid between the specified time range */
427
__forceinline bool valid(size_t i, const range<size_t>& itime_range) const
428
{
429
const unsigned int index = segment(i);
430
if (index+1 >= numVertices()) return false;
431
432
#if !defined(__SYCL_DEVICE_ONLY__)
433
434
for (size_t itime = itime_range.begin(); itime <= itime_range.end(); itime++)
435
{
436
const Vec3ff v0 = vertex(index+0,itime); if (unlikely(!isvalid4(v0))) return false;
437
const Vec3ff v1 = vertex(index+1,itime); if (unlikely(!isvalid4(v1))) return false;
438
if (min(v0.w,v1.w) < 0.0f) return false;
439
}
440
#endif
441
442
return true;
443
}
444
445
/*! calculates the linear bounds of the i'th primitive at the itimeGlobal'th time segment */
446
__forceinline LBBox3fa linearBounds(size_t i, size_t itime) const {
447
return LBBox3fa(bounds(i,itime+0),bounds(i,itime+1));
448
}
449
450
/*! calculates the build bounds of the i'th primitive, if it's valid */
451
__forceinline bool buildBounds(size_t i, BBox3fa* bbox) const
452
{
453
if (!valid(i,0)) return false;
454
*bbox = bounds(i);
455
return true;
456
}
457
458
/*! calculates the build bounds of the i'th primitive at the itime'th time segment, if it's valid */
459
__forceinline bool buildBounds(size_t i, size_t itime, BBox3fa& bbox) const
460
{
461
if (!valid(i,itime+0) || !valid(i,itime+1)) return false;
462
bbox = bounds(i,itime); // use bounds of first time step in builder
463
return true;
464
}
465
466
/*! calculates the linear bounds of the i'th primitive for the specified time range */
467
__forceinline LBBox3fa linearBounds(size_t primID, const BBox1f& dt) const {
468
return LBBox3fa([&] (size_t itime) { return bounds(primID, itime); }, dt, time_range, fnumTimeSegments);
469
}
470
471
/*! calculates the linear bounds of the i'th primitive for the specified time range */
472
__forceinline LBBox3fa linearBounds(const LinearSpace3fa& space, size_t primID, const BBox1f& dt) const {
473
return LBBox3fa([&] (size_t itime) { return bounds(space, primID, itime); }, dt, time_range, fnumTimeSegments);
474
}
475
476
/*! calculates the linear bounds of the i'th primitive for the specified time range */
477
__forceinline LBBox3fa linearBounds(const Vec3fa& ofs, const float scale, const float r_scale0, const LinearSpace3fa& space, size_t primID, const BBox1f& dt) const {
478
return LBBox3fa([&] (size_t itime) { return bounds(ofs, scale, r_scale0, space, primID, itime); }, dt, this->time_range, fnumTimeSegments);
479
}
480
481
/*! calculates the linear bounds of the i'th primitive for the specified time range */
482
__forceinline bool linearBounds(size_t i, const BBox1f& time_range, LBBox3fa& bbox) const
483
{
484
if (!valid(i, timeSegmentRange(time_range))) return false;
485
bbox = linearBounds(i, time_range);
486
return true;
487
}
488
489
/*! get fast access to first vertex buffer */
490
__forceinline float * getCompactVertexArray () const {
491
return (float*) vertices0.getPtr();
492
}
493
494
public:
495
BufferView<unsigned int> segments; //!< array of line segment indices
496
BufferView<Vec3ff> vertices0; //!< fast access to first vertex buffer
497
BufferView<Vec3fa> normals0; //!< fast access to first normal buffer
498
BufferView<char> flags; //!< start, end flag per segment
499
Device::vector<BufferView<Vec3ff>> vertices = device; //!< vertex array for each timestep
500
Device::vector<BufferView<Vec3fa>> normals = device; //!< normal array for each timestep
501
Device::vector<BufferView<char>> vertexAttribs = device; //!< user buffers
502
int tessellationRate; //!< tessellation rate for bezier curve
503
float maxRadiusScale = 1.0; //!< maximal min-width scaling of curve radii
504
};
505
506
namespace isa
507
{
508
struct LineSegmentsISA : public LineSegments
509
{
510
LineSegmentsISA (Device* device, Geometry::GType gtype)
511
: LineSegments(device,gtype) {}
512
513
LinearSpace3fa computeAlignedSpace(const size_t primID) const
514
{
515
const Vec3fa dir = normalize(computeDirection(primID));
516
if (is_finite(dir)) return frame(dir);
517
else return LinearSpace3fa(one);
518
}
519
520
LinearSpace3fa computeAlignedSpaceMB(const size_t primID, const BBox1f time_range) const
521
{
522
Vec3fa axisz(0,0,1);
523
Vec3fa axisy(0,1,0);
524
525
const range<int> tbounds = this->timeSegmentRange(time_range);
526
if (tbounds.size() == 0) return frame(axisz);
527
528
const size_t itime = (tbounds.begin()+tbounds.end())/2;
529
530
const Vec3fa dir = normalize(computeDirection(primID,itime));
531
if (is_finite(dir)) return frame(dir);
532
else return LinearSpace3fa(one);
533
}
534
535
Vec3fa computeDirection(unsigned int primID) const
536
{
537
const unsigned vtxID = segment(primID);
538
const Vec3fa v0 = vertex(vtxID+0);
539
const Vec3fa v1 = vertex(vtxID+1);
540
return v1-v0;
541
}
542
543
Vec3fa computeDirection(unsigned int primID, size_t time) const
544
{
545
const unsigned vtxID = segment(primID);
546
const Vec3fa v0 = vertex(vtxID+0,time);
547
const Vec3fa v1 = vertex(vtxID+1,time);
548
return v1-v0;
549
}
550
551
PrimInfo createPrimRefArray(PrimRef* prims, const range<size_t>& r, size_t k, unsigned int geomID) const
552
{
553
PrimInfo pinfo(empty);
554
for (size_t j=r.begin(); j<r.end(); j++)
555
{
556
BBox3fa bounds = empty;
557
if (!buildBounds(j,&bounds)) continue;
558
const PrimRef prim(bounds,geomID,unsigned(j));
559
pinfo.add_center2(prim);
560
prims[k++] = prim;
561
}
562
return pinfo;
563
}
564
565
PrimInfo createPrimRefArrayMB(mvector<PrimRef>& prims, size_t itime, const range<size_t>& r, size_t k, unsigned int geomID) const
566
{
567
PrimInfo pinfo(empty);
568
for (size_t j=r.begin(); j<r.end(); j++)
569
{
570
BBox3fa bounds = empty;
571
if (!buildBounds(j,itime,bounds)) continue;
572
const PrimRef prim(bounds,geomID,unsigned(j));
573
pinfo.add_center2(prim);
574
prims[k++] = prim;
575
}
576
return pinfo;
577
}
578
579
PrimInfo createPrimRefArrayMB(PrimRef* prims, const BBox1f& time_range, const range<size_t>& r, size_t k, unsigned int geomID) const
580
{
581
PrimInfo pinfo(empty);
582
const BBox1f t0t1 = BBox1f::intersect(getTimeRange(), time_range);
583
if (t0t1.empty()) return pinfo;
584
585
for (size_t j = r.begin(); j < r.end(); j++) {
586
LBBox3fa lbounds = empty;
587
if (!linearBounds(j, t0t1, lbounds))
588
continue;
589
const PrimRef prim(lbounds.bounds(), geomID, unsigned(j));
590
pinfo.add_center2(prim);
591
prims[k++] = prim;
592
}
593
return pinfo;
594
}
595
596
PrimInfoMB createPrimRefMBArray(mvector<PrimRefMB>& prims, const BBox1f& t0t1, const range<size_t>& r, size_t k, unsigned int geomID) const
597
{
598
PrimInfoMB pinfo(empty);
599
for (size_t j=r.begin(); j<r.end(); j++)
600
{
601
if (!valid(j, timeSegmentRange(t0t1))) continue;
602
const PrimRefMB prim(linearBounds(j,t0t1),this->numTimeSegments(),this->time_range,this->numTimeSegments(),geomID,unsigned(j));
603
pinfo.add_primref(prim);
604
prims[k++] = prim;
605
}
606
return pinfo;
607
}
608
609
BBox3fa vbounds(size_t i) const {
610
return bounds(i);
611
}
612
613
BBox3fa vbounds(const LinearSpace3fa& space, size_t i) const {
614
return bounds(space,i);
615
}
616
617
BBox3fa vbounds(const Vec3fa& ofs, const float scale, const float r_scale0, const LinearSpace3fa& space, size_t i, size_t itime = 0) const {
618
return bounds(ofs,scale,r_scale0,space,i,itime);
619
}
620
621
LBBox3fa vlinearBounds(size_t primID, const BBox1f& time_range) const {
622
return linearBounds(primID,time_range);
623
}
624
625
LBBox3fa vlinearBounds(const LinearSpace3fa& space, size_t primID, const BBox1f& time_range) const {
626
return linearBounds(space,primID,time_range);
627
}
628
629
LBBox3fa vlinearBounds(const Vec3fa& ofs, const float scale, const float r_scale0, const LinearSpace3fa& space, size_t primID, const BBox1f& time_range) const {
630
return linearBounds(ofs,scale,r_scale0,space,primID,time_range);
631
}
632
};
633
}
634
635
DECLARE_ISA_FUNCTION(LineSegments*, createLineSegments, Device* COMMA Geometry::GType);
636
}
637
638