triangle_intersector.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  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. #pragma once
  17. #include "triangle.h"
  18. #include "triangle_intersector_moeller.h"
  19. namespace embree
  20. {
  21. namespace isa
  22. {
  23. /*! Intersects M triangles with 1 ray */
  24. template<int M, int Mx, bool filter>
  25. struct TriangleMIntersector1Moeller
  26. {
  27. typedef TriangleM<M> Primitive;
  28. typedef Intersector1Precalculations<MoellerTrumboreIntersector1<Mx>> Precalculations;
  29. /*! Intersect a ray with the M triangles and updates the hit. */
  30. static __forceinline void intersect(const Precalculations& pre, Ray& ray, IntersectContext* context, const TriangleM<M>& tri)
  31. {
  32. STAT3(normal.trav_prims,1,1,1);
  33. pre.intersect(ray,tri.v0,tri.e1,tri.e2,tri.Ng,Intersect1EpilogM<M,Mx,filter>(ray,context,tri.geomIDs,tri.primIDs));
  34. }
  35. /*! Test if the ray is occluded by one of M triangles. */
  36. static __forceinline bool occluded(const Precalculations& pre, Ray& ray, IntersectContext* context, const TriangleM<M>& tri)
  37. {
  38. STAT3(shadow.trav_prims,1,1,1);
  39. return pre.intersect(ray,tri.v0,tri.e1,tri.e2,tri.Ng,Occluded1EpilogM<M,Mx,filter>(ray,context,tri.geomIDs,tri.primIDs));
  40. }
  41. /*! Intersect an array of rays with an array of M primitives. */
  42. static __forceinline size_t intersect(Precalculations* pre, size_t valid, Ray** rays, IntersectContext* context, size_t ty, const Primitive* prim, size_t num)
  43. {
  44. size_t valid_isec = 0;
  45. do {
  46. const size_t i = __bscf(valid);
  47. const float old_far = rays[i]->tfar;
  48. for (size_t n=0; n<num; n++)
  49. intersect(pre[i],*rays[i],context,prim[n]);
  50. valid_isec |= (rays[i]->tfar < old_far) ? ((size_t)1 << i) : 0;
  51. } while(unlikely(valid));
  52. return valid_isec;
  53. }
  54. };
  55. #if defined(__AVX__)
  56. template<bool filter>
  57. struct TriangleMIntersector1Moeller<4,8,filter>
  58. {
  59. static const size_t M = 4;
  60. static const size_t Mx = 8;
  61. typedef TriangleM<M> Primitive;
  62. typedef Intersector1Precalculations<MoellerTrumboreIntersector1<Mx>> Precalculations;
  63. static __forceinline void intersect(const Precalculations& pre, Ray& ray, IntersectContext* context, const TriangleM<M>& tri)
  64. {
  65. STAT3(normal.trav_prims,1,1,1);
  66. pre.intersect(ray,tri.v0,tri.e1,tri.e2,tri.Ng,Intersect1EpilogM<M,Mx,filter>(ray,context,tri.geomIDs,tri.primIDs));
  67. }
  68. /*! Test if the ray is occluded by one of M triangles. */
  69. static __forceinline bool occluded(const Precalculations& pre, Ray& ray, IntersectContext* context, const TriangleM<M>& tri)
  70. {
  71. STAT3(shadow.trav_prims,1,1,1);
  72. return pre.intersect(ray,tri.v0,tri.e1,tri.e2,tri.Ng,Occluded1EpilogM<M,Mx,filter>(ray,context,tri.geomIDs,tri.primIDs));
  73. }
  74. /*! Intersect an array of rays with an array of M primitives. */
  75. static __forceinline size_t intersect(Precalculations* pre, size_t valid, Ray** rays, IntersectContext* context, size_t ty, const Primitive* prim, size_t num)
  76. {
  77. size_t valid_isec = 0;
  78. do {
  79. const size_t i = __bscf(valid);
  80. for (size_t n=0; n<num; n++)
  81. intersect(pre[i],*rays[i],context,prim[n]);
  82. valid_isec |= ((size_t)1 << i);
  83. } while(unlikely(valid));
  84. return valid_isec;
  85. }
  86. };
  87. #endif
  88. /*! Intersects M triangles with K rays. */
  89. template<int M, int Mx, int K, bool filter>
  90. struct TriangleMIntersectorKMoeller
  91. {
  92. typedef TriangleM<M> Primitive;
  93. typedef IntersectorKPrecalculations<K,MoellerTrumboreIntersectorK<Mx,K>> Precalculations;
  94. /*! Intersects K rays with M triangles. */
  95. static __forceinline void intersect(const vbool<K>& valid_i, Precalculations& pre, RayK<K>& ray, IntersectContext* context, const TriangleM<M>& tri)
  96. {
  97. STAT_USER(0,TriangleM<M>::max_size());
  98. for (size_t i=0; i<TriangleM<M>::max_size(); i++)
  99. {
  100. if (!tri.valid(i)) break;
  101. STAT3(normal.trav_prims,1,popcnt(valid_i),K);
  102. const Vec3<vfloat<K>> p0 = broadcast<vfloat<K>>(tri.v0,i);
  103. const Vec3<vfloat<K>> e1 = broadcast<vfloat<K>>(tri.e1,i);
  104. const Vec3<vfloat<K>> e2 = broadcast<vfloat<K>>(tri.e2,i);
  105. const Vec3<vfloat<K>> Ng = broadcast<vfloat<K>>(tri.Ng,i);
  106. pre.intersectK(valid_i,ray,p0,e1,e2,Ng,IntersectKEpilogM<M,K,filter>(ray,context,tri.geomIDs,tri.primIDs,i));
  107. }
  108. }
  109. /*! Test for K rays if they are occluded by any of the M triangles. */
  110. static __forceinline vbool<K> occluded(const vbool<K>& valid_i, Precalculations& pre, RayK<K>& ray, IntersectContext* context, const TriangleM<M>& tri)
  111. {
  112. vbool<K> valid0 = valid_i;
  113. for (size_t i=0; i<TriangleM<M>::max_size(); i++)
  114. {
  115. if (!tri.valid(i)) break;
  116. STAT3(shadow.trav_prims,1,popcnt(valid0),K);
  117. const Vec3<vfloat<K>> p0 = broadcast<vfloat<K>>(tri.v0,i);
  118. const Vec3<vfloat<K>> e1 = broadcast<vfloat<K>>(tri.e1,i);
  119. const Vec3<vfloat<K>> e2 = broadcast<vfloat<K>>(tri.e2,i);
  120. const Vec3<vfloat<K>> Ng = broadcast<vfloat<K>>(tri.Ng,i);
  121. pre.intersectK(valid0,ray,p0,e1,e2,Ng,OccludedKEpilogM<M,K,filter>(valid0,ray,context,tri.geomIDs,tri.primIDs,i));
  122. if (none(valid0)) break;
  123. }
  124. return !valid0;
  125. }
  126. /*! Intersect a ray with M triangles and updates the hit. */
  127. static __forceinline void intersect(Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const TriangleM<M>& tri)
  128. {
  129. STAT3(normal.trav_prims,1,1,1);
  130. pre.intersect(ray,k,tri.v0,tri.e1,tri.e2,tri.Ng,Intersect1KEpilogM<M,Mx,K,filter>(ray,k,context,tri.geomIDs,tri.primIDs));
  131. }
  132. /*! Test if the ray is occluded by one of the M triangles. */
  133. static __forceinline bool occluded(Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const TriangleM<M>& tri)
  134. {
  135. STAT3(shadow.trav_prims,1,1,1);
  136. return pre.intersect(ray,k,tri.v0,tri.e1,tri.e2,tri.Ng,Occluded1KEpilogM<M,Mx,K,filter>(ray,k,context,tri.geomIDs,tri.primIDs));
  137. }
  138. };
  139. }
  140. }