Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/embree/kernels/common/accelset.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 "builder.h"
8
#include "geometry.h"
9
#include "ray.h"
10
#include "hit.h"
11
12
namespace embree
13
{
14
struct IntersectFunctionNArguments;
15
struct OccludedFunctionNArguments;
16
17
struct IntersectFunctionNArguments : public RTCIntersectFunctionNArguments
18
{
19
Geometry* geometry;
20
RTCScene forward_scene;
21
RTCIntersectArguments* args;
22
};
23
24
struct OccludedFunctionNArguments : public RTCOccludedFunctionNArguments
25
{
26
Geometry* geometry;
27
RTCScene forward_scene;
28
RTCIntersectArguments* args;
29
};
30
31
/*! Base class for set of acceleration structures. */
32
class AccelSet : public Geometry
33
{
34
public:
35
typedef RTCIntersectFunctionN IntersectFuncN;
36
typedef RTCOccludedFunctionN OccludedFuncN;
37
typedef void (*ErrorFunc) ();
38
39
struct IntersectorN
40
{
41
IntersectorN (ErrorFunc error = nullptr) ;
42
IntersectorN (IntersectFuncN intersect, OccludedFuncN occluded, const char* name);
43
44
operator bool() const { return name; }
45
46
public:
47
static const char* type;
48
IntersectFuncN intersect;
49
OccludedFuncN occluded;
50
const char* name;
51
};
52
53
public:
54
55
/*! construction */
56
AccelSet (Device* device, Geometry::GType gtype, size_t items, size_t numTimeSteps);
57
58
/*! makes the acceleration structure immutable */
59
virtual void immutable () {}
60
61
/*! build accel */
62
virtual void build () = 0;
63
64
/*! check if the i'th primitive is valid between the specified time range */
65
__forceinline bool valid(size_t i, const range<size_t>& itime_range) const
66
{
67
for (size_t itime = itime_range.begin(); itime <= itime_range.end(); itime++)
68
if (!isvalid_non_empty(bounds(i,itime))) return false;
69
70
return true;
71
}
72
73
/*! Calculates the bounds of an item */
74
__forceinline BBox3fa bounds(size_t i, size_t itime = 0) const
75
{
76
BBox3fa box;
77
assert(i < size());
78
RTCBoundsFunctionArguments args;
79
args.geometryUserPtr = userPtr;
80
args.primID = (unsigned int)i;
81
args.timeStep = (unsigned int)itime;
82
args.bounds_o = (RTCBounds*)&box;
83
boundsFunc(&args);
84
return box;
85
}
86
87
/*! calculates the linear bounds of the i'th item at the itime'th time segment */
88
__forceinline LBBox3fa linearBounds(size_t i, size_t itime) const
89
{
90
BBox3fa box[2];
91
assert(i < size());
92
RTCBoundsFunctionArguments args;
93
args.geometryUserPtr = userPtr;
94
args.primID = (unsigned int)i;
95
args.timeStep = (unsigned int)(itime+0);
96
args.bounds_o = (RTCBounds*)&box[0];
97
boundsFunc(&args);
98
args.timeStep = (unsigned int)(itime+1);
99
args.bounds_o = (RTCBounds*)&box[1];
100
boundsFunc(&args);
101
return LBBox3fa(box[0],box[1]);
102
}
103
104
/*! calculates the build bounds of the i'th item, if it's valid */
105
__forceinline bool buildBounds(size_t i, BBox3fa* bbox = nullptr) const
106
{
107
const BBox3fa b = bounds(i);
108
if (bbox) *bbox = b;
109
return isvalid_non_empty(b);
110
}
111
112
/*! calculates the build bounds of the i'th item at the itime'th time segment, if it's valid */
113
__forceinline bool buildBounds(size_t i, size_t itime, BBox3fa& bbox) const
114
{
115
const LBBox3fa bounds = linearBounds(i,itime);
116
bbox = bounds.bounds0; // use bounding box of first timestep to build BVH
117
return isvalid_non_empty(bounds);
118
}
119
120
/*! calculates the linear bounds of the i'th primitive for the specified time range */
121
__forceinline LBBox3fa linearBounds(size_t primID, const BBox1f& dt) const {
122
return LBBox3fa([&] (size_t itime) { return bounds(primID, itime); }, dt, time_range, fnumTimeSegments);
123
}
124
125
/*! calculates the linear bounds of the i'th primitive for the specified time range */
126
__forceinline bool linearBounds(size_t i, const BBox1f& time_range, LBBox3fa& bbox) const {
127
if (!valid(i, timeSegmentRange(time_range))) return false;
128
bbox = linearBounds(i, time_range);
129
return true;
130
}
131
132
/* gets version info of topology */
133
unsigned int getTopologyVersion() const {
134
return numPrimitives;
135
}
136
137
/* returns true if topology changed */
138
bool topologyChanged(unsigned int otherVersion) const {
139
return numPrimitives != otherVersion;
140
}
141
142
public:
143
144
/*! Intersects a single ray with the scene. */
145
__forceinline bool intersect (RayHit& ray, unsigned int geomID, unsigned int primID, RayQueryContext* context)
146
{
147
assert(primID < size());
148
149
int mask = -1;
150
IntersectFunctionNArguments args;
151
args.valid = &mask;
152
args.geometryUserPtr = userPtr;
153
args.context = context->user;
154
args.rayhit = (RTCRayHitN*)&ray;
155
args.N = 1;
156
args.geomID = geomID;
157
args.primID = primID;
158
args.geometry = this;
159
args.forward_scene = nullptr;
160
args.args = context->args;
161
162
IntersectFuncN intersectFunc = nullptr;
163
intersectFunc = intersectorN.intersect;
164
165
if (context->getIntersectFunction())
166
intersectFunc = context->getIntersectFunction();
167
168
assert(intersectFunc);
169
intersectFunc(&args);
170
171
return mask != 0;
172
}
173
174
/*! Tests if single ray is occluded by the scene. */
175
__forceinline bool occluded (Ray& ray, unsigned int geomID, unsigned int primID, RayQueryContext* context)
176
{
177
assert(primID < size());
178
179
int mask = -1;
180
OccludedFunctionNArguments args;
181
args.valid = &mask;
182
args.geometryUserPtr = userPtr;
183
args.context = context->user;
184
args.ray = (RTCRayN*)&ray;
185
args.N = 1;
186
args.geomID = geomID;
187
args.primID = primID;
188
args.geometry = this;
189
args.forward_scene = nullptr;
190
args.args = context->args;
191
192
OccludedFuncN occludedFunc = nullptr;
193
occludedFunc = intersectorN.occluded;
194
195
if (context->getOccludedFunction())
196
occludedFunc = context->getOccludedFunction();
197
198
assert(occludedFunc);
199
occludedFunc(&args);
200
201
return mask != 0;
202
}
203
204
/*! Intersects a single ray with the scene. */
205
__forceinline bool intersect (RayHit& ray, unsigned int geomID, unsigned int primID, RayQueryContext* context, RTCScene& forward_scene)
206
{
207
assert(primID < size());
208
209
int mask = -1;
210
IntersectFunctionNArguments args;
211
args.valid = &mask;
212
args.geometryUserPtr = userPtr;
213
args.context = context->user;
214
args.rayhit = (RTCRayHitN*)&ray;
215
args.N = 1;
216
args.geomID = geomID;
217
args.primID = primID;
218
args.geometry = this;
219
args.forward_scene = nullptr;
220
args.args = nullptr;
221
222
typedef void (*RTCIntersectFunctionSYCL)(const void* args);
223
RTCIntersectFunctionSYCL intersectFunc = nullptr;
224
225
#if EMBREE_SYCL_GEOMETRY_CALLBACK
226
if (context->args->feature_mask & RTC_FEATURE_FLAG_USER_GEOMETRY_CALLBACK_IN_GEOMETRY)
227
intersectFunc = (RTCIntersectFunctionSYCL) intersectorN.intersect;
228
#endif
229
230
if (context->args->feature_mask & RTC_FEATURE_FLAG_USER_GEOMETRY_CALLBACK_IN_ARGUMENTS)
231
if (context->getIntersectFunction())
232
intersectFunc = (RTCIntersectFunctionSYCL) context->getIntersectFunction();
233
234
if (intersectFunc)
235
intersectFunc(&args);
236
237
forward_scene = args.forward_scene;
238
return mask != 0;
239
}
240
241
/*! Tests if single ray is occluded by the scene. */
242
__forceinline bool occluded (Ray& ray, unsigned int geomID, unsigned int primID, RayQueryContext* context, RTCScene& forward_scene)
243
{
244
assert(primID < size());
245
246
int mask = -1;
247
OccludedFunctionNArguments args;
248
args.valid = &mask;
249
args.geometryUserPtr = userPtr;
250
args.context = context->user;
251
args.ray = (RTCRayN*)&ray;
252
args.N = 1;
253
args.geomID = geomID;
254
args.primID = primID;
255
args.geometry = this;
256
args.forward_scene = nullptr;
257
args.args = nullptr;
258
259
typedef void (*RTCOccludedFunctionSYCL)(const void* args);
260
RTCOccludedFunctionSYCL occludedFunc = nullptr;
261
262
#if EMBREE_SYCL_GEOMETRY_CALLBACK
263
if (context->args->feature_mask & RTC_FEATURE_FLAG_USER_GEOMETRY_CALLBACK_IN_GEOMETRY)
264
occludedFunc = (RTCOccludedFunctionSYCL) intersectorN.occluded;
265
#endif
266
267
if (context->args->feature_mask & RTC_FEATURE_FLAG_USER_GEOMETRY_CALLBACK_IN_ARGUMENTS)
268
if (context->getOccludedFunction())
269
occludedFunc = (RTCOccludedFunctionSYCL) context->getOccludedFunction();
270
271
if (occludedFunc)
272
occludedFunc(&args);
273
274
forward_scene = args.forward_scene;
275
return mask != 0;
276
}
277
278
/*! Intersects a packet of K rays with the scene. */
279
template<int K>
280
__forceinline void intersect (const vbool<K>& valid, RayHitK<K>& ray, unsigned int geomID, unsigned int primID, RayQueryContext* context)
281
{
282
assert(primID < size());
283
284
vint<K> mask = valid.mask32();
285
IntersectFunctionNArguments args;
286
args.valid = (int*)&mask;
287
args.geometryUserPtr = userPtr;
288
args.context = context->user;
289
args.rayhit = (RTCRayHitN*)&ray;
290
args.N = K;
291
args.geomID = geomID;
292
args.primID = primID;
293
args.geometry = this;
294
args.forward_scene = nullptr;
295
args.args = context->args;
296
297
IntersectFuncN intersectFunc = nullptr;
298
intersectFunc = intersectorN.intersect;
299
300
if (context->getIntersectFunction())
301
intersectFunc = context->getIntersectFunction();
302
303
assert(intersectFunc);
304
intersectFunc(&args);
305
}
306
307
/*! Tests if a packet of K rays is occluded by the scene. */
308
template<int K>
309
__forceinline void occluded (const vbool<K>& valid, RayK<K>& ray, unsigned int geomID, unsigned int primID, RayQueryContext* context)
310
{
311
assert(primID < size());
312
313
vint<K> mask = valid.mask32();
314
OccludedFunctionNArguments args;
315
args.valid = (int*)&mask;
316
args.geometryUserPtr = userPtr;
317
args.context = context->user;
318
args.ray = (RTCRayN*)&ray;
319
args.N = K;
320
args.geomID = geomID;
321
args.primID = primID;
322
args.geometry = this;
323
args.forward_scene = nullptr;
324
args.args = context->args;
325
326
OccludedFuncN occludedFunc = nullptr;
327
occludedFunc = intersectorN.occluded;
328
329
if (context->getOccludedFunction())
330
occludedFunc = context->getOccludedFunction();
331
332
assert(occludedFunc);
333
occludedFunc(&args);
334
}
335
336
public:
337
RTCBoundsFunction boundsFunc;
338
IntersectorN intersectorN;
339
};
340
341
#define DEFINE_SET_INTERSECTORN(symbol,intersector) \
342
AccelSet::IntersectorN symbol() { \
343
return AccelSet::IntersectorN(intersector::intersect, \
344
intersector::occluded, \
345
TOSTRING(isa) "::" TOSTRING(symbol)); \
346
}
347
}
348
349