summaryrefslogtreecommitdiff
path: root/thirdparty/embree/kernels/common/accelset.h
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/embree/kernels/common/accelset.h')
-rw-r--r--thirdparty/embree/kernels/common/accelset.h248
1 files changed, 248 insertions, 0 deletions
diff --git a/thirdparty/embree/kernels/common/accelset.h b/thirdparty/embree/kernels/common/accelset.h
new file mode 100644
index 0000000000..90b184a07b
--- /dev/null
+++ b/thirdparty/embree/kernels/common/accelset.h
@@ -0,0 +1,248 @@
+// Copyright 2009-2021 Intel Corporation
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include "default.h"
+#include "builder.h"
+#include "geometry.h"
+#include "ray.h"
+#include "hit.h"
+
+namespace embree
+{
+ struct IntersectFunctionNArguments;
+ struct OccludedFunctionNArguments;
+
+ typedef void (*ReportIntersectionFunc) (IntersectFunctionNArguments* args, const RTCFilterFunctionNArguments* filter_args);
+ typedef void (*ReportOcclusionFunc) (OccludedFunctionNArguments* args, const RTCFilterFunctionNArguments* filter_args);
+
+ struct IntersectFunctionNArguments : public RTCIntersectFunctionNArguments
+ {
+ IntersectContext* internal_context;
+ Geometry* geometry;
+ ReportIntersectionFunc report;
+ };
+
+ struct OccludedFunctionNArguments : public RTCOccludedFunctionNArguments
+ {
+ IntersectContext* internal_context;
+ Geometry* geometry;
+ ReportOcclusionFunc report;
+ };
+
+ /*! Base class for set of acceleration structures. */
+ class AccelSet : public Geometry
+ {
+ public:
+ typedef RTCIntersectFunctionN IntersectFuncN;
+ typedef RTCOccludedFunctionN OccludedFuncN;
+ typedef void (*ErrorFunc) ();
+
+ struct IntersectorN
+ {
+ IntersectorN (ErrorFunc error = nullptr) ;
+ IntersectorN (IntersectFuncN intersect, OccludedFuncN occluded, const char* name);
+
+ operator bool() const { return name; }
+
+ public:
+ static const char* type;
+ IntersectFuncN intersect;
+ OccludedFuncN occluded;
+ const char* name;
+ };
+
+ public:
+
+ /*! construction */
+ AccelSet (Device* device, Geometry::GType gtype, size_t items, size_t numTimeSteps);
+
+ /*! makes the acceleration structure immutable */
+ virtual void immutable () {}
+
+ /*! build accel */
+ virtual void build () = 0;
+
+ /*! check if the i'th primitive is valid between the specified time range */
+ __forceinline bool valid(size_t i, const range<size_t>& itime_range) const
+ {
+ for (size_t itime = itime_range.begin(); itime <= itime_range.end(); itime++)
+ if (!isvalid_non_empty(bounds(i,itime))) return false;
+
+ return true;
+ }
+
+ /*! Calculates the bounds of an item */
+ __forceinline BBox3fa bounds(size_t i, size_t itime = 0) const
+ {
+ BBox3fa box;
+ assert(i < size());
+ RTCBoundsFunctionArguments args;
+ args.geometryUserPtr = userPtr;
+ args.primID = (unsigned int)i;
+ args.timeStep = (unsigned int)itime;
+ args.bounds_o = (RTCBounds*)&box;
+ boundsFunc(&args);
+ return box;
+ }
+
+ /*! calculates the linear bounds of the i'th item at the itime'th time segment */
+ __forceinline LBBox3fa linearBounds(size_t i, size_t itime) const
+ {
+ BBox3fa box[2];
+ assert(i < size());
+ RTCBoundsFunctionArguments args;
+ args.geometryUserPtr = userPtr;
+ args.primID = (unsigned int)i;
+ args.timeStep = (unsigned int)(itime+0);
+ args.bounds_o = (RTCBounds*)&box[0];
+ boundsFunc(&args);
+ args.timeStep = (unsigned int)(itime+1);
+ args.bounds_o = (RTCBounds*)&box[1];
+ boundsFunc(&args);
+ return LBBox3fa(box[0],box[1]);
+ }
+
+ /*! calculates the build bounds of the i'th item, if it's valid */
+ __forceinline bool buildBounds(size_t i, BBox3fa* bbox = nullptr) const
+ {
+ const BBox3fa b = bounds(i);
+ if (bbox) *bbox = b;
+ return isvalid_non_empty(b);
+ }
+
+ /*! calculates the build bounds of the i'th item at the itime'th time segment, if it's valid */
+ __forceinline bool buildBounds(size_t i, size_t itime, BBox3fa& bbox) const
+ {
+ const LBBox3fa bounds = linearBounds(i,itime);
+ bbox = bounds.bounds0; // use bounding box of first timestep to build BVH
+ return isvalid_non_empty(bounds);
+ }
+
+ /*! calculates the linear bounds of the i'th primitive for the specified time range */
+ __forceinline LBBox3fa linearBounds(size_t primID, const BBox1f& dt) const {
+ return LBBox3fa([&] (size_t itime) { return bounds(primID, itime); }, dt, time_range, fnumTimeSegments);
+ }
+
+ /*! calculates the linear bounds of the i'th primitive for the specified time range */
+ __forceinline bool linearBounds(size_t i, const BBox1f& time_range, LBBox3fa& bbox) const {
+ if (!valid(i, timeSegmentRange(time_range))) return false;
+ bbox = linearBounds(i, time_range);
+ return true;
+ }
+
+ /* gets version info of topology */
+ unsigned int getTopologyVersion() const {
+ return numPrimitives;
+ }
+
+ /* returns true if topology changed */
+ bool topologyChanged(unsigned int otherVersion) const {
+ return numPrimitives != otherVersion;
+ }
+
+ public:
+
+ /*! Intersects a single ray with the scene. */
+ __forceinline void intersect (RayHit& ray, unsigned int geomID, unsigned int primID, IntersectContext* context, ReportIntersectionFunc report)
+ {
+ assert(primID < size());
+ assert(intersectorN.intersect);
+
+ int mask = -1;
+ IntersectFunctionNArguments args;
+ args.valid = &mask;
+ args.geometryUserPtr = userPtr;
+ args.context = context->user;
+ args.rayhit = (RTCRayHitN*)&ray;
+ args.N = 1;
+ args.geomID = geomID;
+ args.primID = primID;
+ args.internal_context = context;
+ args.geometry = this;
+ args.report = report;
+
+ intersectorN.intersect(&args);
+ }
+
+ /*! Tests if single ray is occluded by the scene. */
+ __forceinline void occluded (Ray& ray, unsigned int geomID, unsigned int primID, IntersectContext* context, ReportOcclusionFunc report)
+ {
+ assert(primID < size());
+ assert(intersectorN.occluded);
+
+ int mask = -1;
+ OccludedFunctionNArguments args;
+ args.valid = &mask;
+ args.geometryUserPtr = userPtr;
+ args.context = context->user;
+ args.ray = (RTCRayN*)&ray;
+ args.N = 1;
+ args.geomID = geomID;
+ args.primID = primID;
+ args.internal_context = context;
+ args.geometry = this;
+ args.report = report;
+
+ intersectorN.occluded(&args);
+ }
+
+ /*! Intersects a packet of K rays with the scene. */
+ template<int K>
+ __forceinline void intersect (const vbool<K>& valid, RayHitK<K>& ray, unsigned int geomID, unsigned int primID, IntersectContext* context, ReportIntersectionFunc report)
+ {
+ assert(primID < size());
+ assert(intersectorN.intersect);
+
+ vint<K> mask = valid.mask32();
+ IntersectFunctionNArguments args;
+ args.valid = (int*)&mask;
+ args.geometryUserPtr = userPtr;
+ args.context = context->user;
+ args.rayhit = (RTCRayHitN*)&ray;
+ args.N = K;
+ args.geomID = geomID;
+ args.primID = primID;
+ args.internal_context = context;
+ args.geometry = this;
+ args.report = report;
+
+ intersectorN.intersect(&args);
+ }
+
+ /*! Tests if a packet of K rays is occluded by the scene. */
+ template<int K>
+ __forceinline void occluded (const vbool<K>& valid, RayK<K>& ray, unsigned int geomID, unsigned int primID, IntersectContext* context, ReportOcclusionFunc report)
+ {
+ assert(primID < size());
+ assert(intersectorN.occluded);
+
+ vint<K> mask = valid.mask32();
+ OccludedFunctionNArguments args;
+ args.valid = (int*)&mask;
+ args.geometryUserPtr = userPtr;
+ args.context = context->user;
+ args.ray = (RTCRayN*)&ray;
+ args.N = K;
+ args.geomID = geomID;
+ args.primID = primID;
+ args.internal_context = context;
+ args.geometry = this;
+ args.report = report;
+
+ intersectorN.occluded(&args);
+ }
+
+ public:
+ RTCBoundsFunction boundsFunc;
+ IntersectorN intersectorN;
+ };
+
+#define DEFINE_SET_INTERSECTORN(symbol,intersector) \
+ AccelSet::IntersectorN symbol() { \
+ return AccelSet::IntersectorN(intersector::intersect, \
+ intersector::occluded, \
+ TOSTRING(isa) "::" TOSTRING(symbol)); \
+ }
+}