trianglei_intersector.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. // Copyright 2009-2021 Intel Corporation
  2. // SPDX-License-Identifier: Apache-2.0
  3. #pragma once
  4. #include "trianglei.h"
  5. #include "triangle_intersector_moeller.h"
  6. #include "triangle_intersector_pluecker.h"
  7. namespace embree
  8. {
  9. namespace isa
  10. {
  11. /*! Intersects M triangles with 1 ray */
  12. template<int M, bool filter>
  13. struct TriangleMiIntersector1Moeller
  14. {
  15. typedef TriangleMi<M> Primitive;
  16. typedef MoellerTrumboreIntersector1<M> Precalculations;
  17. static __forceinline void intersect(const Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive& tri)
  18. {
  19. STAT3(normal.trav_prims,1,1,1);
  20. Vec3vf<M> v0, v1, v2; tri.gather(v0,v1,v2,context->scene);
  21. pre.intersect(ray,v0,v1,v2,Intersect1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID()));
  22. }
  23. static __forceinline bool occluded(const Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive& tri)
  24. {
  25. STAT3(shadow.trav_prims,1,1,1);
  26. Vec3vf<M> v0, v1, v2; tri.gather(v0,v1,v2,context->scene);
  27. return pre.intersect(ray,v0,v1,v2,Occluded1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID()));
  28. }
  29. static __forceinline bool pointQuery(PointQuery* query, PointQueryContext* context, const Primitive& tri)
  30. {
  31. return PrimitivePointQuery1<Primitive>::pointQuery(query, context, tri);
  32. }
  33. };
  34. /*! Intersects M triangles with K rays */
  35. template<int M, int K, bool filter>
  36. struct TriangleMiIntersectorKMoeller
  37. {
  38. typedef TriangleMi<M> Primitive;
  39. typedef MoellerTrumboreIntersectorK<M,K> Precalculations;
  40. static __forceinline void intersect(const vbool<K>& valid_i, Precalculations& pre, RayHitK<K>& ray, IntersectContext* context, const Primitive& tri)
  41. {
  42. const Scene* scene = context->scene;
  43. for (size_t i=0; i<Primitive::max_size(); i++)
  44. {
  45. if (!tri.valid(i)) break;
  46. STAT3(normal.trav_prims,1,popcnt(valid_i),RayHitK<K>::size());
  47. const Vec3vf<K> v0 = tri.template getVertex<0>(i,scene);
  48. const Vec3vf<K> v1 = tri.template getVertex<1>(i,scene);
  49. const Vec3vf<K> v2 = tri.template getVertex<2>(i,scene);
  50. pre.intersectK(valid_i,ray,v0,v1,v2,IntersectKEpilogM<M,K,filter>(ray,context,tri.geomID(),tri.primID(),i));
  51. }
  52. }
  53. static __forceinline vbool<K> occluded(const vbool<K>& valid_i, Precalculations& pre, RayK<K>& ray, IntersectContext* context, const Primitive& tri)
  54. {
  55. vbool<K> valid0 = valid_i;
  56. const Scene* scene = context->scene;
  57. for (size_t i=0; i<Primitive::max_size(); i++)
  58. {
  59. if (!tri.valid(i)) break;
  60. STAT3(shadow.trav_prims,1,popcnt(valid_i),RayHitK<K>::size());
  61. const Vec3vf<K> v0 = tri.template getVertex<0>(i,scene);
  62. const Vec3vf<K> v1 = tri.template getVertex<1>(i,scene);
  63. const Vec3vf<K> v2 = tri.template getVertex<2>(i,scene);
  64. pre.intersectK(valid0,ray,v0,v1,v2,OccludedKEpilogM<M,K,filter>(valid0,ray,context,tri.geomID(),tri.primID(),i));
  65. if (none(valid0)) break;
  66. }
  67. return !valid0;
  68. }
  69. static __forceinline void intersect(Precalculations& pre, RayHitK<K>& ray, size_t k, IntersectContext* context, const Primitive& tri)
  70. {
  71. STAT3(normal.trav_prims,1,1,1);
  72. Vec3vf<M> v0, v1, v2; tri.gather(v0,v1,v2,context->scene);
  73. pre.intersect(ray,k,v0,v1,v2,Intersect1KEpilogM<M,K,filter>(ray,k,context,tri.geomID(),tri.primID()));
  74. }
  75. static __forceinline bool occluded(Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive& tri)
  76. {
  77. STAT3(shadow.trav_prims,1,1,1);
  78. Vec3vf<M> v0, v1, v2; tri.gather(v0,v1,v2,context->scene);
  79. return pre.intersect(ray,k,v0,v1,v2,Occluded1KEpilogM<M,K,filter>(ray,k,context,tri.geomID(),tri.primID()));
  80. }
  81. };
  82. /*! Intersects M triangles with 1 ray */
  83. template<int M, bool filter>
  84. struct TriangleMiIntersector1Pluecker
  85. {
  86. typedef TriangleMi<M> Primitive;
  87. typedef PlueckerIntersector1<M> Precalculations;
  88. static __forceinline void intersect(const Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive& tri)
  89. {
  90. STAT3(normal.trav_prims,1,1,1);
  91. Vec3vf<M> v0, v1, v2; tri.gather(v0,v1,v2,context->scene);
  92. pre.intersect(ray,v0,v1,v2,Intersect1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID()));
  93. }
  94. static __forceinline bool occluded(const Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive& tri)
  95. {
  96. STAT3(shadow.trav_prims,1,1,1);
  97. Vec3vf<M> v0, v1, v2; tri.gather(v0,v1,v2,context->scene);
  98. return pre.intersect(ray,v0,v1,v2,Occluded1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID()));
  99. }
  100. static __forceinline bool pointQuery(PointQuery* query, PointQueryContext* context, const Primitive& tri)
  101. {
  102. return PrimitivePointQuery1<Primitive>::pointQuery(query, context, tri);
  103. }
  104. };
  105. /*! Intersects M triangles with K rays */
  106. template<int M, int K, bool filter>
  107. struct TriangleMiIntersectorKPluecker
  108. {
  109. typedef TriangleMi<M> Primitive;
  110. typedef PlueckerIntersectorK<M,K> Precalculations;
  111. static __forceinline void intersect(const vbool<K>& valid_i, Precalculations& pre, RayHitK<K>& ray, IntersectContext* context, const Primitive& tri)
  112. {
  113. const Scene* scene = context->scene;
  114. for (size_t i=0; i<Primitive::max_size(); i++)
  115. {
  116. if (!tri.valid(i)) break;
  117. STAT3(normal.trav_prims,1,popcnt(valid_i),RayHitK<K>::size());
  118. const Vec3vf<K> v0 = tri.template getVertex<0>(i,scene);
  119. const Vec3vf<K> v1 = tri.template getVertex<1>(i,scene);
  120. const Vec3vf<K> v2 = tri.template getVertex<2>(i,scene);
  121. pre.intersectK(valid_i,ray,v0,v1,v2,IntersectKEpilogM<M,K,filter>(ray,context,tri.geomID(),tri.primID(),i));
  122. }
  123. }
  124. static __forceinline vbool<K> occluded(const vbool<K>& valid_i, Precalculations& pre, RayK<K>& ray, IntersectContext* context, const Primitive& tri)
  125. {
  126. vbool<K> valid0 = valid_i;
  127. const Scene* scene = context->scene;
  128. for (size_t i=0; i<Primitive::max_size(); i++)
  129. {
  130. if (!tri.valid(i)) break;
  131. STAT3(shadow.trav_prims,1,popcnt(valid_i),RayHitK<K>::size());
  132. const Vec3vf<K> v0 = tri.template getVertex<0>(i,scene);
  133. const Vec3vf<K> v1 = tri.template getVertex<1>(i,scene);
  134. const Vec3vf<K> v2 = tri.template getVertex<2>(i,scene);
  135. pre.intersectK(valid0,ray,v0,v1,v2,OccludedKEpilogM<M,K,filter>(valid0,ray,context,tri.geomID(),tri.primID(),i));
  136. if (none(valid0)) break;
  137. }
  138. return !valid0;
  139. }
  140. static __forceinline void intersect(Precalculations& pre, RayHitK<K>& ray, size_t k, IntersectContext* context, const Primitive& tri)
  141. {
  142. STAT3(normal.trav_prims,1,1,1);
  143. Vec3vf<M> v0, v1, v2; tri.gather(v0,v1,v2,context->scene);
  144. pre.intersect(ray,k,v0,v1,v2,Intersect1KEpilogM<M,K,filter>(ray,k,context,tri.geomID(),tri.primID()));
  145. }
  146. static __forceinline bool occluded(Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive& tri)
  147. {
  148. STAT3(shadow.trav_prims,1,1,1);
  149. Vec3vf<M> v0, v1, v2; tri.gather(v0,v1,v2,context->scene);
  150. return pre.intersect(ray,k,v0,v1,v2,Occluded1KEpilogM<M,K,filter>(ray,k,context,tri.geomID(),tri.primID()));
  151. }
  152. };
  153. /*! Intersects M motion blur triangles with 1 ray */
  154. template<int M, bool filter>
  155. struct TriangleMiMBIntersector1Moeller
  156. {
  157. typedef TriangleMi<M> Primitive;
  158. typedef MoellerTrumboreIntersector1<M> Precalculations;
  159. /*! Intersect a ray with the M triangles and updates the hit. */
  160. static __forceinline void intersect(const Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive& tri)
  161. {
  162. STAT3(normal.trav_prims,1,1,1);
  163. Vec3vf<M> v0,v1,v2; tri.gather(v0,v1,v2,context->scene,ray.time());
  164. pre.intersect(ray,v0,v1,v2,Intersect1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID()));
  165. }
  166. /*! Test if the ray is occluded by one of M triangles. */
  167. static __forceinline bool occluded(const Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive& tri)
  168. {
  169. STAT3(shadow.trav_prims,1,1,1);
  170. Vec3vf<M> v0,v1,v2; tri.gather(v0,v1,v2,context->scene,ray.time());
  171. return pre.intersect(ray,v0,v1,v2,Occluded1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID()));
  172. }
  173. static __forceinline bool pointQuery(PointQuery* query, PointQueryContext* context, const Primitive& tri)
  174. {
  175. return PrimitivePointQuery1<Primitive>::pointQuery(query, context, tri);
  176. }
  177. };
  178. /*! Intersects M motion blur triangles with K rays. */
  179. template<int M, int K, bool filter>
  180. struct TriangleMiMBIntersectorKMoeller
  181. {
  182. typedef TriangleMi<M> Primitive;
  183. typedef MoellerTrumboreIntersectorK<M,K> Precalculations;
  184. /*! Intersects K rays with M triangles. */
  185. static __forceinline void intersect(const vbool<K>& valid_i, Precalculations& pre, RayHitK<K>& ray, IntersectContext* context, const TriangleMi<M>& tri)
  186. {
  187. for (size_t i=0; i<TriangleMi<M>::max_size(); i++)
  188. {
  189. if (!tri.valid(i)) break;
  190. STAT3(normal.trav_prims,1,popcnt(valid_i),K);
  191. Vec3vf<K> v0,v1,v2; tri.template gather<K>(valid_i,v0,v1,v2,i,context->scene,ray.time());
  192. pre.intersectK(valid_i,ray,v0,v1,v2,IntersectKEpilogM<M,K,filter>(ray,context,tri.geomID(),tri.primID(),i));
  193. }
  194. }
  195. /*! Test for K rays if they are occluded by any of the M triangles. */
  196. static __forceinline vbool<K> occluded(const vbool<K>& valid_i, Precalculations& pre, RayK<K>& ray, IntersectContext* context, const TriangleMi<M>& tri)
  197. {
  198. vbool<K> valid0 = valid_i;
  199. for (size_t i=0; i<TriangleMi<M>::max_size(); i++)
  200. {
  201. if (!tri.valid(i)) break;
  202. STAT3(shadow.trav_prims,1,popcnt(valid0),K);
  203. Vec3vf<K> v0,v1,v2; tri.template gather<K>(valid_i,v0,v1,v2,i,context->scene,ray.time());
  204. pre.intersectK(valid0,ray,v0,v1,v2,OccludedKEpilogM<M,K,filter>(valid0,ray,context,tri.geomID(),tri.primID(),i));
  205. if (none(valid0)) break;
  206. }
  207. return !valid0;
  208. }
  209. /*! Intersect a ray with M triangles and updates the hit. */
  210. static __forceinline void intersect(Precalculations& pre, RayHitK<K>& ray, size_t k, IntersectContext* context, const TriangleMi<M>& tri)
  211. {
  212. STAT3(normal.trav_prims,1,1,1);
  213. Vec3vf<M> v0,v1,v2; tri.gather(v0,v1,v2,context->scene,ray.time()[k]);
  214. pre.intersect(ray,k,v0,v1,v2,Intersect1KEpilogM<M,K,filter>(ray,k,context,tri.geomID(),tri.primID()));
  215. }
  216. /*! Test if the ray is occluded by one of the M triangles. */
  217. static __forceinline bool occluded(Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const TriangleMi<M>& tri)
  218. {
  219. STAT3(shadow.trav_prims,1,1,1);
  220. Vec3vf<M> v0,v1,v2; tri.gather(v0,v1,v2,context->scene,ray.time()[k]);
  221. return pre.intersect(ray,k,v0,v1,v2,Occluded1KEpilogM<M,K,filter>(ray,k,context,tri.geomID(),tri.primID()));
  222. }
  223. };
  224. /*! Intersects M motion blur triangles with 1 ray */
  225. template<int M, bool filter>
  226. struct TriangleMiMBIntersector1Pluecker
  227. {
  228. typedef TriangleMi<M> Primitive;
  229. typedef PlueckerIntersector1<M> Precalculations;
  230. /*! Intersect a ray with the M triangles and updates the hit. */
  231. static __forceinline void intersect(const Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive& tri)
  232. {
  233. STAT3(normal.trav_prims,1,1,1);
  234. Vec3vf<M> v0,v1,v2; tri.gather(v0,v1,v2,context->scene,ray.time());
  235. pre.intersect(ray,v0,v1,v2,Intersect1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID()));
  236. }
  237. /*! Test if the ray is occluded by one of M triangles. */
  238. static __forceinline bool occluded(const Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive& tri)
  239. {
  240. STAT3(shadow.trav_prims,1,1,1);
  241. Vec3vf<M> v0,v1,v2; tri.gather(v0,v1,v2,context->scene,ray.time());
  242. return pre.intersect(ray,v0,v1,v2,Occluded1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID()));
  243. }
  244. static __forceinline bool pointQuery(PointQuery* query, PointQueryContext* context, const Primitive& tri)
  245. {
  246. return PrimitivePointQuery1<Primitive>::pointQuery(query, context, tri);
  247. }
  248. };
  249. /*! Intersects M motion blur triangles with K rays. */
  250. template<int M, int K, bool filter>
  251. struct TriangleMiMBIntersectorKPluecker
  252. {
  253. typedef TriangleMi<M> Primitive;
  254. typedef PlueckerIntersectorK<M,K> Precalculations;
  255. /*! Intersects K rays with M triangles. */
  256. static __forceinline void intersect(const vbool<K>& valid_i, Precalculations& pre, RayHitK<K>& ray, IntersectContext* context, const TriangleMi<M>& tri)
  257. {
  258. for (size_t i=0; i<TriangleMi<M>::max_size(); i++)
  259. {
  260. if (!tri.valid(i)) break;
  261. STAT3(normal.trav_prims,1,popcnt(valid_i),K);
  262. Vec3vf<K> v0,v1,v2; tri.template gather<K>(valid_i,v0,v1,v2,i,context->scene,ray.time());
  263. pre.intersectK(valid_i,ray,v0,v1,v2,IntersectKEpilogM<M,K,filter>(ray,context,tri.geomID(),tri.primID(),i));
  264. }
  265. }
  266. /*! Test for K rays if they are occluded by any of the M triangles. */
  267. static __forceinline vbool<K> occluded(const vbool<K>& valid_i, Precalculations& pre, RayK<K>& ray, IntersectContext* context, const TriangleMi<M>& tri)
  268. {
  269. vbool<K> valid0 = valid_i;
  270. for (size_t i=0; i<TriangleMi<M>::max_size(); i++)
  271. {
  272. if (!tri.valid(i)) break;
  273. STAT3(shadow.trav_prims,1,popcnt(valid0),K);
  274. Vec3vf<K> v0,v1,v2; tri.template gather<K>(valid_i,v0,v1,v2,i,context->scene,ray.time());
  275. pre.intersectK(valid0,ray,v0,v1,v2,OccludedKEpilogM<M,K,filter>(valid0,ray,context,tri.geomID(),tri.primID(),i));
  276. if (none(valid0)) break;
  277. }
  278. return !valid0;
  279. }
  280. /*! Intersect a ray with M triangles and updates the hit. */
  281. static __forceinline void intersect(Precalculations& pre, RayHitK<K>& ray, size_t k, IntersectContext* context, const TriangleMi<M>& tri)
  282. {
  283. STAT3(normal.trav_prims,1,1,1);
  284. Vec3vf<M> v0,v1,v2; tri.gather(v0,v1,v2,context->scene,ray.time()[k]);
  285. pre.intersect(ray,k,v0,v1,v2,Intersect1KEpilogM<M,K,filter>(ray,k,context,tri.geomID(),tri.primID()));
  286. }
  287. /*! Test if the ray is occluded by one of the M triangles. */
  288. static __forceinline bool occluded(Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const TriangleMi<M>& tri)
  289. {
  290. STAT3(shadow.trav_prims,1,1,1);
  291. Vec3vf<M> v0,v1,v2; tri.gather(v0,v1,v2,context->scene,ray.time()[k]);
  292. return pre.intersect(ray,k,v0,v1,v2,Occluded1KEpilogM<M,K,filter>(ray,k,context,tri.geomID(),tri.primID()));
  293. }
  294. };
  295. }
  296. }