accelset.h 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  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. typedef void (*ReportIntersectionFunc) (IntersectFunctionNArguments* args, const RTCFilterFunctionNArguments* filter_args);
  14. typedef void (*ReportOcclusionFunc) (OccludedFunctionNArguments* args, const RTCFilterFunctionNArguments* filter_args);
  15. struct IntersectFunctionNArguments : public RTCIntersectFunctionNArguments
  16. {
  17. IntersectContext* internal_context;
  18. Geometry* geometry;
  19. ReportIntersectionFunc report;
  20. };
  21. struct OccludedFunctionNArguments : public RTCOccludedFunctionNArguments
  22. {
  23. IntersectContext* internal_context;
  24. Geometry* geometry;
  25. ReportOcclusionFunc report;
  26. };
  27. /*! Base class for set of acceleration structures. */
  28. class AccelSet : public Geometry
  29. {
  30. public:
  31. typedef RTCIntersectFunctionN IntersectFuncN;
  32. typedef RTCOccludedFunctionN OccludedFuncN;
  33. typedef void (*ErrorFunc) ();
  34. struct IntersectorN
  35. {
  36. IntersectorN (ErrorFunc error = nullptr) ;
  37. IntersectorN (IntersectFuncN intersect, OccludedFuncN occluded, const char* name);
  38. operator bool() const { return name; }
  39. public:
  40. static const char* type;
  41. IntersectFuncN intersect;
  42. OccludedFuncN occluded;
  43. const char* name;
  44. };
  45. public:
  46. /*! construction */
  47. AccelSet (Device* device, Geometry::GType gtype, size_t items, size_t numTimeSteps);
  48. /*! makes the acceleration structure immutable */
  49. virtual void immutable () {}
  50. /*! build accel */
  51. virtual void build () = 0;
  52. /*! check if the i'th primitive is valid between the specified time range */
  53. __forceinline bool valid(size_t i, const range<size_t>& itime_range) const
  54. {
  55. for (size_t itime = itime_range.begin(); itime <= itime_range.end(); itime++)
  56. if (!isvalid_non_empty(bounds(i,itime))) return false;
  57. return true;
  58. }
  59. /*! Calculates the bounds of an item */
  60. __forceinline BBox3fa bounds(size_t i, size_t itime = 0) const
  61. {
  62. BBox3fa box;
  63. assert(i < size());
  64. RTCBoundsFunctionArguments args;
  65. args.geometryUserPtr = userPtr;
  66. args.primID = (unsigned int)i;
  67. args.timeStep = (unsigned int)itime;
  68. args.bounds_o = (RTCBounds*)&box;
  69. boundsFunc(&args);
  70. return box;
  71. }
  72. /*! calculates the linear bounds of the i'th item at the itime'th time segment */
  73. __forceinline LBBox3fa linearBounds(size_t i, size_t itime) const
  74. {
  75. BBox3fa box[2];
  76. assert(i < size());
  77. RTCBoundsFunctionArguments args;
  78. args.geometryUserPtr = userPtr;
  79. args.primID = (unsigned int)i;
  80. args.timeStep = (unsigned int)(itime+0);
  81. args.bounds_o = (RTCBounds*)&box[0];
  82. boundsFunc(&args);
  83. args.timeStep = (unsigned int)(itime+1);
  84. args.bounds_o = (RTCBounds*)&box[1];
  85. boundsFunc(&args);
  86. return LBBox3fa(box[0],box[1]);
  87. }
  88. /*! calculates the build bounds of the i'th item, if it's valid */
  89. __forceinline bool buildBounds(size_t i, BBox3fa* bbox = nullptr) const
  90. {
  91. const BBox3fa b = bounds(i);
  92. if (bbox) *bbox = b;
  93. return isvalid_non_empty(b);
  94. }
  95. /*! calculates the build bounds of the i'th item at the itime'th time segment, if it's valid */
  96. __forceinline bool buildBounds(size_t i, size_t itime, BBox3fa& bbox) const
  97. {
  98. const LBBox3fa bounds = linearBounds(i,itime);
  99. bbox = bounds.bounds0; // use bounding box of first timestep to build BVH
  100. return isvalid_non_empty(bounds);
  101. }
  102. /*! calculates the linear bounds of the i'th primitive for the specified time range */
  103. __forceinline LBBox3fa linearBounds(size_t primID, const BBox1f& dt) const {
  104. return LBBox3fa([&] (size_t itime) { return bounds(primID, itime); }, dt, time_range, fnumTimeSegments);
  105. }
  106. /*! calculates the linear bounds of the i'th primitive for the specified time range */
  107. __forceinline bool linearBounds(size_t i, const BBox1f& time_range, LBBox3fa& bbox) const {
  108. if (!valid(i, timeSegmentRange(time_range))) return false;
  109. bbox = linearBounds(i, time_range);
  110. return true;
  111. }
  112. /* gets version info of topology */
  113. unsigned int getTopologyVersion() const {
  114. return numPrimitives;
  115. }
  116. /* returns true if topology changed */
  117. bool topologyChanged(unsigned int otherVersion) const {
  118. return numPrimitives != otherVersion;
  119. }
  120. public:
  121. /*! Intersects a single ray with the scene. */
  122. __forceinline void intersect (RayHit& ray, unsigned int geomID, unsigned int primID, IntersectContext* context, ReportIntersectionFunc report)
  123. {
  124. assert(primID < size());
  125. assert(intersectorN.intersect);
  126. int mask = -1;
  127. IntersectFunctionNArguments args;
  128. args.valid = &mask;
  129. args.geometryUserPtr = userPtr;
  130. args.context = context->user;
  131. args.rayhit = (RTCRayHitN*)&ray;
  132. args.N = 1;
  133. args.geomID = geomID;
  134. args.primID = primID;
  135. args.internal_context = context;
  136. args.geometry = this;
  137. args.report = report;
  138. intersectorN.intersect(&args);
  139. }
  140. /*! Tests if single ray is occluded by the scene. */
  141. __forceinline void occluded (Ray& ray, unsigned int geomID, unsigned int primID, IntersectContext* context, ReportOcclusionFunc report)
  142. {
  143. assert(primID < size());
  144. assert(intersectorN.occluded);
  145. int mask = -1;
  146. OccludedFunctionNArguments args;
  147. args.valid = &mask;
  148. args.geometryUserPtr = userPtr;
  149. args.context = context->user;
  150. args.ray = (RTCRayN*)&ray;
  151. args.N = 1;
  152. args.geomID = geomID;
  153. args.primID = primID;
  154. args.internal_context = context;
  155. args.geometry = this;
  156. args.report = report;
  157. intersectorN.occluded(&args);
  158. }
  159. /*! Intersects a packet of K rays with the scene. */
  160. template<int K>
  161. __forceinline void intersect (const vbool<K>& valid, RayHitK<K>& ray, unsigned int geomID, unsigned int primID, IntersectContext* context, ReportIntersectionFunc report)
  162. {
  163. assert(primID < size());
  164. assert(intersectorN.intersect);
  165. vint<K> mask = valid.mask32();
  166. IntersectFunctionNArguments args;
  167. args.valid = (int*)&mask;
  168. args.geometryUserPtr = userPtr;
  169. args.context = context->user;
  170. args.rayhit = (RTCRayHitN*)&ray;
  171. args.N = K;
  172. args.geomID = geomID;
  173. args.primID = primID;
  174. args.internal_context = context;
  175. args.geometry = this;
  176. args.report = report;
  177. intersectorN.intersect(&args);
  178. }
  179. /*! Tests if a packet of K rays is occluded by the scene. */
  180. template<int K>
  181. __forceinline void occluded (const vbool<K>& valid, RayK<K>& ray, unsigned int geomID, unsigned int primID, IntersectContext* context, ReportOcclusionFunc report)
  182. {
  183. assert(primID < size());
  184. assert(intersectorN.occluded);
  185. vint<K> mask = valid.mask32();
  186. OccludedFunctionNArguments args;
  187. args.valid = (int*)&mask;
  188. args.geometryUserPtr = userPtr;
  189. args.context = context->user;
  190. args.ray = (RTCRayN*)&ray;
  191. args.N = K;
  192. args.geomID = geomID;
  193. args.primID = primID;
  194. args.internal_context = context;
  195. args.geometry = this;
  196. args.report = report;
  197. intersectorN.occluded(&args);
  198. }
  199. public:
  200. RTCBoundsFunction boundsFunc;
  201. IntersectorN intersectorN;
  202. };
  203. #define DEFINE_SET_INTERSECTORN(symbol,intersector) \
  204. AccelSet::IntersectorN symbol() { \
  205. return AccelSet::IntersectorN(intersector::intersect, \
  206. intersector::occluded, \
  207. TOSTRING(isa) "::" TOSTRING(symbol)); \
  208. }
  209. }