accelset.h 7.4 KB

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