Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/embree/kernels/common/accel.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 "ray.h"
8
#include "point_query.h"
9
#include "context.h"
10
11
namespace embree
12
{
13
class Scene;
14
15
/*! Base class for the acceleration structure data. */
16
class AccelData : public RefCount
17
{
18
ALIGNED_CLASS_(16);
19
public:
20
enum Type { TY_UNKNOWN = 0, TY_ACCELN = 1, TY_ACCEL_INSTANCE = 2, TY_BVH4 = 3, TY_BVH8 = 4, TY_GPU = 5 };
21
22
public:
23
AccelData (const Type type)
24
: bounds(empty), type(type) {}
25
26
/*! notifies the acceleration structure about the deletion of some geometry */
27
virtual void deleteGeometry(size_t geomID) {};
28
29
/*! clears the acceleration structure data */
30
virtual void clear() = 0;
31
32
/*! returns normal bounds */
33
__forceinline BBox3fa getBounds() const {
34
return bounds.bounds();
35
}
36
37
/*! returns bounds for some time */
38
__forceinline BBox3fa getBounds(float t) const {
39
return bounds.interpolate(t);
40
}
41
42
/*! returns linear bounds */
43
__forceinline LBBox3fa getLinearBounds() const {
44
return bounds;
45
}
46
47
/*! checks if acceleration structure is empty */
48
__forceinline bool isEmpty() const {
49
return bounds.bounds0.lower.x == float(pos_inf);
50
}
51
52
public:
53
LBBox3fa bounds; // linear bounds
54
Type type;
55
};
56
57
/*! Base class for all intersectable and buildable acceleration structures. */
58
class Accel : public AccelData
59
{
60
ALIGNED_CLASS_(16);
61
public:
62
63
struct Intersectors;
64
65
/*! Type of collide function */
66
typedef void (*CollideFunc)(void* bvh0, void* bvh1, RTCCollideFunc callback, void* userPtr);
67
68
/*! Type of point query function */
69
typedef bool(*PointQueryFunc)(Intersectors* This, /*!< this pointer to accel */
70
PointQuery* query, /*!< point query for lookup */
71
PointQueryContext* context); /*!< point query context */
72
73
/*! Type of intersect function pointer for single rays. */
74
typedef void (*IntersectFunc)(Intersectors* This, /*!< this pointer to accel */
75
RTCRayHit& ray, /*!< ray to intersect */
76
RayQueryContext* context);
77
78
/*! Type of intersect function pointer for ray packets of size 4. */
79
typedef void (*IntersectFunc4)(const void* valid, /*!< pointer to valid mask */
80
Intersectors* This, /*!< this pointer to accel */
81
RTCRayHit4& ray, /*!< ray packet to intersect */
82
RayQueryContext* context);
83
84
/*! Type of intersect function pointer for ray packets of size 8. */
85
typedef void (*IntersectFunc8)(const void* valid, /*!< pointer to valid mask */
86
Intersectors* This, /*!< this pointer to accel */
87
RTCRayHit8& ray, /*!< ray packet to intersect */
88
RayQueryContext* context);
89
90
/*! Type of intersect function pointer for ray packets of size 16. */
91
typedef void (*IntersectFunc16)(const void* valid, /*!< pointer to valid mask */
92
Intersectors* This, /*!< this pointer to accel */
93
RTCRayHit16& ray, /*!< ray packet to intersect */
94
RayQueryContext* context);
95
96
/*! Type of occlusion function pointer for single rays. */
97
typedef void (*OccludedFunc) (Intersectors* This, /*!< this pointer to accel */
98
RTCRay& ray, /*!< ray to test occlusion */
99
RayQueryContext* context);
100
101
/*! Type of occlusion function pointer for ray packets of size 4. */
102
typedef void (*OccludedFunc4) (const void* valid, /*!< pointer to valid mask */
103
Intersectors* This, /*!< this pointer to accel */
104
RTCRay4& ray, /*!< ray packet to test occlusion. */
105
RayQueryContext* context);
106
107
/*! Type of occlusion function pointer for ray packets of size 8. */
108
typedef void (*OccludedFunc8) (const void* valid, /*!< pointer to valid mask */
109
Intersectors* This, /*!< this pointer to accel */
110
RTCRay8& ray, /*!< ray packet to test occlusion. */
111
RayQueryContext* context);
112
113
/*! Type of occlusion function pointer for ray packets of size 16. */
114
typedef void (*OccludedFunc16) (const void* valid, /*!< pointer to valid mask */
115
Intersectors* This, /*!< this pointer to accel */
116
RTCRay16& ray, /*!< ray packet to test occlusion. */
117
RayQueryContext* context);
118
119
typedef void (*ErrorFunc) ();
120
121
struct Collider
122
{
123
Collider (ErrorFunc error = nullptr)
124
: collide((CollideFunc)error), name(nullptr) {}
125
126
Collider (CollideFunc collide, const char* name)
127
: collide(collide), name(name) {}
128
129
operator bool() const { return name; }
130
131
public:
132
CollideFunc collide;
133
const char* name;
134
};
135
136
struct Intersector1
137
{
138
Intersector1 (ErrorFunc error = nullptr)
139
: intersect((IntersectFunc)error), occluded((OccludedFunc)error), name(nullptr) {}
140
141
Intersector1 (IntersectFunc intersect, OccludedFunc occluded, const char* name)
142
: intersect(intersect), occluded(occluded), pointQuery(nullptr), name(name) {}
143
144
Intersector1 (IntersectFunc intersect, OccludedFunc occluded, PointQueryFunc pointQuery, const char* name)
145
: intersect(intersect), occluded(occluded), pointQuery(pointQuery), name(name) {}
146
147
operator bool() const { return name; }
148
149
public:
150
static const char* type;
151
IntersectFunc intersect;
152
OccludedFunc occluded;
153
PointQueryFunc pointQuery;
154
const char* name;
155
};
156
157
struct Intersector4
158
{
159
Intersector4 (ErrorFunc error = nullptr)
160
: intersect((IntersectFunc4)error), occluded((OccludedFunc4)error), name(nullptr) {}
161
162
Intersector4 (IntersectFunc4 intersect, OccludedFunc4 occluded, const char* name)
163
: intersect(intersect), occluded(occluded), name(name) {}
164
165
operator bool() const { return name; }
166
167
public:
168
static const char* type;
169
IntersectFunc4 intersect;
170
OccludedFunc4 occluded;
171
const char* name;
172
};
173
174
struct Intersector8
175
{
176
Intersector8 (ErrorFunc error = nullptr)
177
: intersect((IntersectFunc8)error), occluded((OccludedFunc8)error), name(nullptr) {}
178
179
Intersector8 (IntersectFunc8 intersect, OccludedFunc8 occluded, const char* name)
180
: intersect(intersect), occluded(occluded), name(name) {}
181
182
operator bool() const { return name; }
183
184
public:
185
static const char* type;
186
IntersectFunc8 intersect;
187
OccludedFunc8 occluded;
188
const char* name;
189
};
190
191
struct Intersector16
192
{
193
Intersector16 (ErrorFunc error = nullptr)
194
: intersect((IntersectFunc16)error), occluded((OccludedFunc16)error), name(nullptr) {}
195
196
Intersector16 (IntersectFunc16 intersect, OccludedFunc16 occluded, const char* name)
197
: intersect(intersect), occluded(occluded), name(name) {}
198
199
operator bool() const { return name; }
200
201
public:
202
static const char* type;
203
IntersectFunc16 intersect;
204
OccludedFunc16 occluded;
205
const char* name;
206
};
207
208
struct Intersectors
209
{
210
Intersectors()
211
: ptr(nullptr), leafIntersector(nullptr), collider(nullptr), intersector1(nullptr), intersector4(nullptr), intersector8(nullptr), intersector16(nullptr) {}
212
213
Intersectors (ErrorFunc error)
214
: ptr(nullptr), leafIntersector(nullptr), collider(error), intersector1(error), intersector4(error), intersector8(error), intersector16(error) {}
215
216
void print(size_t ident)
217
{
218
if (collider.name) {
219
for (size_t i=0; i<ident; i++) std::cout << " ";
220
std::cout << "collider = " << collider.name << std::endl;
221
}
222
if (intersector1.name) {
223
for (size_t i=0; i<ident; i++) std::cout << " ";
224
std::cout << "intersector1 = " << intersector1.name << std::endl;
225
}
226
if (intersector4.name) {
227
for (size_t i=0; i<ident; i++) std::cout << " ";
228
std::cout << "intersector4 = " << intersector4.name << std::endl;
229
}
230
if (intersector8.name) {
231
for (size_t i=0; i<ident; i++) std::cout << " ";
232
std::cout << "intersector8 = " << intersector8.name << std::endl;
233
}
234
if (intersector16.name) {
235
for (size_t i=0; i<ident; i++) std::cout << " ";
236
std::cout << "intersector16 = " << intersector16.name << std::endl;
237
}
238
}
239
240
void select(bool filter)
241
{
242
if (intersector4_filter) {
243
if (filter) intersector4 = intersector4_filter;
244
else intersector4 = intersector4_nofilter;
245
}
246
if (intersector8_filter) {
247
if (filter) intersector8 = intersector8_filter;
248
else intersector8 = intersector8_nofilter;
249
}
250
if (intersector16_filter) {
251
if (filter) intersector16 = intersector16_filter;
252
else intersector16 = intersector16_nofilter;
253
}
254
}
255
256
__forceinline bool pointQuery (PointQuery* query, PointQueryContext* context) {
257
assert(intersector1.pointQuery);
258
return intersector1.pointQuery(this,query,context);
259
}
260
261
/*! collides two scenes */
262
__forceinline void collide (Accel* scene0, Accel* scene1, RTCCollideFunc callback, void* userPtr) {
263
assert(collider.collide);
264
collider.collide(scene0->intersectors.ptr,scene1->intersectors.ptr,callback,userPtr);
265
}
266
267
/*! Intersects a single ray with the scene. */
268
__forceinline void intersect (RTCRayHit& ray, RayQueryContext* context) {
269
assert(intersector1.intersect);
270
intersector1.intersect(this,ray,context);
271
}
272
273
/*! Intersects a packet of 4 rays with the scene. */
274
__forceinline void intersect4 (const void* valid, RTCRayHit4& ray, RayQueryContext* context) {
275
assert(intersector4.intersect);
276
intersector4.intersect(valid,this,ray,context);
277
}
278
279
/*! Intersects a packet of 8 rays with the scene. */
280
__forceinline void intersect8 (const void* valid, RTCRayHit8& ray, RayQueryContext* context) {
281
assert(intersector8.intersect);
282
intersector8.intersect(valid,this,ray,context);
283
}
284
285
/*! Intersects a packet of 16 rays with the scene. */
286
__forceinline void intersect16 (const void* valid, RTCRayHit16& ray, RayQueryContext* context) {
287
assert(intersector16.intersect);
288
intersector16.intersect(valid,this,ray,context);
289
}
290
291
/*! Intersects a packet of 4 rays with the scene. */
292
__forceinline void intersect (const void* valid, RTCRayHit4& ray, RayQueryContext* context) {
293
assert(intersector4.intersect);
294
intersector4.intersect(valid,this,ray,context);
295
}
296
297
/*! Intersects a packet of 8 rays with the scene. */
298
__forceinline void intersect (const void* valid, RTCRayHit8& ray, RayQueryContext* context) {
299
assert(intersector8.intersect);
300
intersector8.intersect(valid,this,ray,context);
301
}
302
303
/*! Intersects a packet of 16 rays with the scene. */
304
__forceinline void intersect (const void* valid, RTCRayHit16& ray, RayQueryContext* context) {
305
assert(intersector16.intersect);
306
intersector16.intersect(valid,this,ray,context);
307
}
308
309
#if defined(__SSE__) || defined(__ARM_NEON)
310
__forceinline void intersect(const vbool4& valid, RayHitK<4>& ray, RayQueryContext* context) {
311
const vint<4> mask = valid.mask32();
312
intersect4(&mask,(RTCRayHit4&)ray,context);
313
}
314
#endif
315
#if defined(__AVX__)
316
__forceinline void intersect(const vbool8& valid, RayHitK<8>& ray, RayQueryContext* context) {
317
const vint<8> mask = valid.mask32();
318
intersect8(&mask,(RTCRayHit8&)ray,context);
319
}
320
#endif
321
#if defined(__AVX512F__)
322
__forceinline void intersect(const vbool16& valid, RayHitK<16>& ray, RayQueryContext* context) {
323
const vint<16> mask = valid.mask32();
324
intersect16(&mask,(RTCRayHit16&)ray,context);
325
}
326
#endif
327
328
/*! Tests if single ray is occluded by the scene. */
329
__forceinline void occluded (RTCRay& ray, RayQueryContext* context) {
330
assert(intersector1.occluded);
331
intersector1.occluded(this,ray,context);
332
}
333
334
/*! Tests if a packet of 4 rays is occluded by the scene. */
335
__forceinline void occluded4 (const void* valid, RTCRay4& ray, RayQueryContext* context) {
336
assert(intersector4.occluded);
337
intersector4.occluded(valid,this,ray,context);
338
}
339
340
/*! Tests if a packet of 8 rays is occluded by the scene. */
341
__forceinline void occluded8 (const void* valid, RTCRay8& ray, RayQueryContext* context) {
342
assert(intersector8.occluded);
343
intersector8.occluded(valid,this,ray,context);
344
}
345
346
/*! Tests if a packet of 16 rays is occluded by the scene. */
347
__forceinline void occluded16 (const void* valid, RTCRay16& ray, RayQueryContext* context) {
348
assert(intersector16.occluded);
349
intersector16.occluded(valid,this,ray,context);
350
}
351
352
/*! Tests if a packet of 4 rays is occluded by the scene. */
353
__forceinline void occluded (const void* valid, RTCRay4& ray, RayQueryContext* context) {
354
assert(intersector4.occluded);
355
intersector4.occluded(valid,this,ray,context);
356
}
357
358
/*! Tests if a packet of 8 rays is occluded by the scene. */
359
__forceinline void occluded (const void* valid, RTCRay8& ray, RayQueryContext* context) {
360
assert(intersector8.occluded);
361
intersector8.occluded(valid,this,ray,context);
362
}
363
364
/*! Tests if a packet of 16 rays is occluded by the scene. */
365
__forceinline void occluded (const void* valid, RTCRay16& ray, RayQueryContext* context) {
366
assert(intersector16.occluded);
367
intersector16.occluded(valid,this,ray,context);
368
}
369
370
#if defined(__SSE__) || defined(__ARM_NEON)
371
__forceinline void occluded(const vbool4& valid, RayK<4>& ray, RayQueryContext* context) {
372
const vint<4> mask = valid.mask32();
373
occluded4(&mask,(RTCRay4&)ray,context);
374
}
375
#endif
376
#if defined(__AVX__)
377
__forceinline void occluded(const vbool8& valid, RayK<8>& ray, RayQueryContext* context) {
378
const vint<8> mask = valid.mask32();
379
occluded8(&mask,(RTCRay8&)ray,context);
380
}
381
#endif
382
#if defined(__AVX512F__)
383
__forceinline void occluded(const vbool16& valid, RayK<16>& ray, RayQueryContext* context) {
384
const vint<16> mask = valid.mask32();
385
occluded16(&mask,(RTCRay16&)ray,context);
386
}
387
#endif
388
389
/*! Tests if single ray is occluded by the scene. */
390
__forceinline void intersect(RTCRay& ray, RayQueryContext* context) {
391
occluded(ray, context);
392
}
393
394
/*! Tests if a packet of K rays is occluded by the scene. */
395
template<int K>
396
__forceinline void intersect(const vbool<K>& valid, RayK<K>& ray, RayQueryContext* context) {
397
occluded(valid, ray, context);
398
}
399
400
401
public:
402
AccelData* ptr;
403
void* leafIntersector;
404
Collider collider;
405
Intersector1 intersector1;
406
Intersector4 intersector4;
407
Intersector4 intersector4_filter;
408
Intersector4 intersector4_nofilter;
409
Intersector8 intersector8;
410
Intersector8 intersector8_filter;
411
Intersector8 intersector8_nofilter;
412
Intersector16 intersector16;
413
Intersector16 intersector16_filter;
414
Intersector16 intersector16_nofilter;
415
};
416
417
public:
418
419
/*! Construction */
420
Accel (const AccelData::Type type)
421
: AccelData(type) {}
422
423
/*! Construction */
424
Accel (const AccelData::Type type, const Intersectors& intersectors)
425
: AccelData(type), intersectors(intersectors) {}
426
427
/*! Virtual destructor */
428
virtual ~Accel() {}
429
430
/*! makes the acceleration structure immutable */
431
virtual void immutable () {}
432
433
/*! build acceleration structure */
434
virtual void build () = 0;
435
436
public:
437
Intersectors intersectors;
438
};
439
440
#define DEFINE_COLLIDER(symbol,collider) \
441
Accel::Collider symbol() { \
442
return Accel::Collider((Accel::CollideFunc)collider::collide, \
443
TOSTRING(isa) "::" TOSTRING(symbol)); \
444
}
445
446
#define DEFINE_INTERSECTOR1(symbol,intersector) \
447
Accel::Intersector1 symbol() { \
448
return Accel::Intersector1((Accel::IntersectFunc )intersector::intersect, \
449
(Accel::OccludedFunc )intersector::occluded, \
450
(Accel::PointQueryFunc)intersector::pointQuery,\
451
TOSTRING(isa) "::" TOSTRING(symbol)); \
452
}
453
454
#define DEFINE_INTERSECTOR4(symbol,intersector) \
455
Accel::Intersector4 symbol() { \
456
return Accel::Intersector4((Accel::IntersectFunc4)intersector::intersect, \
457
(Accel::OccludedFunc4)intersector::occluded, \
458
TOSTRING(isa) "::" TOSTRING(symbol)); \
459
}
460
461
#define DEFINE_INTERSECTOR8(symbol,intersector) \
462
Accel::Intersector8 symbol() { \
463
return Accel::Intersector8((Accel::IntersectFunc8)intersector::intersect, \
464
(Accel::OccludedFunc8)intersector::occluded, \
465
TOSTRING(isa) "::" TOSTRING(symbol)); \
466
}
467
468
#define DEFINE_INTERSECTOR16(symbol,intersector) \
469
Accel::Intersector16 symbol() { \
470
return Accel::Intersector16((Accel::IntersectFunc16)intersector::intersect, \
471
(Accel::OccludedFunc16)intersector::occluded, \
472
TOSTRING(isa) "::" TOSTRING(symbol)); \
473
}
474
}
475
476