Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/embree/kernels/bvh/bvh_builder_morton.cpp
9906 views
1
// Copyright 2009-2021 Intel Corporation
2
// SPDX-License-Identifier: Apache-2.0
3
4
#include "bvh.h"
5
#include "bvh_statistics.h"
6
#include "bvh_rotate.h"
7
#include "../common/profile.h"
8
#include "../../common/algorithms/parallel_prefix_sum.h"
9
10
#include "../builders/primrefgen.h"
11
#include "../builders/bvh_builder_morton.h"
12
13
#include "../geometry/triangle.h"
14
#include "../geometry/trianglev.h"
15
#include "../geometry/trianglei.h"
16
#include "../geometry/quadv.h"
17
#include "../geometry/quadi.h"
18
#include "../geometry/object.h"
19
#include "../geometry/instance.h"
20
#include "../geometry/instance_array.h"
21
22
#if defined(__64BIT__)
23
# define ROTATE_TREE 1 // specifies number of tree rotation rounds to perform
24
#else
25
# define ROTATE_TREE 0 // do not use tree rotations on 32 bit platforms, barrier bit in NodeRef will cause issues
26
#endif
27
28
namespace embree
29
{
30
namespace isa
31
{
32
template<int N>
33
struct SetBVHNBounds
34
{
35
typedef BVHN<N> BVH;
36
typedef typename BVH::NodeRef NodeRef;
37
typedef typename BVH::NodeRecord NodeRecord;
38
typedef typename BVH::AABBNode AABBNode;
39
40
BVH* bvh;
41
__forceinline SetBVHNBounds (BVH* bvh) : bvh(bvh) {}
42
43
__forceinline NodeRecord operator() (NodeRef ref, const NodeRecord* children, size_t num)
44
{
45
AABBNode* node = ref.getAABBNode();
46
47
BBox3fa res = empty;
48
for (size_t i=0; i<num; i++) {
49
const BBox3fa b = children[i].bounds;
50
res.extend(b);
51
node->setRef(i,children[i].ref);
52
node->setBounds(i,b);
53
}
54
55
BBox3fx result = (BBox3fx&)res;
56
#if ROTATE_TREE
57
if (N == 4)
58
{
59
size_t n = 0;
60
for (size_t i=0; i<num; i++)
61
n += children[i].bounds.lower.a;
62
63
if (n >= 4096) {
64
for (size_t i=0; i<num; i++) {
65
if (children[i].bounds.lower.a < 4096) {
66
for (int j=0; j<ROTATE_TREE; j++)
67
BVHNRotate<N>::rotate(node->child(i));
68
node->child(i).setBarrier();
69
}
70
}
71
}
72
result.lower.a = unsigned(n);
73
}
74
#endif
75
76
return NodeRecord(ref,result);
77
}
78
};
79
80
template<int N, typename Primitive>
81
struct CreateMortonLeaf;
82
83
template<int N>
84
struct CreateMortonLeaf<N,Triangle4>
85
{
86
typedef BVHN<N> BVH;
87
typedef typename BVH::NodeRef NodeRef;
88
typedef typename BVH::NodeRecord NodeRecord;
89
90
__forceinline CreateMortonLeaf (TriangleMesh* mesh, unsigned int geomID, BVHBuilderMorton::BuildPrim* morton)
91
: mesh(mesh), morton(morton), geomID_(geomID) {}
92
93
__noinline NodeRecord operator() (const range<unsigned>& current, const FastAllocator::CachedAllocator& alloc)
94
{
95
vfloat4 lower(pos_inf);
96
vfloat4 upper(neg_inf);
97
size_t items = current.size();
98
size_t start = current.begin();
99
assert(items<=4);
100
101
/* allocate leaf node */
102
Triangle4* accel = (Triangle4*) alloc.malloc1(sizeof(Triangle4),BVH::byteAlignment);
103
NodeRef ref = BVH::encodeLeaf((char*)accel,1);
104
vuint4 vgeomID = -1, vprimID = -1;
105
Vec3vf4 v0 = zero, v1 = zero, v2 = zero;
106
const TriangleMesh* __restrict__ const mesh = this->mesh;
107
108
for (size_t i=0; i<items; i++)
109
{
110
const unsigned int primID = morton[start+i].index;
111
const TriangleMesh::Triangle& tri = mesh->triangle(primID);
112
const Vec3fa& p0 = mesh->vertex(tri.v[0]);
113
const Vec3fa& p1 = mesh->vertex(tri.v[1]);
114
const Vec3fa& p2 = mesh->vertex(tri.v[2]);
115
lower = min(lower,(vfloat4)p0,(vfloat4)p1,(vfloat4)p2);
116
upper = max(upper,(vfloat4)p0,(vfloat4)p1,(vfloat4)p2);
117
vgeomID [i] = geomID_;
118
vprimID [i] = primID;
119
v0.x[i] = p0.x; v0.y[i] = p0.y; v0.z[i] = p0.z;
120
v1.x[i] = p1.x; v1.y[i] = p1.y; v1.z[i] = p1.z;
121
v2.x[i] = p2.x; v2.y[i] = p2.y; v2.z[i] = p2.z;
122
}
123
124
Triangle4::store_nt(accel,Triangle4(v0,v1,v2,vgeomID,vprimID));
125
BBox3fx box_o = BBox3fx((Vec3fx)lower,(Vec3fx)upper);
126
#if ROTATE_TREE
127
if (N == 4)
128
box_o.lower.a = unsigned(current.size());
129
#endif
130
return NodeRecord(ref,box_o);
131
}
132
133
private:
134
TriangleMesh* mesh;
135
BVHBuilderMorton::BuildPrim* morton;
136
unsigned int geomID_ = std::numeric_limits<unsigned int>::max();
137
};
138
139
template<int N>
140
struct CreateMortonLeaf<N,Triangle4v>
141
{
142
typedef BVHN<N> BVH;
143
typedef typename BVH::NodeRef NodeRef;
144
typedef typename BVH::NodeRecord NodeRecord;
145
146
__forceinline CreateMortonLeaf (TriangleMesh* mesh, unsigned int geomID, BVHBuilderMorton::BuildPrim* morton)
147
: mesh(mesh), morton(morton), geomID_(geomID) {}
148
149
__noinline NodeRecord operator() (const range<unsigned>& current, const FastAllocator::CachedAllocator& alloc)
150
{
151
vfloat4 lower(pos_inf);
152
vfloat4 upper(neg_inf);
153
size_t items = current.size();
154
size_t start = current.begin();
155
assert(items<=4);
156
157
/* allocate leaf node */
158
Triangle4v* accel = (Triangle4v*) alloc.malloc1(sizeof(Triangle4v),BVH::byteAlignment);
159
NodeRef ref = BVH::encodeLeaf((char*)accel,1);
160
vuint4 vgeomID = -1, vprimID = -1;
161
Vec3vf4 v0 = zero, v1 = zero, v2 = zero;
162
const TriangleMesh* __restrict__ mesh = this->mesh;
163
164
for (size_t i=0; i<items; i++)
165
{
166
const unsigned int primID = morton[start+i].index;
167
const TriangleMesh::Triangle& tri = mesh->triangle(primID);
168
const Vec3fa& p0 = mesh->vertex(tri.v[0]);
169
const Vec3fa& p1 = mesh->vertex(tri.v[1]);
170
const Vec3fa& p2 = mesh->vertex(tri.v[2]);
171
lower = min(lower,(vfloat4)p0,(vfloat4)p1,(vfloat4)p2);
172
upper = max(upper,(vfloat4)p0,(vfloat4)p1,(vfloat4)p2);
173
vgeomID [i] = geomID_;
174
vprimID [i] = primID;
175
v0.x[i] = p0.x; v0.y[i] = p0.y; v0.z[i] = p0.z;
176
v1.x[i] = p1.x; v1.y[i] = p1.y; v1.z[i] = p1.z;
177
v2.x[i] = p2.x; v2.y[i] = p2.y; v2.z[i] = p2.z;
178
}
179
Triangle4v::store_nt(accel,Triangle4v(v0,v1,v2,vgeomID,vprimID));
180
BBox3fx box_o = BBox3fx((Vec3fx)lower,(Vec3fx)upper);
181
#if ROTATE_TREE
182
if (N == 4)
183
box_o.lower.a = current.size();
184
#endif
185
return NodeRecord(ref,box_o);
186
}
187
private:
188
TriangleMesh* mesh;
189
BVHBuilderMorton::BuildPrim* morton;
190
unsigned int geomID_ = std::numeric_limits<unsigned int>::max();
191
};
192
193
template<int N>
194
struct CreateMortonLeaf<N,Triangle4i>
195
{
196
typedef BVHN<N> BVH;
197
typedef typename BVH::NodeRef NodeRef;
198
typedef typename BVH::NodeRecord NodeRecord;
199
200
__forceinline CreateMortonLeaf (TriangleMesh* mesh, unsigned int geomID, BVHBuilderMorton::BuildPrim* morton)
201
: mesh(mesh), morton(morton), geomID_(geomID) {}
202
203
__noinline NodeRecord operator() (const range<unsigned>& current, const FastAllocator::CachedAllocator& alloc)
204
{
205
vfloat4 lower(pos_inf);
206
vfloat4 upper(neg_inf);
207
size_t items = current.size();
208
size_t start = current.begin();
209
assert(items<=4);
210
211
/* allocate leaf node */
212
Triangle4i* accel = (Triangle4i*) alloc.malloc1(sizeof(Triangle4i),BVH::byteAlignment);
213
NodeRef ref = BVH::encodeLeaf((char*)accel,1);
214
215
vuint4 v0 = zero, v1 = zero, v2 = zero;
216
vuint4 vgeomID = -1, vprimID = -1;
217
const TriangleMesh* __restrict__ const mesh = this->mesh;
218
219
for (size_t i=0; i<items; i++)
220
{
221
const unsigned int primID = morton[start+i].index;
222
const TriangleMesh::Triangle& tri = mesh->triangle(primID);
223
const Vec3fa& p0 = mesh->vertex(tri.v[0]);
224
const Vec3fa& p1 = mesh->vertex(tri.v[1]);
225
const Vec3fa& p2 = mesh->vertex(tri.v[2]);
226
lower = min(lower,(vfloat4)p0,(vfloat4)p1,(vfloat4)p2);
227
upper = max(upper,(vfloat4)p0,(vfloat4)p1,(vfloat4)p2);
228
vgeomID[i] = geomID_;
229
vprimID[i] = primID;
230
unsigned int int_stride = mesh->vertices0.getStride()/4;
231
v0[i] = tri.v[0] * int_stride;
232
v1[i] = tri.v[1] * int_stride;
233
v2[i] = tri.v[2] * int_stride;
234
}
235
236
for (size_t i=items; i<4; i++)
237
{
238
vgeomID[i] = vgeomID[0];
239
vprimID[i] = -1;
240
v0[i] = 0;
241
v1[i] = 0;
242
v2[i] = 0;
243
}
244
Triangle4i::store_nt(accel,Triangle4i(v0,v1,v2,vgeomID,vprimID));
245
BBox3fx box_o = BBox3fx((Vec3fx)lower,(Vec3fx)upper);
246
#if ROTATE_TREE
247
if (N == 4)
248
box_o.lower.a = current.size();
249
#endif
250
return NodeRecord(ref,box_o);
251
}
252
private:
253
TriangleMesh* mesh;
254
BVHBuilderMorton::BuildPrim* morton;
255
unsigned int geomID_ = std::numeric_limits<unsigned int>::max();
256
};
257
258
template<int N>
259
struct CreateMortonLeaf<N,Quad4v>
260
{
261
typedef BVHN<N> BVH;
262
typedef typename BVH::NodeRef NodeRef;
263
typedef typename BVH::NodeRecord NodeRecord;
264
265
__forceinline CreateMortonLeaf (QuadMesh* mesh, unsigned int geomID, BVHBuilderMorton::BuildPrim* morton)
266
: mesh(mesh), morton(morton), geomID_(geomID) {}
267
268
__noinline NodeRecord operator() (const range<unsigned>& current, const FastAllocator::CachedAllocator& alloc)
269
{
270
vfloat4 lower(pos_inf);
271
vfloat4 upper(neg_inf);
272
size_t items = current.size();
273
size_t start = current.begin();
274
assert(items<=4);
275
276
/* allocate leaf node */
277
Quad4v* accel = (Quad4v*) alloc.malloc1(sizeof(Quad4v),BVH::byteAlignment);
278
NodeRef ref = BVH::encodeLeaf((char*)accel,1);
279
280
vuint4 vgeomID = -1, vprimID = -1;
281
Vec3vf4 v0 = zero, v1 = zero, v2 = zero, v3 = zero;
282
const QuadMesh* __restrict__ mesh = this->mesh;
283
284
for (size_t i=0; i<items; i++)
285
{
286
const unsigned int primID = morton[start+i].index;
287
const QuadMesh::Quad& tri = mesh->quad(primID);
288
const Vec3fa& p0 = mesh->vertex(tri.v[0]);
289
const Vec3fa& p1 = mesh->vertex(tri.v[1]);
290
const Vec3fa& p2 = mesh->vertex(tri.v[2]);
291
const Vec3fa& p3 = mesh->vertex(tri.v[3]);
292
lower = min(lower,(vfloat4)p0,(vfloat4)p1,(vfloat4)p2,(vfloat4)p3);
293
upper = max(upper,(vfloat4)p0,(vfloat4)p1,(vfloat4)p2,(vfloat4)p3);
294
vgeomID [i] = geomID_;
295
vprimID [i] = primID;
296
v0.x[i] = p0.x; v0.y[i] = p0.y; v0.z[i] = p0.z;
297
v1.x[i] = p1.x; v1.y[i] = p1.y; v1.z[i] = p1.z;
298
v2.x[i] = p2.x; v2.y[i] = p2.y; v2.z[i] = p2.z;
299
v3.x[i] = p3.x; v3.y[i] = p3.y; v3.z[i] = p3.z;
300
}
301
Quad4v::store_nt(accel,Quad4v(v0,v1,v2,v3,vgeomID,vprimID));
302
BBox3fx box_o = BBox3fx((Vec3fx)lower,(Vec3fx)upper);
303
#if ROTATE_TREE
304
if (N == 4)
305
box_o.lower.a = current.size();
306
#endif
307
return NodeRecord(ref,box_o);
308
}
309
private:
310
QuadMesh* mesh;
311
BVHBuilderMorton::BuildPrim* morton;
312
unsigned int geomID_ = std::numeric_limits<unsigned int>::max();
313
};
314
315
template<int N>
316
struct CreateMortonLeaf<N,Object>
317
{
318
typedef BVHN<N> BVH;
319
typedef typename BVH::NodeRef NodeRef;
320
typedef typename BVH::NodeRecord NodeRecord;
321
322
__forceinline CreateMortonLeaf (UserGeometry* mesh, unsigned int geomID, BVHBuilderMorton::BuildPrim* morton)
323
: mesh(mesh), morton(morton), geomID_(geomID) {}
324
325
__noinline NodeRecord operator() (const range<unsigned>& current, const FastAllocator::CachedAllocator& alloc)
326
{
327
vfloat4 lower(pos_inf);
328
vfloat4 upper(neg_inf);
329
size_t items = current.size();
330
size_t start = current.begin();
331
332
/* allocate leaf node */
333
Object* accel = (Object*) alloc.malloc1(items*sizeof(Object),BVH::byteAlignment);
334
NodeRef ref = BVH::encodeLeaf((char*)accel,items);
335
const UserGeometry* mesh = this->mesh;
336
337
BBox3fa bounds = empty;
338
for (size_t i=0; i<items; i++)
339
{
340
const unsigned int index = morton[start+i].index;
341
const unsigned int primID = index;
342
bounds.extend(mesh->bounds(primID));
343
new (&accel[i]) Object(geomID_,primID);
344
}
345
346
BBox3fx box_o = (BBox3fx&)bounds;
347
#if ROTATE_TREE
348
if (N == 4)
349
box_o.lower.a = current.size();
350
#endif
351
return NodeRecord(ref,box_o);
352
}
353
private:
354
UserGeometry* mesh;
355
BVHBuilderMorton::BuildPrim* morton;
356
unsigned int geomID_ = std::numeric_limits<unsigned int>::max();
357
};
358
359
template<int N>
360
struct CreateMortonLeaf<N,InstancePrimitive>
361
{
362
typedef BVHN<N> BVH;
363
typedef typename BVH::NodeRef NodeRef;
364
typedef typename BVH::NodeRecord NodeRecord;
365
366
__forceinline CreateMortonLeaf (Instance* mesh, unsigned int geomID, BVHBuilderMorton::BuildPrim* morton)
367
: mesh(mesh), morton(morton), geomID_(geomID) {}
368
369
__noinline NodeRecord operator() (const range<unsigned>& current, const FastAllocator::CachedAllocator& alloc)
370
{
371
vfloat4 lower(pos_inf);
372
vfloat4 upper(neg_inf);
373
size_t items = current.size();
374
size_t start = current.begin();
375
assert(items <= 1);
376
377
/* allocate leaf node */
378
InstancePrimitive* accel = (InstancePrimitive*) alloc.malloc1(items*sizeof(InstancePrimitive),BVH::byteAlignment);
379
NodeRef ref = BVH::encodeLeaf((char*)accel,items);
380
const Instance* instance = this->mesh;
381
382
BBox3fa bounds = empty;
383
for (size_t i=0; i<items; i++)
384
{
385
const unsigned int primID = morton[start+i].index;
386
bounds.extend(instance->bounds(primID));
387
new (&accel[i]) InstancePrimitive(instance, geomID_);
388
}
389
390
BBox3fx box_o = (BBox3fx&)bounds;
391
#if ROTATE_TREE
392
if (N == 4)
393
box_o.lower.a = current.size();
394
#endif
395
return NodeRecord(ref,box_o);
396
}
397
private:
398
Instance* mesh;
399
BVHBuilderMorton::BuildPrim* morton;
400
unsigned int geomID_ = std::numeric_limits<unsigned int>::max();
401
};
402
403
template<int N>
404
struct CreateMortonLeaf<N,InstanceArrayPrimitive>
405
{
406
typedef BVHN<N> BVH;
407
typedef typename BVH::NodeRef NodeRef;
408
typedef typename BVH::NodeRecord NodeRecord;
409
410
__forceinline CreateMortonLeaf (InstanceArray* mesh, unsigned int geomID, BVHBuilderMorton::BuildPrim* morton)
411
: mesh(mesh), morton(morton), geomID_(geomID) {}
412
413
__noinline NodeRecord operator() (const range<unsigned>& current, const FastAllocator::CachedAllocator& alloc)
414
{
415
vfloat4 lower(pos_inf);
416
vfloat4 upper(neg_inf);
417
size_t items = current.size();
418
size_t start = current.begin();
419
assert(items <= 1);
420
421
/* allocate leaf node */
422
InstanceArrayPrimitive* accel = (InstanceArrayPrimitive*) alloc.malloc1(items*sizeof(InstanceArrayPrimitive),BVH::byteAlignment);
423
NodeRef ref = BVH::encodeLeaf((char*)accel,items);
424
const InstanceArray* instance = this->mesh;
425
426
BBox3fa bounds = empty;
427
for (size_t i=0; i<items; i++)
428
{
429
const unsigned int primID = morton[start+i].index;
430
bounds.extend(instance->bounds(primID));
431
new (&accel[i]) InstanceArrayPrimitive(geomID_, primID);
432
}
433
434
BBox3fx box_o = (BBox3fx&)bounds;
435
#if ROTATE_TREE
436
if (N == 4)
437
box_o.lower.a = current.size();
438
#endif
439
return NodeRecord(ref,box_o);
440
}
441
private:
442
InstanceArray* mesh;
443
BVHBuilderMorton::BuildPrim* morton;
444
unsigned int geomID_ = std::numeric_limits<unsigned int>::max();
445
};
446
447
template<typename Mesh>
448
struct CalculateMeshBounds
449
{
450
__forceinline CalculateMeshBounds (Mesh* mesh)
451
: mesh(mesh) {}
452
453
__forceinline const BBox3fa operator() (const BVHBuilderMorton::BuildPrim& morton) {
454
return mesh->bounds(morton.index);
455
}
456
457
private:
458
Mesh* mesh;
459
};
460
461
template<int N, typename Mesh, typename Primitive>
462
class BVHNMeshBuilderMorton : public Builder
463
{
464
typedef BVHN<N> BVH;
465
typedef typename BVH::AABBNode AABBNode;
466
typedef typename BVH::NodeRef NodeRef;
467
typedef typename BVH::NodeRecord NodeRecord;
468
469
public:
470
471
BVHNMeshBuilderMorton (BVH* bvh, Mesh* mesh, unsigned int geomID, const size_t minLeafSize, const size_t maxLeafSize, const size_t singleThreadThreshold = DEFAULT_SINGLE_THREAD_THRESHOLD)
472
: bvh(bvh), mesh(mesh), morton(bvh->device,0), settings(N,BVH::maxBuildDepth,minLeafSize,min(maxLeafSize,Primitive::max_size()*BVH::maxLeafBlocks),singleThreadThreshold), geomID_(geomID) {}
473
474
/* build function */
475
void build()
476
{
477
/* we reset the allocator when the mesh size changed */
478
if (mesh->numPrimitives != numPreviousPrimitives) {
479
bvh->alloc.clear();
480
morton.clear();
481
}
482
size_t numPrimitives = mesh->size();
483
numPreviousPrimitives = numPrimitives;
484
485
/* skip build for empty scene */
486
if (numPrimitives == 0) {
487
bvh->set(BVH::emptyNode,empty,0);
488
return;
489
}
490
491
/* preallocate arrays */
492
morton.resize(numPrimitives);
493
size_t bytesEstimated = numPrimitives*sizeof(AABBNode)/(4*N) + size_t(1.2f*Primitive::blocks(numPrimitives)*sizeof(Primitive));
494
size_t bytesMortonCodes = numPrimitives*sizeof(BVHBuilderMorton::BuildPrim);
495
bytesEstimated = max(bytesEstimated,bytesMortonCodes); // the first allocation block is reused to sort the morton codes
496
bvh->alloc.init(bytesMortonCodes,bytesMortonCodes,bytesEstimated);
497
498
/* create morton code array */
499
BVHBuilderMorton::BuildPrim* dest = (BVHBuilderMorton::BuildPrim*) bvh->alloc.specialAlloc(bytesMortonCodes);
500
size_t numPrimitivesGen = createMortonCodeArray<Mesh>(mesh,morton,bvh->scene->progressInterface);
501
502
/* create BVH */
503
SetBVHNBounds<N> setBounds(bvh);
504
CreateMortonLeaf<N,Primitive> createLeaf(mesh,geomID_,morton.data());
505
CalculateMeshBounds<Mesh> calculateBounds(mesh);
506
auto root = BVHBuilderMorton::build<NodeRecord>(
507
typename BVH::CreateAlloc(bvh),
508
typename BVH::AABBNode::Create(),
509
setBounds,createLeaf,calculateBounds,bvh->scene->progressInterface,
510
morton.data(),dest,numPrimitivesGen,settings);
511
512
bvh->set(root.ref,LBBox3fa(root.bounds),numPrimitives);
513
514
#if ROTATE_TREE
515
if (N == 4)
516
{
517
for (int i=0; i<ROTATE_TREE; i++)
518
BVHNRotate<N>::rotate(bvh->root);
519
bvh->clearBarrier(bvh->root);
520
}
521
#endif
522
523
/* clear temporary data for static geometry */
524
if (bvh->scene->isStaticAccel()) {
525
morton.clear();
526
}
527
bvh->cleanup();
528
}
529
530
void clear() {
531
morton.clear();
532
}
533
534
private:
535
BVH* bvh;
536
Mesh* mesh;
537
mvector<BVHBuilderMorton::BuildPrim> morton;
538
BVHBuilderMorton::Settings settings;
539
unsigned int geomID_ = std::numeric_limits<unsigned int>::max();
540
unsigned int numPreviousPrimitives = 0;
541
};
542
543
#if defined(EMBREE_GEOMETRY_TRIANGLE)
544
Builder* BVH4Triangle4MeshBuilderMortonGeneral (void* bvh, TriangleMesh* mesh, unsigned int geomID, size_t mode) { return new class BVHNMeshBuilderMorton<4,TriangleMesh,Triangle4> ((BVH4*)bvh,mesh,geomID,4,4); }
545
Builder* BVH4Triangle4vMeshBuilderMortonGeneral (void* bvh, TriangleMesh* mesh, unsigned int geomID, size_t mode) { return new class BVHNMeshBuilderMorton<4,TriangleMesh,Triangle4v>((BVH4*)bvh,mesh,geomID,4,4); }
546
Builder* BVH4Triangle4iMeshBuilderMortonGeneral (void* bvh, TriangleMesh* mesh, unsigned int geomID, size_t mode) { return new class BVHNMeshBuilderMorton<4,TriangleMesh,Triangle4i>((BVH4*)bvh,mesh,geomID,4,4); }
547
#if defined(__AVX__)
548
Builder* BVH8Triangle4MeshBuilderMortonGeneral (void* bvh, TriangleMesh* mesh, unsigned int geomID, size_t mode) { return new class BVHNMeshBuilderMorton<8,TriangleMesh,Triangle4> ((BVH8*)bvh,mesh,geomID,4,4); }
549
Builder* BVH8Triangle4vMeshBuilderMortonGeneral (void* bvh, TriangleMesh* mesh, unsigned int geomID, size_t mode) { return new class BVHNMeshBuilderMorton<8,TriangleMesh,Triangle4v>((BVH8*)bvh,mesh,geomID,4,4); }
550
Builder* BVH8Triangle4iMeshBuilderMortonGeneral (void* bvh, TriangleMesh* mesh, unsigned int geomID, size_t mode) { return new class BVHNMeshBuilderMorton<8,TriangleMesh,Triangle4i>((BVH8*)bvh,mesh,geomID,4,4); }
551
#endif
552
#endif
553
554
#if defined(EMBREE_GEOMETRY_QUAD)
555
Builder* BVH4Quad4vMeshBuilderMortonGeneral (void* bvh, QuadMesh* mesh, unsigned int geomID, size_t mode) { return new class BVHNMeshBuilderMorton<4,QuadMesh,Quad4v>((BVH4*)bvh,mesh,geomID,4,4); }
556
#if defined(__AVX__)
557
Builder* BVH8Quad4vMeshBuilderMortonGeneral (void* bvh, QuadMesh* mesh, unsigned int geomID, size_t mode) { return new class BVHNMeshBuilderMorton<8,QuadMesh,Quad4v>((BVH8*)bvh,mesh,geomID,4,4); }
558
#endif
559
#endif
560
561
#if defined(EMBREE_GEOMETRY_USER)
562
Builder* BVH4VirtualMeshBuilderMortonGeneral (void* bvh, UserGeometry* mesh, unsigned int geomID, size_t mode) { return new class BVHNMeshBuilderMorton<4,UserGeometry,Object>((BVH4*)bvh,mesh,geomID,1,BVH4::maxLeafBlocks); }
563
#if defined(__AVX__)
564
Builder* BVH8VirtualMeshBuilderMortonGeneral (void* bvh, UserGeometry* mesh, unsigned int geomID, size_t mode) { return new class BVHNMeshBuilderMorton<8,UserGeometry,Object>((BVH8*)bvh,mesh,geomID,1,BVH4::maxLeafBlocks); }
565
#endif
566
#endif
567
568
#if defined(EMBREE_GEOMETRY_INSTANCE)
569
Builder* BVH4InstanceMeshBuilderMortonGeneral (void* bvh, Instance* mesh, Geometry::GTypeMask gtype, unsigned int geomID, size_t mode) { return new class BVHNMeshBuilderMorton<4,Instance,InstancePrimitive>((BVH4*)bvh,mesh,gtype,geomID,1,BVH4::maxLeafBlocks); }
570
#if defined(__AVX__)
571
Builder* BVH8InstanceMeshBuilderMortonGeneral (void* bvh, Instance* mesh, Geometry::GTypeMask gtype, unsigned int geomID, size_t mode) { return new class BVHNMeshBuilderMorton<8,Instance,InstancePrimitive>((BVH8*)bvh,mesh,gtype,geomID,1,BVH4::maxLeafBlocks); }
572
#endif
573
#endif
574
575
#if defined(EMBREE_GEOMETRY_INSTANCE_ARRAY)
576
Builder* BVH4InstanceArrayMeshBuilderMortonGeneral (void* bvh, InstanceArray* mesh, Geometry::GTypeMask gtype, unsigned int geomID, size_t mode) { return new class BVHNMeshBuilderMorton<4,InstanceArray,InstanceArrayPrimitive>((BVH4*)bvh,mesh,gtype,geomID,1,BVH4::maxLeafBlocks); }
577
#if defined(__AVX__)
578
Builder* BVH8InstanceArrayMeshBuilderMortonGeneral (void* bvh, InstanceArray* mesh, Geometry::GTypeMask gtype, unsigned int geomID, size_t mode) { return new class BVHNMeshBuilderMorton<8,InstanceArray,InstanceArrayPrimitive>((BVH8*)bvh,mesh,gtype,geomID,1,BVH4::maxLeafBlocks); }
579
#endif
580
#endif
581
582
}
583
}
584
585