primref_mb.h 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. // Copyright 2009-2021 Intel Corporation
  2. // SPDX-License-Identifier: Apache-2.0
  3. #pragma once
  4. #include "default.h"
  5. #define MBLUR_BIN_LBBOX 1
  6. namespace embree
  7. {
  8. #if MBLUR_BIN_LBBOX
  9. /*! A primitive reference stores the bounds of the primitive and its ID. */
  10. struct PrimRefMB
  11. {
  12. typedef LBBox3fa BBox;
  13. __forceinline PrimRefMB () {}
  14. __forceinline PrimRefMB (const LBBox3fa& lbounds_i, unsigned int activeTimeSegments, BBox1f time_range, unsigned int totalTimeSegments, unsigned int geomID, unsigned int primID)
  15. : lbounds((LBBox3fx)lbounds_i), time_range(time_range)
  16. {
  17. assert(activeTimeSegments > 0);
  18. lbounds.bounds0.lower.a = geomID;
  19. lbounds.bounds0.upper.a = primID;
  20. lbounds.bounds1.lower.a = activeTimeSegments;
  21. lbounds.bounds1.upper.a = totalTimeSegments;
  22. }
  23. __forceinline PrimRefMB (EmptyTy empty, const LBBox3fa& lbounds_i, unsigned int activeTimeSegments, BBox1f time_range, unsigned int totalTimeSegments, size_t id)
  24. : lbounds((LBBox3fx)lbounds_i), time_range(time_range)
  25. {
  26. assert(activeTimeSegments > 0);
  27. #if defined(__64BIT__)
  28. lbounds.bounds0.lower.a = id & 0xFFFFFFFF;
  29. lbounds.bounds0.upper.a = (id >> 32) & 0xFFFFFFFF;
  30. #else
  31. lbounds.bounds0.lower.a = id;
  32. lbounds.bounds0.upper.a = 0;
  33. #endif
  34. lbounds.bounds1.lower.a = activeTimeSegments;
  35. lbounds.bounds1.upper.a = totalTimeSegments;
  36. }
  37. __forceinline PrimRefMB (const LBBox3fa& lbounds_i, unsigned int activeTimeSegments, BBox1f time_range, unsigned int totalTimeSegments, size_t id)
  38. : lbounds((LBBox3fx)lbounds_i), time_range(time_range)
  39. {
  40. assert(activeTimeSegments > 0);
  41. #if defined(__64BIT__)
  42. lbounds.bounds0.lower.u = id & 0xFFFFFFFF;
  43. lbounds.bounds0.upper.u = (id >> 32) & 0xFFFFFFFF;
  44. #else
  45. lbounds.bounds0.lower.u = id;
  46. lbounds.bounds0.upper.u = 0;
  47. #endif
  48. lbounds.bounds1.lower.a = activeTimeSegments;
  49. lbounds.bounds1.upper.a = totalTimeSegments;
  50. }
  51. /*! returns bounds for binning */
  52. __forceinline LBBox3fa bounds() const {
  53. return lbounds;
  54. }
  55. /*! returns the number of time segments of this primref */
  56. __forceinline unsigned size() const {
  57. return lbounds.bounds1.lower.a;
  58. }
  59. __forceinline unsigned totalTimeSegments() const {
  60. return lbounds.bounds1.upper.a;
  61. }
  62. /* calculate overlapping time segment range */
  63. __forceinline range<int> timeSegmentRange(const BBox1f& range) const {
  64. return getTimeSegmentRange(range,time_range,float(totalTimeSegments()));
  65. }
  66. /* returns time that corresponds to time step */
  67. __forceinline float timeStep(const int i) const {
  68. assert(i>=0 && i<=(int)totalTimeSegments());
  69. return time_range.lower + time_range.size()*float(i)/float(totalTimeSegments());
  70. }
  71. /*! checks if time range overlaps */
  72. __forceinline bool time_range_overlap(const BBox1f& range) const
  73. {
  74. if (0.9999f*time_range.upper <= range.lower) return false;
  75. if (1.0001f*time_range.lower >= range.upper) return false;
  76. return true;
  77. }
  78. /*! returns center for binning */
  79. __forceinline Vec3fa binCenter() const {
  80. return center2(lbounds.interpolate(0.5f));
  81. }
  82. /*! returns bounds and centroid used for binning */
  83. __forceinline void binBoundsAndCenter(LBBox3fa& bounds_o, Vec3fa& center_o) const
  84. {
  85. bounds_o = bounds();
  86. center_o = binCenter();
  87. }
  88. /*! returns the geometry ID */
  89. __forceinline unsigned geomID() const {
  90. return lbounds.bounds0.lower.a;
  91. }
  92. /*! returns the primitive ID */
  93. __forceinline unsigned primID() const {
  94. return lbounds.bounds0.upper.a;
  95. }
  96. /*! returns an size_t sized ID */
  97. __forceinline size_t ID() const {
  98. #if defined(__64BIT__)
  99. return size_t(lbounds.bounds0.lower.u) + (size_t(lbounds.bounds0.upper.u) << 32);
  100. #else
  101. return size_t(lbounds.bounds0.lower.u);
  102. #endif
  103. }
  104. /*! special function for operator< */
  105. __forceinline uint64_t ID64() const {
  106. return (((uint64_t)primID()) << 32) + (uint64_t)geomID();
  107. }
  108. /*! allows sorting the primrefs by ID */
  109. friend __forceinline bool operator<(const PrimRefMB& p0, const PrimRefMB& p1) {
  110. return p0.ID64() < p1.ID64();
  111. }
  112. /*! Outputs primitive reference to a stream. */
  113. friend __forceinline embree_ostream operator<<(embree_ostream cout, const PrimRefMB& ref) {
  114. return cout << "{ time_range = " << ref.time_range << ", bounds = " << ref.bounds() << ", geomID = " << ref.geomID() << ", primID = " << ref.primID() << ", active_segments = " << ref.size() << ", total_segments = " << ref.totalTimeSegments() << " }";
  115. }
  116. public:
  117. LBBox3fx lbounds;
  118. BBox1f time_range; // entire geometry time range
  119. };
  120. #else
  121. /*! A primitive reference stores the bounds of the primitive and its ID. */
  122. struct __aligned(16) PrimRefMB
  123. {
  124. typedef BBox3fa BBox;
  125. __forceinline PrimRefMB () {}
  126. __forceinline PrimRefMB (const LBBox3fa& bounds, unsigned int activeTimeSegments, BBox1f time_range, unsigned int totalTimeSegments, unsigned int geomID, unsigned int primID)
  127. : bbox(bounds.interpolate(0.5f)), _activeTimeSegments(activeTimeSegments), _totalTimeSegments(totalTimeSegments), time_range(time_range)
  128. {
  129. assert(activeTimeSegments > 0);
  130. bbox.lower.a = geomID;
  131. bbox.upper.a = primID;
  132. }
  133. __forceinline PrimRefMB (EmptyTy empty, const LBBox3fa& bounds, unsigned int activeTimeSegments, BBox1f time_range, unsigned int totalTimeSegments, size_t id)
  134. : bbox(bounds.interpolate(0.5f)), _activeTimeSegments(activeTimeSegments), _totalTimeSegments(totalTimeSegments), time_range(time_range)
  135. {
  136. assert(activeTimeSegments > 0);
  137. #if defined(__64BIT__)
  138. bbox.lower.u = id & 0xFFFFFFFF;
  139. bbox.upper.u = (id >> 32) & 0xFFFFFFFF;
  140. #else
  141. bbox.lower.u = id;
  142. bbox.upper.u = 0;
  143. #endif
  144. }
  145. /*! returns bounds for binning */
  146. __forceinline BBox3fa bounds() const {
  147. return bbox;
  148. }
  149. /*! returns the number of time segments of this primref */
  150. __forceinline unsigned int size() const {
  151. return _activeTimeSegments;
  152. }
  153. __forceinline unsigned int totalTimeSegments() const {
  154. return _totalTimeSegments;
  155. }
  156. /* calculate overlapping time segment range */
  157. __forceinline range<int> timeSegmentRange(const BBox1f& range) const {
  158. return getTimeSegmentRange(range,time_range,float(_totalTimeSegments));
  159. }
  160. /* returns time that corresponds to time step */
  161. __forceinline float timeStep(const int i) const {
  162. assert(i>=0 && i<=(int)_totalTimeSegments);
  163. return time_range.lower + time_range.size()*float(i)/float(_totalTimeSegments);
  164. }
  165. /*! checks if time range overlaps */
  166. __forceinline bool time_range_overlap(const BBox1f& range) const
  167. {
  168. if (0.9999f*time_range.upper <= range.lower) return false;
  169. if (1.0001f*time_range.lower >= range.upper) return false;
  170. return true;
  171. }
  172. /*! returns center for binning */
  173. __forceinline Vec3fa binCenter() const {
  174. return center2(bounds());
  175. }
  176. /*! returns bounds and centroid used for binning */
  177. __forceinline void binBoundsAndCenter(BBox3fa& bounds_o, Vec3fa& center_o) const
  178. {
  179. bounds_o = bounds();
  180. center_o = center2(bounds());
  181. }
  182. /*! returns the geometry ID */
  183. __forceinline unsigned int geomID() const {
  184. return bbox.lower.a;
  185. }
  186. /*! returns the primitive ID */
  187. __forceinline unsigned int primID() const {
  188. return bbox.upper.a;
  189. }
  190. /*! returns an size_t sized ID */
  191. __forceinline size_t ID() const {
  192. #if defined(__64BIT__)
  193. return size_t(bbox.lower.u) + (size_t(bbox.upper.u) << 32);
  194. #else
  195. return size_t(bbox.lower.u);
  196. #endif
  197. }
  198. /*! special function for operator< */
  199. __forceinline uint64_t ID64() const {
  200. return (((uint64_t)primID()) << 32) + (uint64_t)geomID();
  201. }
  202. /*! allows sorting the primrefs by ID */
  203. friend __forceinline bool operator<(const PrimRefMB& p0, const PrimRefMB& p1) {
  204. return p0.ID64() < p1.ID64();
  205. }
  206. /*! Outputs primitive reference to a stream. */
  207. friend __forceinline embree_ostream operator<<(embree_ostream cout, const PrimRefMB& ref) {
  208. return cout << "{ bounds = " << ref.bounds() << ", geomID = " << ref.geomID() << ", primID = " << ref.primID() << ", active_segments = " << ref.size() << ", total_segments = " << ref.totalTimeSegments() << " }";
  209. }
  210. public:
  211. BBox3fa bbox; // bounds, geomID, primID
  212. unsigned int _activeTimeSegments;
  213. unsigned int _totalTimeSegments;
  214. BBox1f time_range; // entire geometry time range
  215. };
  216. #endif
  217. }