bvh_node_ref.h 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. // Copyright 2009-2020 Intel Corporation
  2. // SPDX-License-Identifier: Apache-2.0
  3. #pragma once
  4. #include "../common/default.h"
  5. #include "../common/alloc.h"
  6. #include "../common/accel.h"
  7. #include "../common/device.h"
  8. #include "../common/scene.h"
  9. #include "../geometry/primitive.h"
  10. #include "../common/ray.h"
  11. namespace embree
  12. {
  13. /* BVH node reference with bounds */
  14. template<typename NodeRef>
  15. struct BVHNodeRecord
  16. {
  17. __forceinline BVHNodeRecord() {}
  18. __forceinline BVHNodeRecord(NodeRef ref, const BBox3fa& bounds) : ref(ref), bounds((BBox3fx)bounds) {}
  19. __forceinline BVHNodeRecord(NodeRef ref, const BBox3fx& bounds) : ref(ref), bounds(bounds) {}
  20. NodeRef ref;
  21. BBox3fx bounds;
  22. };
  23. template<typename NodeRef>
  24. struct BVHNodeRecordMB
  25. {
  26. __forceinline BVHNodeRecordMB() {}
  27. __forceinline BVHNodeRecordMB(NodeRef ref, const LBBox3fa& lbounds) : ref(ref), lbounds(lbounds) {}
  28. NodeRef ref;
  29. LBBox3fa lbounds;
  30. };
  31. template<typename NodeRef>
  32. struct BVHNodeRecordMB4D
  33. {
  34. __forceinline BVHNodeRecordMB4D() {}
  35. __forceinline BVHNodeRecordMB4D(NodeRef ref, const LBBox3fa& lbounds, const BBox1f& dt) : ref(ref), lbounds(lbounds), dt(dt) {}
  36. NodeRef ref;
  37. LBBox3fa lbounds;
  38. BBox1f dt;
  39. };
  40. template<typename NodeRef, int N> struct BaseNode_t;
  41. template<typename NodeRef, int N> struct AABBNode_t;
  42. template<typename NodeRef, int N> struct AABBNodeMB_t;
  43. template<typename NodeRef, int N> struct AABBNodeMB4D_t;
  44. template<typename NodeRef, int N> struct OBBNode_t;
  45. template<typename NodeRef, int N> struct OBBNodeMB_t;
  46. template<typename NodeRef, int N> struct QuantizedNode_t;
  47. template<typename NodeRef, int N> struct QuantizedNodeMB_t;
  48. /*! Pointer that points to a node or a list of primitives */
  49. template<int N>
  50. struct NodeRefPtr
  51. {
  52. //template<int NN> friend class BVHN;
  53. /*! Number of bytes the nodes and primitives are minimally aligned to.*/
  54. static const size_t byteAlignment = 16;
  55. static const size_t byteNodeAlignment = 4*N;
  56. /*! highest address bit is used as barrier for some algorithms */
  57. static const size_t barrier_mask = (1LL << (8*sizeof(size_t)-1));
  58. /*! Masks the bits that store the number of items per leaf. */
  59. static const size_t align_mask = byteAlignment-1;
  60. static const size_t items_mask = byteAlignment-1;
  61. /*! different supported node types */
  62. static const size_t tyAABBNode = 0;
  63. static const size_t tyAABBNodeMB = 1;
  64. static const size_t tyAABBNodeMB4D = 6;
  65. static const size_t tyOBBNode = 2;
  66. static const size_t tyOBBNodeMB = 3;
  67. static const size_t tyQuantizedNode = 5;
  68. static const size_t tyLeaf = 8;
  69. /*! Empty node */
  70. static const size_t emptyNode = tyLeaf;
  71. /*! Invalid node, used as marker in traversal */
  72. static const size_t invalidNode = (((size_t)-1) & (~items_mask)) | (tyLeaf+0);
  73. static const size_t popRay = (((size_t)-1) & (~items_mask)) | (tyLeaf+1);
  74. /*! Maximum number of primitive blocks in a leaf. */
  75. static const size_t maxLeafBlocks = items_mask-tyLeaf;
  76. /*! Default constructor */
  77. __forceinline NodeRefPtr () {}
  78. /*! Construction from integer */
  79. __forceinline NodeRefPtr (size_t ptr) : ptr(ptr) {}
  80. /*! Cast to size_t */
  81. __forceinline operator size_t() const { return ptr; }
  82. /*! Sets the barrier bit. */
  83. __forceinline void setBarrier() {
  84. #if defined(__X86_64__) || defined(__aarch64__)
  85. assert(!isBarrier());
  86. ptr |= barrier_mask;
  87. #else
  88. assert(false);
  89. #endif
  90. }
  91. /*! Clears the barrier bit. */
  92. __forceinline void clearBarrier() {
  93. #if defined(__X86_64__) || defined(__aarch64__)
  94. ptr &= ~barrier_mask;
  95. #else
  96. assert(false);
  97. #endif
  98. }
  99. /*! Checks if this is an barrier. A barrier tells the top level tree rotations how deep to enter the tree. */
  100. __forceinline bool isBarrier() const { return (ptr & barrier_mask) != 0; }
  101. /*! checks if this is a leaf */
  102. __forceinline size_t isLeaf() const { return ptr & tyLeaf; }
  103. /*! returns node type */
  104. __forceinline int type() const { return ptr & (size_t)align_mask; }
  105. /*! checks if this is a node */
  106. __forceinline int isAABBNode() const { return (ptr & (size_t)align_mask) == tyAABBNode; }
  107. /*! checks if this is a motion blur node */
  108. __forceinline int isAABBNodeMB() const { return (ptr & (size_t)align_mask) == tyAABBNodeMB; }
  109. /*! checks if this is a 4D motion blur node */
  110. __forceinline int isAABBNodeMB4D() const { return (ptr & (size_t)align_mask) == tyAABBNodeMB4D; }
  111. /*! checks if this is a node with unaligned bounding boxes */
  112. __forceinline int isOBBNode() const { return (ptr & (size_t)align_mask) == tyOBBNode; }
  113. /*! checks if this is a motion blur node with unaligned bounding boxes */
  114. __forceinline int isOBBNodeMB() const { return (ptr & (size_t)align_mask) == tyOBBNodeMB; }
  115. /*! checks if this is a quantized node */
  116. __forceinline int isQuantizedNode() const { return (ptr & (size_t)align_mask) == tyQuantizedNode; }
  117. /*! Encodes a node */
  118. static __forceinline NodeRefPtr encodeNode(AABBNode_t<NodeRefPtr,N>* node) {
  119. assert(!((size_t)node & align_mask));
  120. return NodeRefPtr((size_t) node);
  121. }
  122. static __forceinline NodeRefPtr encodeNode(AABBNodeMB_t<NodeRefPtr,N>* node) {
  123. assert(!((size_t)node & align_mask));
  124. return NodeRefPtr((size_t) node | tyAABBNodeMB);
  125. }
  126. static __forceinline NodeRefPtr encodeNode(AABBNodeMB4D_t<NodeRefPtr,N>* node) {
  127. assert(!((size_t)node & align_mask));
  128. return NodeRefPtr((size_t) node | tyAABBNodeMB4D);
  129. }
  130. /*! Encodes an unaligned node */
  131. static __forceinline NodeRefPtr encodeNode(OBBNode_t<NodeRefPtr,N>* node) {
  132. return NodeRefPtr((size_t) node | tyOBBNode);
  133. }
  134. /*! Encodes an unaligned motion blur node */
  135. static __forceinline NodeRefPtr encodeNode(OBBNodeMB_t<NodeRefPtr,N>* node) {
  136. return NodeRefPtr((size_t) node | tyOBBNodeMB);
  137. }
  138. /*! Encodes a leaf */
  139. static __forceinline NodeRefPtr encodeLeaf(void* tri, size_t num) {
  140. assert(!((size_t)tri & align_mask));
  141. assert(num <= maxLeafBlocks);
  142. return NodeRefPtr((size_t)tri | (tyLeaf+min(num,(size_t)maxLeafBlocks)));
  143. }
  144. /*! Encodes a leaf */
  145. static __forceinline NodeRefPtr encodeTypedLeaf(void* ptr, size_t ty) {
  146. assert(!((size_t)ptr & align_mask));
  147. return NodeRefPtr((size_t)ptr | (tyLeaf+ty));
  148. }
  149. /*! returns base node pointer */
  150. __forceinline BaseNode_t<NodeRefPtr,N>* baseNode()
  151. {
  152. assert(!isLeaf());
  153. return (BaseNode_t<NodeRefPtr,N>*)(ptr & ~(size_t)align_mask);
  154. }
  155. __forceinline const BaseNode_t<NodeRefPtr,N>* baseNode() const
  156. {
  157. assert(!isLeaf());
  158. return (const BaseNode_t<NodeRefPtr,N>*)(ptr & ~(size_t)align_mask);
  159. }
  160. /*! returns node pointer */
  161. __forceinline AABBNode_t<NodeRefPtr,N>* getAABBNode() { assert(isAABBNode()); return ( AABBNode_t<NodeRefPtr,N>*)ptr; }
  162. __forceinline const AABBNode_t<NodeRefPtr,N>* getAABBNode() const { assert(isAABBNode()); return (const AABBNode_t<NodeRefPtr,N>*)ptr; }
  163. /*! returns motion blur node pointer */
  164. __forceinline AABBNodeMB_t<NodeRefPtr,N>* getAABBNodeMB() { assert(isAABBNodeMB() || isAABBNodeMB4D()); return ( AABBNodeMB_t<NodeRefPtr,N>*)(ptr & ~(size_t)align_mask); }
  165. __forceinline const AABBNodeMB_t<NodeRefPtr,N>* getAABBNodeMB() const { assert(isAABBNodeMB() || isAABBNodeMB4D()); return (const AABBNodeMB_t<NodeRefPtr,N>*)(ptr & ~(size_t)align_mask); }
  166. /*! returns 4D motion blur node pointer */
  167. __forceinline AABBNodeMB4D_t<NodeRefPtr,N>* getAABBNodeMB4D() { assert(isAABBNodeMB4D()); return ( AABBNodeMB4D_t<NodeRefPtr,N>*)(ptr & ~(size_t)align_mask); }
  168. __forceinline const AABBNodeMB4D_t<NodeRefPtr,N>* getAABBNodeMB4D() const { assert(isAABBNodeMB4D()); return (const AABBNodeMB4D_t<NodeRefPtr,N>*)(ptr & ~(size_t)align_mask); }
  169. /*! returns unaligned node pointer */
  170. __forceinline OBBNode_t<NodeRefPtr,N>* ungetAABBNode() { assert(isOBBNode()); return ( OBBNode_t<NodeRefPtr,N>*)(ptr & ~(size_t)align_mask); }
  171. __forceinline const OBBNode_t<NodeRefPtr,N>* ungetAABBNode() const { assert(isOBBNode()); return (const OBBNode_t<NodeRefPtr,N>*)(ptr & ~(size_t)align_mask); }
  172. /*! returns unaligned motion blur node pointer */
  173. __forceinline OBBNodeMB_t<NodeRefPtr,N>* ungetAABBNodeMB() { assert(isOBBNodeMB()); return ( OBBNodeMB_t<NodeRefPtr,N>*)(ptr & ~(size_t)align_mask); }
  174. __forceinline const OBBNodeMB_t<NodeRefPtr,N>* ungetAABBNodeMB() const { assert(isOBBNodeMB()); return (const OBBNodeMB_t<NodeRefPtr,N>*)(ptr & ~(size_t)align_mask); }
  175. /*! returns quantized node pointer */
  176. __forceinline QuantizedNode_t<NodeRefPtr,N>* quantizedNode() { assert(isQuantizedNode()); return ( QuantizedNode_t<NodeRefPtr,N>*)(ptr & ~(size_t)align_mask ); }
  177. __forceinline const QuantizedNode_t<NodeRefPtr,N>* quantizedNode() const { assert(isQuantizedNode()); return (const QuantizedNode_t<NodeRefPtr,N>*)(ptr & ~(size_t)align_mask ); }
  178. /*! returns leaf pointer */
  179. __forceinline char* leaf(size_t& num) const {
  180. assert(isLeaf());
  181. num = (ptr & (size_t)items_mask)-tyLeaf;
  182. return (char*)(ptr & ~(size_t)align_mask);
  183. }
  184. /*! clear all bit flags */
  185. __forceinline void clearFlags() {
  186. ptr &= ~(size_t)align_mask;
  187. }
  188. /*! returns the wideness */
  189. __forceinline size_t getN() const { return N; }
  190. public:
  191. size_t ptr;
  192. };
  193. }