Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/embree/kernels/geometry/pointi.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 PointMi
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
/* primitive supports multiple time segments */
25
static const bool singleTimeSegment = false;
26
27
/* Returns maximum number of stored line segments */
28
static __forceinline size_t max_size()
29
{
30
return M;
31
}
32
33
/* Returns required number of primitive blocks for N line segments */
34
static __forceinline size_t blocks(size_t N)
35
{
36
return (N + max_size() - 1) / max_size();
37
}
38
39
/* Returns required number of bytes for N line segments */
40
static __forceinline size_t bytes(size_t N)
41
{
42
return blocks(N) * sizeof(PointMi);
43
}
44
45
public:
46
/* Default constructor */
47
__forceinline PointMi() {}
48
49
/* Construction from vertices and IDs */
50
__forceinline PointMi(const vuint<M>& geomIDs, const vuint<M>& primIDs, Geometry::GType gtype, uint32_t numPrimitives)
51
: gtype((unsigned char)gtype),
52
numPrimitives(numPrimitives),
53
sharedGeomID(geomIDs[0]),
54
primIDs(primIDs)
55
{
56
assert(all(vuint<M>(geomID()) == geomIDs));
57
}
58
59
/* Returns a mask that tells which line segments are valid */
60
__forceinline vbool<M> valid() const {
61
return vint<M>(step) < vint<M>(numPrimitives);
62
}
63
64
/* Returns if the specified line segment is valid */
65
__forceinline bool valid(const size_t i) const
66
{
67
assert(i < M);
68
return i < numPrimitives;
69
}
70
71
/* Returns the number of stored line segments */
72
__forceinline size_t size() const {
73
return numPrimitives;
74
}
75
76
__forceinline unsigned int geomID(unsigned int i = 0) const {
77
return sharedGeomID;
78
}
79
80
__forceinline vuint<M>& primID() {
81
return primIDs;
82
}
83
__forceinline const vuint<M>& primID() const {
84
return primIDs;
85
}
86
__forceinline unsigned int primID(const size_t i) const {
87
assert(i < M);
88
return primIDs[i];
89
}
90
91
/* gather the line segments */
92
__forceinline void gather(Vec4vf<M>& p0, const Points* geom) const;
93
__forceinline void gather(Vec4vf<M>& p0, Vec3vf<M>& n0, const Points* geom) const;
94
95
__forceinline void gatheri(Vec4vf<M>& p0, const Points* geom, const int itime) const;
96
__forceinline void gatheri(Vec4vf<M>& p0, Vec3vf<M>& n0, const Points* geom, const int itime) const;
97
98
__forceinline void gather(Vec4vf<M>& p0, const Points* geom, float time) const;
99
__forceinline void gather(Vec4vf<M>& p0, Vec3vf<M>& n0, const Points* geom, float time) const;
100
101
/* Calculate the bounds of the line segments */
102
__forceinline const BBox3fa bounds(const Scene* scene, size_t itime = 0) const
103
{
104
BBox3fa bounds = empty;
105
for (size_t i = 0; i < M && valid(i); i++) {
106
const Points* geom = scene->get<Points>(geomID(i));
107
bounds.extend(geom->bounds(primID(i),itime));
108
}
109
return bounds;
110
}
111
112
/* Calculate the linear bounds of the primitive */
113
__forceinline LBBox3fa linearBounds(const Scene* scene, size_t itime) {
114
return LBBox3fa(bounds(scene, itime + 0), bounds(scene, itime + 1));
115
}
116
117
__forceinline LBBox3fa linearBounds(const Scene* const scene, size_t itime, size_t numTimeSteps)
118
{
119
LBBox3fa allBounds = empty;
120
for (size_t i = 0; i < M && valid(i); i++) {
121
const Points* geom = scene->get<Points>(geomID(i));
122
allBounds.extend(geom->linearBounds(primID(i), itime, numTimeSteps));
123
}
124
return allBounds;
125
}
126
127
__forceinline LBBox3fa linearBounds(const Scene* const scene, const BBox1f time_range)
128
{
129
LBBox3fa allBounds = empty;
130
for (size_t i = 0; i < M && valid(i); i++) {
131
const Points* geom = scene->get<Points>(geomID((unsigned int)i));
132
allBounds.extend(geom->linearBounds(primID(i), time_range));
133
}
134
return allBounds;
135
}
136
137
/* Fill line segment from line segment list */
138
template<typename PrimRefT>
139
__forceinline void fill(const PrimRefT* prims, size_t& begin, size_t end, Scene* scene)
140
{
141
Geometry::GType gty = scene->get(prims[begin].geomID())->getType();
142
vuint<M> geomID, primID;
143
vuint<M> v0;
144
const PrimRefT* prim = &prims[begin];
145
146
int numPrimitives = 0;
147
for (size_t i = 0; i < M; i++) {
148
if (begin < end) {
149
geomID[i] = prim->geomID();
150
primID[i] = prim->primID();
151
begin++;
152
numPrimitives++;
153
} else {
154
assert(i);
155
if (i > 0) {
156
geomID[i] = geomID[i - 1];
157
primID[i] = primID[i - 1];
158
}
159
}
160
if (begin < end)
161
prim = &prims[begin]; // FIXME: remove this line
162
}
163
new (this) PointMi(geomID, primID, gty, numPrimitives); // FIXME: use non temporal store
164
}
165
166
template<typename BVH, typename Allocator>
167
__forceinline static typename BVH::NodeRef createLeaf(BVH* bvh,
168
const PrimRef* prims,
169
const range<size_t>& set,
170
const Allocator& alloc)
171
{
172
size_t start = set.begin();
173
size_t items = PointMi::blocks(set.size());
174
size_t numbytes = PointMi::bytes(set.size());
175
PointMi* accel = (PointMi*)alloc.malloc1(numbytes, M * sizeof(float));
176
for (size_t i = 0; i < items; i++) {
177
accel[i].fill(prims, start, set.end(), bvh->scene);
178
}
179
return bvh->encodeLeaf((char*)accel, items);
180
};
181
182
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime)
183
{
184
fill(prims, begin, end, scene);
185
return linearBounds(scene, itime);
186
}
187
188
__forceinline LBBox3fa fillMB(
189
const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range)
190
{
191
fill(prims, begin, end, scene);
192
return linearBounds(scene, time_range);
193
}
194
195
template<typename BVH, typename SetMB, typename Allocator>
196
__forceinline static typename BVH::NodeRecordMB4D createLeafMB(BVH* bvh, const SetMB& prims, const Allocator& alloc)
197
{
198
size_t start = prims.object_range.begin();
199
size_t end = prims.object_range.end();
200
size_t items = PointMi::blocks(prims.object_range.size());
201
size_t numbytes = PointMi::bytes(prims.object_range.size());
202
PointMi* accel = (PointMi*)alloc.malloc1(numbytes, M * sizeof(float));
203
const typename BVH::NodeRef node = bvh->encodeLeaf((char*)accel, items);
204
205
LBBox3fa bounds = empty;
206
for (size_t i = 0; i < items; i++)
207
bounds.extend(accel[i].fillMB(prims.prims->data(), start, end, bvh->scene, prims.time_range));
208
209
return typename BVH::NodeRecordMB4D(node, bounds, prims.time_range);
210
};
211
212
/*! output operator */
213
friend __forceinline embree_ostream operator<<(embree_ostream cout, const PointMi& point)
214
{
215
return cout << "Point" << M << "i {" << point.geomID() << ", " << point.primID() << "}";
216
}
217
218
public:
219
unsigned char gtype;
220
unsigned char numPrimitives;
221
unsigned int sharedGeomID;
222
223
private:
224
vuint<M> primIDs; // primitive ID
225
};
226
227
template<>
228
__forceinline void PointMi<4>::gather(Vec4vf4& p0, const Points* geom) const
229
{
230
const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(primID(0)));
231
const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(primID(1)));
232
const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(primID(2)));
233
const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(primID(3)));
234
transpose(a0, a1, a2, a3, p0.x, p0.y, p0.z, p0.w);
235
}
236
237
template<>
238
__forceinline void PointMi<4>::gather(Vec4vf4& p0, Vec3vf4& n0, const Points* geom) const
239
{
240
const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(primID(0)));
241
const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(primID(1)));
242
const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(primID(2)));
243
const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(primID(3)));
244
transpose(a0, a1, a2, a3, p0.x, p0.y, p0.z, p0.w);
245
const vfloat4 b0 = vfloat4(geom->normal(primID(0)));
246
const vfloat4 b1 = vfloat4(geom->normal(primID(1)));
247
const vfloat4 b2 = vfloat4(geom->normal(primID(2)));
248
const vfloat4 b3 = vfloat4(geom->normal(primID(3)));
249
transpose(b0, b1, b2, b3, n0.x, n0.y, n0.z);
250
}
251
252
template<>
253
__forceinline void PointMi<4>::gatheri(Vec4vf4& p0, const Points* geom, const int itime) const
254
{
255
const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(primID(0), itime));
256
const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(primID(1), itime));
257
const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(primID(2), itime));
258
const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(primID(3), itime));
259
transpose(a0, a1, a2, a3, p0.x, p0.y, p0.z, p0.w);
260
}
261
262
template<>
263
__forceinline void PointMi<4>::gatheri(Vec4vf4& p0, Vec3vf4& n0, const Points* geom, const int itime) const
264
{
265
const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(primID(0), itime));
266
const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(primID(1), itime));
267
const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(primID(2), itime));
268
const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(primID(3), itime));
269
transpose(a0, a1, a2, a3, p0.x, p0.y, p0.z, p0.w);
270
const vfloat4 b0 = vfloat4(geom->normal((size_t)primID(0), (size_t)itime));
271
const vfloat4 b1 = vfloat4(geom->normal((size_t)primID(1), (size_t)itime));
272
const vfloat4 b2 = vfloat4(geom->normal((size_t)primID(2), (size_t)itime));
273
const vfloat4 b3 = vfloat4(geom->normal((size_t)primID(3), (size_t)itime));
274
transpose(b0, b1, b2, b3, n0.x, n0.y, n0.z);
275
}
276
277
template<>
278
__forceinline void PointMi<4>::gather(Vec4vf4& p0, const Points* geom, float time) const
279
{
280
float ftime;
281
const int itime = geom->timeSegment(time, ftime);
282
283
Vec4vf4 a0; gatheri(a0, geom, itime);
284
Vec4vf4 b0; gatheri(b0, geom, itime + 1);
285
p0 = lerp(a0, b0, vfloat4(ftime));
286
}
287
288
template<>
289
__forceinline void PointMi<4>::gather(Vec4vf4& p0, Vec3vf4& n0, const Points* geom, float time) const
290
{
291
float ftime;
292
const int itime = geom->timeSegment(time, ftime);
293
294
Vec4vf4 a0, b0;
295
Vec3vf4 norm0, norm1;
296
gatheri(a0, norm0, geom, itime);
297
gatheri(b0, norm1, geom, itime + 1);
298
p0 = lerp(a0, b0, vfloat4(ftime));
299
n0 = lerp(norm0, norm1, vfloat4(ftime));
300
}
301
302
#if defined(__AVX__)
303
304
template<>
305
__forceinline void PointMi<8>::gather(Vec4vf8& p0, const Points* geom) const
306
{
307
const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(primID(0)));
308
const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(primID(1)));
309
const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(primID(2)));
310
const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(primID(3)));
311
const vfloat4 a4 = vfloat4::loadu(geom->vertexPtr(primID(4)));
312
const vfloat4 a5 = vfloat4::loadu(geom->vertexPtr(primID(5)));
313
const vfloat4 a6 = vfloat4::loadu(geom->vertexPtr(primID(6)));
314
const vfloat4 a7 = vfloat4::loadu(geom->vertexPtr(primID(7)));
315
transpose(a0, a1, a2, a3, a4, a5, a6, a7, p0.x, p0.y, p0.z, p0.w);
316
}
317
318
template<>
319
__forceinline void PointMi<8>::gather(Vec4vf8& p0, Vec3vf8& n0, const Points* geom) const
320
{
321
const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(primID(0)));
322
const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(primID(1)));
323
const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(primID(2)));
324
const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(primID(3)));
325
const vfloat4 a4 = vfloat4::loadu(geom->vertexPtr(primID(4)));
326
const vfloat4 a5 = vfloat4::loadu(geom->vertexPtr(primID(5)));
327
const vfloat4 a6 = vfloat4::loadu(geom->vertexPtr(primID(6)));
328
const vfloat4 a7 = vfloat4::loadu(geom->vertexPtr(primID(7)));
329
transpose(a0, a1, a2, a3, a4, a5, a6, a7, p0.x, p0.y, p0.z, p0.w);
330
const vfloat4 b0 = vfloat4(geom->normal(primID(0)));
331
const vfloat4 b1 = vfloat4(geom->normal(primID(1)));
332
const vfloat4 b2 = vfloat4(geom->normal(primID(2)));
333
const vfloat4 b3 = vfloat4(geom->normal(primID(3)));
334
const vfloat4 b4 = vfloat4(geom->normal(primID(4)));
335
const vfloat4 b5 = vfloat4(geom->normal(primID(5)));
336
const vfloat4 b6 = vfloat4(geom->normal(primID(6)));
337
const vfloat4 b7 = vfloat4(geom->normal(primID(7)));
338
transpose(b0, b1, b2, b3, b4, b5, b6, b7, n0.x, n0.y, n0.z);
339
}
340
341
template<>
342
__forceinline void PointMi<8>::gatheri(Vec4vf8& p0, const Points* geom, const int itime) const
343
{
344
const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(primID(0), itime));
345
const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(primID(1), itime));
346
const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(primID(2), itime));
347
const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(primID(3), itime));
348
const vfloat4 a4 = vfloat4::loadu(geom->vertexPtr(primID(4), itime));
349
const vfloat4 a5 = vfloat4::loadu(geom->vertexPtr(primID(5), itime));
350
const vfloat4 a6 = vfloat4::loadu(geom->vertexPtr(primID(6), itime));
351
const vfloat4 a7 = vfloat4::loadu(geom->vertexPtr(primID(7), itime));
352
transpose(a0, a1, a2, a3, a4, a5, a6, a7, p0.x, p0.y, p0.z, p0.w);
353
}
354
355
template<>
356
__forceinline void PointMi<8>::gatheri(Vec4vf8& p0, Vec3vf8& n0, const Points* geom, const int itime) const
357
{
358
const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(primID(0), itime));
359
const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(primID(1), itime));
360
const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(primID(2), itime));
361
const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(primID(3), itime));
362
const vfloat4 a4 = vfloat4::loadu(geom->vertexPtr(primID(4), itime));
363
const vfloat4 a5 = vfloat4::loadu(geom->vertexPtr(primID(5), itime));
364
const vfloat4 a6 = vfloat4::loadu(geom->vertexPtr(primID(6), itime));
365
const vfloat4 a7 = vfloat4::loadu(geom->vertexPtr(primID(7), itime));
366
transpose(a0, a1, a2, a3, a4, a5, a6, a7, p0.x, p0.y, p0.z, p0.w);
367
const vfloat4 b0 = vfloat4(geom->normal((size_t)primID(0), (size_t)itime));
368
const vfloat4 b1 = vfloat4(geom->normal((size_t)primID(1), (size_t)itime));
369
const vfloat4 b2 = vfloat4(geom->normal((size_t)primID(2), (size_t)itime));
370
const vfloat4 b3 = vfloat4(geom->normal((size_t)primID(3), (size_t)itime));
371
const vfloat4 b4 = vfloat4(geom->normal((size_t)primID(4), (size_t)itime));
372
const vfloat4 b5 = vfloat4(geom->normal((size_t)primID(5), (size_t)itime));
373
const vfloat4 b6 = vfloat4(geom->normal((size_t)primID(6), (size_t)itime));
374
const vfloat4 b7 = vfloat4(geom->normal((size_t)primID(7), (size_t)itime));
375
transpose(b0, b1, b2, b3, b4, b5, b6, b7, n0.x, n0.y, n0.z);
376
}
377
378
template<>
379
__forceinline void PointMi<8>::gather(Vec4vf8& p0, const Points* geom, float time) const
380
{
381
float ftime;
382
const int itime = geom->timeSegment(time, ftime);
383
384
Vec4vf8 a0;
385
gatheri(a0, geom, itime);
386
Vec4vf8 b0;
387
gatheri(b0, geom, itime + 1);
388
p0 = lerp(a0, b0, vfloat8(ftime));
389
}
390
391
template<>
392
__forceinline void PointMi<8>::gather(Vec4vf8& p0, Vec3vf8& n0, const Points* geom, float time) const
393
{
394
float ftime;
395
const int itime = geom->timeSegment(time, ftime);
396
397
Vec4vf8 a0, b0;
398
Vec3vf8 norm0, norm1;
399
gatheri(a0, norm0, geom, itime);
400
gatheri(b0, norm1, geom, itime + 1);
401
p0 = lerp(a0, b0, vfloat8(ftime));
402
n0 = lerp(norm0, norm1, vfloat8(ftime));
403
}
404
#endif
405
406
template<int M>
407
typename PointMi<M>::Type PointMi<M>::type;
408
409
typedef PointMi<4> Point4i;
410
typedef PointMi<8> Point8i;
411
412
} // namespace embree
413
414