accelset.h 11 KB

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