bvh_intersector1.cpp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. // ======================================================================== //
  2. // Copyright 2009-2017 Intel Corporation //
  3. // //
  4. // Licensed under the Apache License, Version 2.0 (the "License"); //
  5. // you may not use this file except in compliance with the License. //
  6. // You may obtain a copy of the License at //
  7. // //
  8. // http://www.apache.org/licenses/LICENSE-2.0 //
  9. // //
  10. // Unless required by applicable law or agreed to in writing, software //
  11. // distributed under the License is distributed on an "AS IS" BASIS, //
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
  13. // See the License for the specific language governing permissions and //
  14. // limitations under the License. //
  15. // ======================================================================== //
  16. #include "bvh_intersector1.h"
  17. #include "bvh_intersector_node.h"
  18. #include "bvh_traverser1.h"
  19. #include "../geometry/intersector_iterators.h"
  20. #include "../geometry/triangle_intersector.h"
  21. #include "../geometry/trianglev_intersector.h"
  22. #include "../geometry/trianglev_mb_intersector.h"
  23. #include "../geometry/trianglei_intersector.h"
  24. #include "../geometry/trianglei_mb_intersector.h"
  25. #include "../geometry/quadv_intersector.h"
  26. #include "../geometry/quadi_intersector.h"
  27. #include "../geometry/quadi_mb_intersector.h"
  28. #include "../geometry/bezier1v_intersector.h"
  29. #include "../geometry/bezier1i_intersector.h"
  30. #include "../geometry/linei_intersector.h"
  31. #include "../geometry/subdivpatch1eager_intersector.h"
  32. #include "../geometry/subdivpatch1cached_intersector.h"
  33. #include "../geometry/object_intersector.h"
  34. namespace embree
  35. {
  36. namespace isa
  37. {
  38. template<int N, int types, bool robust, typename PrimitiveIntersector1>
  39. void BVHNIntersector1<N,types,robust,PrimitiveIntersector1>::intersect(const BVH* __restrict__ bvh, Ray& __restrict__ ray, IntersectContext* context)
  40. {
  41. /*! perform per ray precalculations required by the primitive intersector */
  42. Precalculations pre(ray,bvh,bvh->numTimeSteps);
  43. /*! stack state */
  44. StackItemT<NodeRef> stack[stackSize]; //!< stack of nodes
  45. StackItemT<NodeRef>* stackPtr = stack+1; //!< current stack pointer
  46. StackItemT<NodeRef>* stackEnd = stack+stackSize;
  47. stack[0].ptr = bvh->getRoot(pre);
  48. stack[0].dist = neg_inf;
  49. /* filter out invalid rays */
  50. #if defined(EMBREE_IGNORE_INVALID_RAYS)
  51. if (!ray.valid()) return;
  52. #endif
  53. /* verify correct input */
  54. assert(ray.valid());
  55. assert(ray.tnear >= 0.0f);
  56. assert(!(types & BVH_MB) || (ray.time >= 0.0f && ray.time <= 1.0f));
  57. /*! load the ray into SIMD registers */
  58. size_t leafType = 0;
  59. context->geomID_to_instID = nullptr;
  60. TravRay<N,Nx> vray(ray.org,ray.dir);
  61. vfloat<Nx> ray_near = max(ray.tnear,0.0f);
  62. vfloat<Nx> ray_far = max(ray.tfar ,0.0f);
  63. /*! initialize the node traverser */
  64. BVHNNodeTraverser1<N,Nx,types> nodeTraverser(vray);
  65. /* pop loop */
  66. while (true) pop:
  67. {
  68. /*! pop next node */
  69. if (unlikely(stackPtr == stack)) break;
  70. stackPtr--;
  71. NodeRef cur = NodeRef(stackPtr->ptr);
  72. /*! if popped node is too far, pop next one */
  73. if (unlikely(*(float*)&stackPtr->dist > ray.tfar))
  74. continue;
  75. /* downtraversal loop */
  76. while (true)
  77. {
  78. /* intersect node */
  79. size_t mask; vfloat<Nx> tNear;
  80. STAT3(normal.trav_nodes,1,1,1);
  81. bool nodeIntersected = BVHNNodeIntersector1<N,Nx,types,robust>::intersect(cur,vray,ray_near,ray_far,pre.ftime(),tNear,mask);
  82. if (unlikely(!nodeIntersected)) { STAT3(normal.trav_nodes,-1,-1,-1); break; }
  83. /*! if no child is hit, pop next node */
  84. if (unlikely(mask == 0))
  85. goto pop;
  86. /* select next child and push other children */
  87. nodeTraverser.traverseClosestHit(cur,mask,tNear,stackPtr,stackEnd);
  88. }
  89. /* ray transformation support */
  90. if (unlikely(nodeTraverser.traverseTransform(cur,ray,vray,leafType,context,stackPtr,stackEnd)))
  91. goto pop;
  92. /*! this is a leaf node */
  93. assert(cur != BVH::emptyNode);
  94. STAT3(normal.trav_leaves,1,1,1);
  95. size_t num; Primitive* prim = (Primitive*) cur.leaf(num);
  96. size_t lazy_node = 0;
  97. PrimitiveIntersector1::intersect(pre,ray,context,leafType,prim,num,lazy_node);
  98. ray_far = ray.tfar;
  99. /*! push lazy node onto stack */
  100. if (unlikely(lazy_node)) {
  101. stackPtr->ptr = lazy_node;
  102. stackPtr->dist = neg_inf;
  103. stackPtr++;
  104. }
  105. // perform stack compaction
  106. /*StackItemT<NodeRef>* left=stack;
  107. for (StackItemT<NodeRef>* right=stack; right<stackPtr; right++)
  108. {
  109. if (*(float*)&right->dist >= ray.tfar) continue;
  110. *left = *right; left++;
  111. }
  112. stackPtr = left;*/
  113. }
  114. AVX_ZERO_UPPER();
  115. }
  116. template<int N, int types, bool robust, typename PrimitiveIntersector1>
  117. void BVHNIntersector1<N,types,robust,PrimitiveIntersector1>::occluded(const BVH* __restrict__ bvh, Ray& __restrict__ ray, IntersectContext* context)
  118. {
  119. /*! early out for already occluded rays */
  120. if (unlikely(ray.geomID == 0))
  121. return;
  122. /*! perform per ray precalculations required by the primitive intersector */
  123. Precalculations pre(ray,bvh,bvh->numTimeSteps);
  124. /*! stack state */
  125. NodeRef stack[stackSize]; //!< stack of nodes that still need to get traversed
  126. NodeRef* stackPtr = stack+1; //!< current stack pointer
  127. NodeRef* stackEnd = stack+stackSize;
  128. stack[0] = bvh->getRoot(pre);
  129. /* filter out invalid rays */
  130. #if defined(EMBREE_IGNORE_INVALID_RAYS)
  131. if (!ray.valid()) return;
  132. #endif
  133. /* verify correct input */
  134. assert(ray.valid());
  135. assert(ray.tnear >= 0.0f);
  136. assert(!(types & BVH_MB) || (ray.time >= 0.0f && ray.time <= 1.0f));
  137. /*! load the ray into SIMD registers */
  138. size_t leafType = 0;
  139. context->geomID_to_instID = nullptr;
  140. TravRay<N,Nx> vray(ray.org,ray.dir);
  141. vfloat<Nx> ray_near = max(ray.tnear,0.0f);
  142. vfloat<Nx> ray_far = max(ray.tfar ,0.0f);
  143. /*! initialize the node traverser */
  144. BVHNNodeTraverser1<N,Nx,types> nodeTraverser(vray);
  145. /* pop loop */
  146. while (true) pop:
  147. {
  148. /*! pop next node */
  149. if (unlikely(stackPtr == stack)) break;
  150. stackPtr--;
  151. NodeRef cur = (NodeRef) *stackPtr;
  152. /* downtraversal loop */
  153. while (true)
  154. {
  155. /* intersect node */
  156. size_t mask; vfloat<Nx> tNear;
  157. STAT3(shadow.trav_nodes,1,1,1);
  158. bool nodeIntersected = BVHNNodeIntersector1<N,Nx,types,robust>::intersect(cur,vray,ray_near,ray_far,pre.ftime(),tNear,mask);
  159. if (unlikely(!nodeIntersected)) { STAT3(shadow.trav_nodes,-1,-1,-1); break; }
  160. /*! if no child is hit, pop next node */
  161. if (unlikely(mask == 0))
  162. goto pop;
  163. /* select next child and push other children */
  164. nodeTraverser.traverseAnyHit(cur,mask,tNear,stackPtr,stackEnd);
  165. }
  166. /* ray transformation support */
  167. if (unlikely(nodeTraverser.traverseTransform(cur,ray,vray,leafType,context,stackPtr,stackEnd)))
  168. goto pop;
  169. /*! this is a leaf node */
  170. assert(cur != BVH::emptyNode);
  171. STAT3(shadow.trav_leaves,1,1,1);
  172. size_t num; Primitive* prim = (Primitive*) cur.leaf(num);
  173. size_t lazy_node = 0;
  174. if (PrimitiveIntersector1::occluded(pre,ray,context,leafType,prim,num,lazy_node)) {
  175. ray.geomID = 0;
  176. break;
  177. }
  178. /*! push lazy node onto stack */
  179. if (unlikely(lazy_node)) {
  180. *stackPtr = (NodeRef)lazy_node;
  181. stackPtr++;
  182. }
  183. }
  184. AVX_ZERO_UPPER();
  185. }
  186. }
  187. }