curveNi_mb_intersector.h 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. // Copyright 2009-2021 Intel Corporation
  2. // SPDX-License-Identifier: Apache-2.0
  3. #pragma once
  4. #include "curveNi_mb.h"
  5. #include "../subdiv/linear_bezier_patch.h"
  6. #include "roundline_intersector.h"
  7. #include "coneline_intersector.h"
  8. #include "curve_intersector_ribbon.h"
  9. #include "curve_intersector_oriented.h"
  10. #include "curve_intersector_sweep.h"
  11. namespace embree
  12. {
  13. namespace isa
  14. {
  15. template<int M>
  16. struct CurveNiMBIntersector1
  17. {
  18. typedef CurveNiMB<M> Primitive;
  19. typedef Vec3vf<M> Vec3vfM;
  20. typedef LinearSpace3<Vec3vfM>LinearSpace3vfM;
  21. typedef CurvePrecalculations1 Precalculations;
  22. static __forceinline vbool<M> intersect(Ray& ray, const Primitive& prim, vfloat<M>& tNear_o)
  23. {
  24. const size_t N = prim.N;
  25. #if __SYCL_DEVICE_ONLY__
  26. const Vec3f offset = *prim.offset(N);
  27. const float scale = *prim.scale(N);
  28. #else
  29. const vfloat4 offset_scale = vfloat4::loadu(prim.offset(N));
  30. const Vec3fa offset = Vec3fa(offset_scale);
  31. const Vec3fa scale = Vec3fa(shuffle<3,3,3,3>(offset_scale));
  32. #endif
  33. const Vec3fa org1 = (ray.org-offset)*scale;
  34. const Vec3fa dir1 = ray.dir*scale;
  35. const LinearSpace3vfM space(vfloat<M>::load(prim.bounds_vx_x(N)), vfloat<M>::load(prim.bounds_vx_y(N)), vfloat<M>::load(prim.bounds_vx_z(N)),
  36. vfloat<M>::load(prim.bounds_vy_x(N)), vfloat<M>::load(prim.bounds_vy_y(N)), vfloat<M>::load(prim.bounds_vy_z(N)),
  37. vfloat<M>::load(prim.bounds_vz_x(N)), vfloat<M>::load(prim.bounds_vz_y(N)), vfloat<M>::load(prim.bounds_vz_z(N)));
  38. const Vec3vfM dir2 = xfmVector(space,Vec3vfM(dir1));
  39. const Vec3vfM org2 = xfmPoint (space,Vec3vfM(org1));
  40. const Vec3vfM rcp_dir2 = rcp_safe(dir2);
  41. const vfloat<M> ltime = (ray.time()-prim.time_offset(N))*prim.time_scale(N);
  42. const vfloat<M> vx_lower0 = vfloat<M>::load(prim.bounds_vx_lower0(N));
  43. const vfloat<M> vx_lower1 = vfloat<M>::load(prim.bounds_vx_lower1(N));
  44. const vfloat<M> vx_lower = madd(ltime,vx_lower1-vx_lower0,vx_lower0);
  45. const vfloat<M> vx_upper0 = vfloat<M>::load(prim.bounds_vx_upper0(N));
  46. const vfloat<M> vx_upper1 = vfloat<M>::load(prim.bounds_vx_upper1(N));
  47. const vfloat<M> vx_upper = madd(ltime,vx_upper1-vx_upper0,vx_upper0);
  48. const vfloat<M> vy_lower0 = vfloat<M>::load(prim.bounds_vy_lower0(N));
  49. const vfloat<M> vy_lower1 = vfloat<M>::load(prim.bounds_vy_lower1(N));
  50. const vfloat<M> vy_lower = madd(ltime,vy_lower1-vy_lower0,vy_lower0);
  51. const vfloat<M> vy_upper0 = vfloat<M>::load(prim.bounds_vy_upper0(N));
  52. const vfloat<M> vy_upper1 = vfloat<M>::load(prim.bounds_vy_upper1(N));
  53. const vfloat<M> vy_upper = madd(ltime,vy_upper1-vy_upper0,vy_upper0);
  54. const vfloat<M> vz_lower0 = vfloat<M>::load(prim.bounds_vz_lower0(N));
  55. const vfloat<M> vz_lower1 = vfloat<M>::load(prim.bounds_vz_lower1(N));
  56. const vfloat<M> vz_lower = madd(ltime,vz_lower1-vz_lower0,vz_lower0);
  57. const vfloat<M> vz_upper0 = vfloat<M>::load(prim.bounds_vz_upper0(N));
  58. const vfloat<M> vz_upper1 = vfloat<M>::load(prim.bounds_vz_upper1(N));
  59. const vfloat<M> vz_upper = madd(ltime,vz_upper1-vz_upper0,vz_upper0);
  60. const vfloat<M> t_lower_x = (vx_lower-vfloat<M>(org2.x))*vfloat<M>(rcp_dir2.x);
  61. const vfloat<M> t_upper_x = (vx_upper-vfloat<M>(org2.x))*vfloat<M>(rcp_dir2.x);
  62. const vfloat<M> t_lower_y = (vy_lower-vfloat<M>(org2.y))*vfloat<M>(rcp_dir2.y);
  63. const vfloat<M> t_upper_y = (vy_upper-vfloat<M>(org2.y))*vfloat<M>(rcp_dir2.y);
  64. const vfloat<M> t_lower_z = (vz_lower-vfloat<M>(org2.z))*vfloat<M>(rcp_dir2.z);
  65. const vfloat<M> t_upper_z = (vz_upper-vfloat<M>(org2.z))*vfloat<M>(rcp_dir2.z);
  66. const vfloat<M> round_up (1.0f+3.0f*float(ulp));
  67. const vfloat<M> round_down(1.0f-3.0f*float(ulp));
  68. const vfloat<M> tNear = round_down*max(mini(t_lower_x,t_upper_x),mini(t_lower_y,t_upper_y),mini(t_lower_z,t_upper_z),vfloat<M>(ray.tnear()));
  69. const vfloat<M> tFar = round_up *min(maxi(t_lower_x,t_upper_x),maxi(t_lower_y,t_upper_y),maxi(t_lower_z,t_upper_z),vfloat<M>(ray.tfar));
  70. tNear_o = tNear;
  71. return (vint<M>(step) < vint<M>(prim.N)) & (tNear <= tFar);
  72. }
  73. template<typename Intersector, typename Epilog>
  74. static __forceinline void intersect_t(const Precalculations& pre, RayHit& ray, RayQueryContext* context, const Primitive& prim)
  75. {
  76. vfloat<M> tNear;
  77. vbool<M> valid = intersect(ray,prim,tNear);
  78. const size_t N = prim.N;
  79. size_t mask = movemask(valid);
  80. while (mask)
  81. {
  82. const size_t i = bscf(mask);
  83. STAT3(normal.trav_prims,1,1,1);
  84. const unsigned int geomID = prim.geomID(N);
  85. const unsigned int primID = prim.primID(N)[i];
  86. const CurveGeometry* geom = context->scene->get<CurveGeometry>(geomID);
  87. Vec3ff a0,a1,a2,a3; geom->gather(a0,a1,a2,a3,geom->curve(primID),ray.time());
  88. Intersector().intersect(pre,ray,context,geom,primID,a0,a1,a2,a3,Epilog(ray,context,geomID,primID));
  89. mask &= movemask(tNear <= vfloat<M>(ray.tfar));
  90. }
  91. }
  92. template<typename Intersector, typename Epilog>
  93. static __forceinline bool occluded_t(const Precalculations& pre, Ray& ray, RayQueryContext* context, const Primitive& prim)
  94. {
  95. vfloat<M> tNear;
  96. vbool<M> valid = intersect(ray,prim,tNear);
  97. const size_t N = prim.N;
  98. size_t mask = movemask(valid);
  99. while (mask)
  100. {
  101. const size_t i = bscf(mask);
  102. STAT3(shadow.trav_prims,1,1,1);
  103. const unsigned int geomID = prim.geomID(N);
  104. const unsigned int primID = prim.primID(N)[i];
  105. const CurveGeometry* geom = context->scene->get<CurveGeometry>(geomID);
  106. Vec3ff a0,a1,a2,a3; geom->gather(a0,a1,a2,a3,geom->curve(primID),ray.time());
  107. if (Intersector().intersect(pre,ray,context,geom,primID,a0,a1,a2,a3,Epilog(ray,context,geomID,primID)))
  108. return true;
  109. mask &= movemask(tNear <= vfloat<M>(ray.tfar));
  110. }
  111. return false;
  112. }
  113. template<typename Intersector, typename Epilog>
  114. static __forceinline void intersect_n(const Precalculations& pre, RayHit& ray, RayQueryContext* context, const Primitive& prim)
  115. {
  116. vfloat<M> tNear;
  117. vbool<M> valid = intersect(ray,prim,tNear);
  118. const size_t N = prim.N;
  119. size_t mask = movemask(valid);
  120. while (mask)
  121. {
  122. const size_t i = bscf(mask);
  123. STAT3(normal.trav_prims,1,1,1);
  124. const unsigned int geomID = prim.geomID(N);
  125. const unsigned int primID = prim.primID(N)[i];
  126. const CurveGeometry* geom = context->scene->get<CurveGeometry>(geomID);
  127. const TensorLinearCubicBezierSurface3fa curve = geom->getNormalOrientedCurve<typename Intersector::SourceCurve3ff, typename Intersector::SourceCurve3fa, TensorLinearCubicBezierSurface3fa>(context, ray.org, primID,ray.time());
  128. Intersector().intersect(pre,ray,context,geom,primID,curve,Epilog(ray,context,geomID,primID));
  129. mask &= movemask(tNear <= vfloat<M>(ray.tfar));
  130. }
  131. }
  132. template<typename Intersector, typename Epilog>
  133. static __forceinline bool occluded_n(const Precalculations& pre, Ray& ray, RayQueryContext* context, const Primitive& prim)
  134. {
  135. vfloat<M> tNear;
  136. vbool<M> valid = intersect(ray,prim,tNear);
  137. const size_t N = prim.N;
  138. size_t mask = movemask(valid);
  139. while (mask)
  140. {
  141. const size_t i = bscf(mask);
  142. STAT3(shadow.trav_prims,1,1,1);
  143. const unsigned int geomID = prim.geomID(N);
  144. const unsigned int primID = prim.primID(N)[i];
  145. const CurveGeometry* geom = context->scene->get<CurveGeometry>(geomID);
  146. const TensorLinearCubicBezierSurface3fa curve = geom->getNormalOrientedCurve<typename Intersector::SourceCurve3ff, typename Intersector::SourceCurve3fa, TensorLinearCubicBezierSurface3fa>(context, ray.org, primID,ray.time());
  147. if (Intersector().intersect(pre,ray,context,geom,primID,curve,Epilog(ray,context,geomID,primID)))
  148. return true;
  149. mask &= movemask(tNear <= vfloat<M>(ray.tfar));
  150. }
  151. return false;
  152. }
  153. template<typename Intersector, typename Epilog>
  154. static __forceinline void intersect_h(const Precalculations& pre, RayHit& ray, RayQueryContext* context, const Primitive& prim)
  155. {
  156. vfloat<M> tNear;
  157. vbool<M> valid = intersect(ray,prim,tNear);
  158. const size_t N = prim.N;
  159. size_t mask = movemask(valid);
  160. while (mask)
  161. {
  162. const size_t i = bscf(mask);
  163. STAT3(normal.trav_prims,1,1,1);
  164. const unsigned int geomID = prim.geomID(N);
  165. const unsigned int primID = prim.primID(N)[i];
  166. const CurveGeometry* geom = context->scene->get<CurveGeometry>(geomID);
  167. Vec3ff p0,t0,p1,t1; geom->gather_hermite(p0,t0,p1,t1,geom->curve(primID),ray.time());
  168. Intersector().intersect(pre,ray,context,geom,primID,p0,t0,p1,t1,Epilog(ray,context,geomID,primID));
  169. mask &= movemask(tNear <= vfloat<M>(ray.tfar));
  170. }
  171. }
  172. template<typename Intersector, typename Epilog>
  173. static __forceinline bool occluded_h(const Precalculations& pre, Ray& ray, RayQueryContext* context, const Primitive& prim)
  174. {
  175. vfloat<M> tNear;
  176. vbool<M> valid = intersect(ray,prim,tNear);
  177. const size_t N = prim.N;
  178. size_t mask = movemask(valid);
  179. while (mask)
  180. {
  181. const size_t i = bscf(mask);
  182. STAT3(shadow.trav_prims,1,1,1);
  183. const unsigned int geomID = prim.geomID(N);
  184. const unsigned int primID = prim.primID(N)[i];
  185. const CurveGeometry* geom = context->scene->get<CurveGeometry>(geomID);
  186. Vec3ff p0,t0,p1,t1; geom->gather_hermite(p0,t0,p1,t1,geom->curve(primID),ray.time());
  187. if (Intersector().intersect(pre,ray,context,geom,primID,p0,t0,p1,t1,Epilog(ray,context,geomID,primID)))
  188. return true;
  189. mask &= movemask(tNear <= vfloat<M>(ray.tfar));
  190. }
  191. return false;
  192. }
  193. template<typename Intersector, typename Epilog>
  194. static __forceinline void intersect_hn(const Precalculations& pre, RayHit& ray, RayQueryContext* context, const Primitive& prim)
  195. {
  196. vfloat<M> tNear;
  197. vbool<M> valid = intersect(ray,prim,tNear);
  198. const size_t N = prim.N;
  199. size_t mask = movemask(valid);
  200. while (mask)
  201. {
  202. const size_t i = bscf(mask);
  203. STAT3(normal.trav_prims,1,1,1);
  204. const unsigned int geomID = prim.geomID(N);
  205. const unsigned int primID = prim.primID(N)[i];
  206. const CurveGeometry* geom = context->scene->get<CurveGeometry>(geomID);
  207. const TensorLinearCubicBezierSurface3fa curve = geom->getNormalOrientedHermiteCurve<typename Intersector::SourceCurve3ff, typename Intersector::SourceCurve3fa, TensorLinearCubicBezierSurface3fa>(context, ray.org, primID,ray.time());
  208. Intersector().intersect(pre,ray,context,geom,primID,curve,Epilog(ray,context,geomID,primID));
  209. mask &= movemask(tNear <= vfloat<M>(ray.tfar));
  210. }
  211. }
  212. template<typename Intersector, typename Epilog>
  213. static __forceinline bool occluded_hn(const Precalculations& pre, Ray& ray, RayQueryContext* context, const Primitive& prim)
  214. {
  215. vfloat<M> tNear;
  216. vbool<M> valid = intersect(ray,prim,tNear);
  217. const size_t N = prim.N;
  218. size_t mask = movemask(valid);
  219. while (mask)
  220. {
  221. const size_t i = bscf(mask);
  222. STAT3(shadow.trav_prims,1,1,1);
  223. const unsigned int geomID = prim.geomID(N);
  224. const unsigned int primID = prim.primID(N)[i];
  225. const CurveGeometry* geom = context->scene->get<CurveGeometry>(geomID);
  226. const TensorLinearCubicBezierSurface3fa curve = geom->getNormalOrientedHermiteCurve<typename Intersector::SourceCurve3ff, typename Intersector::SourceCurve3fa, TensorLinearCubicBezierSurface3fa>(context, ray.org, primID,ray.time());
  227. if (Intersector().intersect(pre,ray,context,geom,primID,curve,Epilog(ray,context,geomID,primID)))
  228. return true;
  229. mask &= movemask(tNear <= vfloat<M>(ray.tfar));
  230. }
  231. return false;
  232. }
  233. };
  234. template<int M, int K>
  235. struct CurveNiMBIntersectorK
  236. {
  237. typedef CurveNiMB<M> Primitive;
  238. typedef Vec3vf<M> Vec3vfM;
  239. typedef LinearSpace3<Vec3vfM>LinearSpace3vfM;
  240. typedef CurvePrecalculationsK<K> Precalculations;
  241. static __forceinline vbool<M> intersect(RayK<K>& ray, const size_t k, const Primitive& prim, vfloat<M>& tNear_o)
  242. {
  243. const size_t N = prim.N;
  244. #if __SYCL_DEVICE_ONLY__
  245. const Vec3f offset = *prim.offset(N);
  246. const float scale = *prim.scale(N);
  247. #else
  248. const vfloat4 offset_scale = vfloat4::loadu(prim.offset(N));
  249. const Vec3fa offset = Vec3fa(offset_scale);
  250. const Vec3fa scale = Vec3fa(shuffle<3,3,3,3>(offset_scale));
  251. #endif
  252. const Vec3fa ray_org(ray.org.x[k],ray.org.y[k],ray.org.z[k]);
  253. const Vec3fa ray_dir(ray.dir.x[k],ray.dir.y[k],ray.dir.z[k]);
  254. const Vec3fa org1 = (ray_org-offset)*scale;
  255. const Vec3fa dir1 = ray_dir*scale;
  256. const LinearSpace3vfM space(vfloat<M>::load(prim.bounds_vx_x(N)), vfloat<M>::load(prim.bounds_vx_y(N)), vfloat<M>::load(prim.bounds_vx_z(N)),
  257. vfloat<M>::load(prim.bounds_vy_x(N)), vfloat<M>::load(prim.bounds_vy_y(N)), vfloat<M>::load(prim.bounds_vy_z(N)),
  258. vfloat<M>::load(prim.bounds_vz_x(N)), vfloat<M>::load(prim.bounds_vz_y(N)), vfloat<M>::load(prim.bounds_vz_z(N)));
  259. const Vec3vfM dir2 = xfmVector(space,Vec3vfM(dir1));
  260. const Vec3vfM org2 = xfmPoint (space,Vec3vfM(org1));
  261. const Vec3vfM rcp_dir2 = rcp_safe(dir2);
  262. const vfloat<M> ltime = (ray.time()[k]-prim.time_offset(N))*prim.time_scale(N);
  263. const vfloat<M> vx_lower0 = vfloat<M>::load(prim.bounds_vx_lower0(N));
  264. const vfloat<M> vx_lower1 = vfloat<M>::load(prim.bounds_vx_lower1(N));
  265. const vfloat<M> vx_lower = madd(ltime,vx_lower1-vx_lower0,vx_lower0);
  266. const vfloat<M> vx_upper0 = vfloat<M>::load(prim.bounds_vx_upper0(N));
  267. const vfloat<M> vx_upper1 = vfloat<M>::load(prim.bounds_vx_upper1(N));
  268. const vfloat<M> vx_upper = madd(ltime,vx_upper1-vx_upper0,vx_upper0);
  269. const vfloat<M> vy_lower0 = vfloat<M>::load(prim.bounds_vy_lower0(N));
  270. const vfloat<M> vy_lower1 = vfloat<M>::load(prim.bounds_vy_lower1(N));
  271. const vfloat<M> vy_lower = madd(ltime,vy_lower1-vy_lower0,vy_lower0);
  272. const vfloat<M> vy_upper0 = vfloat<M>::load(prim.bounds_vy_upper0(N));
  273. const vfloat<M> vy_upper1 = vfloat<M>::load(prim.bounds_vy_upper1(N));
  274. const vfloat<M> vy_upper = madd(ltime,vy_upper1-vy_upper0,vy_upper0);
  275. const vfloat<M> vz_lower0 = vfloat<M>::load(prim.bounds_vz_lower0(N));
  276. const vfloat<M> vz_lower1 = vfloat<M>::load(prim.bounds_vz_lower1(N));
  277. const vfloat<M> vz_lower = madd(ltime,vz_lower1-vz_lower0,vz_lower0);
  278. const vfloat<M> vz_upper0 = vfloat<M>::load(prim.bounds_vz_upper0(N));
  279. const vfloat<M> vz_upper1 = vfloat<M>::load(prim.bounds_vz_upper1(N));
  280. const vfloat<M> vz_upper = madd(ltime,vz_upper1-vz_upper0,vz_upper0);
  281. const vfloat<M> t_lower_x = (vx_lower-vfloat<M>(org2.x))*vfloat<M>(rcp_dir2.x);
  282. const vfloat<M> t_upper_x = (vx_upper-vfloat<M>(org2.x))*vfloat<M>(rcp_dir2.x);
  283. const vfloat<M> t_lower_y = (vy_lower-vfloat<M>(org2.y))*vfloat<M>(rcp_dir2.y);
  284. const vfloat<M> t_upper_y = (vy_upper-vfloat<M>(org2.y))*vfloat<M>(rcp_dir2.y);
  285. const vfloat<M> t_lower_z = (vz_lower-vfloat<M>(org2.z))*vfloat<M>(rcp_dir2.z);
  286. const vfloat<M> t_upper_z = (vz_upper-vfloat<M>(org2.z))*vfloat<M>(rcp_dir2.z);
  287. const vfloat<M> round_up (1.0f+3.0f*float(ulp));
  288. const vfloat<M> round_down(1.0f-3.0f*float(ulp));
  289. const vfloat<M> tNear = round_down*max(mini(t_lower_x,t_upper_x),mini(t_lower_y,t_upper_y),mini(t_lower_z,t_upper_z),vfloat<M>(ray.tnear()[k]));
  290. const vfloat<M> tFar = round_up *min(maxi(t_lower_x,t_upper_x),maxi(t_lower_y,t_upper_y),maxi(t_lower_z,t_upper_z),vfloat<M>(ray.tfar[k]));
  291. tNear_o = tNear;
  292. return (vint<M>(step) < vint<M>(prim.N)) & (tNear <= tFar);
  293. }
  294. template<typename Intersector, typename Epilog>
  295. static __forceinline void intersect_t(Precalculations& pre, RayHitK<K>& ray, const size_t k, RayQueryContext* context, const Primitive& prim)
  296. {
  297. vfloat<M> tNear;
  298. vbool<M> valid = intersect(ray,k,prim,tNear);
  299. const size_t N = prim.N;
  300. size_t mask = movemask(valid);
  301. while (mask)
  302. {
  303. const size_t i = bscf(mask);
  304. STAT3(normal.trav_prims,1,1,1);
  305. const unsigned int geomID = prim.geomID(N);
  306. const unsigned int primID = prim.primID(N)[i];
  307. const CurveGeometry* geom = context->scene->get<CurveGeometry>(geomID);
  308. Vec3ff a0,a1,a2,a3; geom->gather(a0,a1,a2,a3,geom->curve(primID),ray.time()[k]);
  309. Intersector().intersect(pre,ray,k,context,geom,primID,a0,a1,a2,a3,Epilog(ray,k,context,geomID,primID));
  310. mask &= movemask(tNear <= vfloat<M>(ray.tfar[k]));
  311. }
  312. }
  313. template<typename Intersector, typename Epilog>
  314. static __forceinline bool occluded_t(Precalculations& pre, RayK<K>& ray, const size_t k, RayQueryContext* context, const Primitive& prim)
  315. {
  316. vfloat<M> tNear;
  317. vbool<M> valid = intersect(ray,k,prim,tNear);
  318. const size_t N = prim.N;
  319. size_t mask = movemask(valid);
  320. while (mask)
  321. {
  322. const size_t i = bscf(mask);
  323. STAT3(shadow.trav_prims,1,1,1);
  324. const unsigned int geomID = prim.geomID(N);
  325. const unsigned int primID = prim.primID(N)[i];
  326. const CurveGeometry* geom = context->scene->get<CurveGeometry>(geomID);
  327. Vec3ff a0,a1,a2,a3; geom->gather(a0,a1,a2,a3,geom->curve(primID),ray.time()[k]);
  328. if (Intersector().intersect(pre,ray,k,context,geom,primID,a0,a1,a2,a3,Epilog(ray,k,context,geomID,primID)))
  329. return true;
  330. mask &= movemask(tNear <= vfloat<M>(ray.tfar[k]));
  331. }
  332. return false;
  333. }
  334. template<typename Intersector, typename Epilog>
  335. static __forceinline void intersect_n(Precalculations& pre, RayHitK<K>& ray, const size_t k, RayQueryContext* context, const Primitive& prim)
  336. {
  337. vfloat<M> tNear;
  338. vbool<M> valid = intersect(ray,k,prim,tNear);
  339. const size_t N = prim.N;
  340. size_t mask = movemask(valid);
  341. while (mask)
  342. {
  343. const size_t i = bscf(mask);
  344. STAT3(normal.trav_prims,1,1,1);
  345. const unsigned int geomID = prim.geomID(N);
  346. const unsigned int primID = prim.primID(N)[i];
  347. const CurveGeometry* geom = context->scene->get<CurveGeometry>(geomID);
  348. const Vec3fa ray_org(ray.org.x[k], ray.org.y[k], ray.org.z[k]);
  349. const TensorLinearCubicBezierSurface3fa curve = geom->getNormalOrientedCurve<typename Intersector::SourceCurve3ff, typename Intersector::SourceCurve3fa, TensorLinearCubicBezierSurface3fa>(context, ray_org, primID,ray.time()[k]);
  350. Intersector().intersect(pre,ray,k,context,geom,primID,curve,Epilog(ray,k,context,geomID,primID));
  351. mask &= movemask(tNear <= vfloat<M>(ray.tfar[k]));
  352. }
  353. }
  354. template<typename Intersector, typename Epilog>
  355. static __forceinline bool occluded_n(Precalculations& pre, RayK<K>& ray, const size_t k, RayQueryContext* context, const Primitive& prim)
  356. {
  357. vfloat<M> tNear;
  358. vbool<M> valid = intersect(ray,k,prim,tNear);
  359. const size_t N = prim.N;
  360. size_t mask = movemask(valid);
  361. while (mask)
  362. {
  363. const size_t i = bscf(mask);
  364. STAT3(shadow.trav_prims,1,1,1);
  365. const unsigned int geomID = prim.geomID(N);
  366. const unsigned int primID = prim.primID(N)[i];
  367. const CurveGeometry* geom = context->scene->get<CurveGeometry>(geomID);
  368. const Vec3fa ray_org(ray.org.x[k], ray.org.y[k], ray.org.z[k]);
  369. const TensorLinearCubicBezierSurface3fa curve = geom->getNormalOrientedCurve<typename Intersector::SourceCurve3ff, typename Intersector::SourceCurve3fa, TensorLinearCubicBezierSurface3fa>(context, ray_org, primID,ray.time()[k]);
  370. if (Intersector().intersect(pre,ray,k,context,geom,primID,curve,Epilog(ray,k,context,geomID,primID)))
  371. return true;
  372. mask &= movemask(tNear <= vfloat<M>(ray.tfar[k]));
  373. }
  374. return false;
  375. }
  376. template<typename Intersector, typename Epilog>
  377. static __forceinline void intersect_h(Precalculations& pre, RayHitK<K>& ray, const size_t k, RayQueryContext* context, const Primitive& prim)
  378. {
  379. vfloat<M> tNear;
  380. vbool<M> valid = intersect(ray,k,prim,tNear);
  381. const size_t N = prim.N;
  382. size_t mask = movemask(valid);
  383. while (mask)
  384. {
  385. const size_t i = bscf(mask);
  386. STAT3(normal.trav_prims,1,1,1);
  387. const unsigned int geomID = prim.geomID(N);
  388. const unsigned int primID = prim.primID(N)[i];
  389. const CurveGeometry* geom = context->scene->get<CurveGeometry>(geomID);
  390. Vec3ff p0,t0,p1,t1; geom->gather_hermite(p0,t0,p1,t1,geom->curve(primID),ray.time()[k]);
  391. Intersector().intersect(pre,ray,k,context,geom,primID,p0,t0,p1,t1,Epilog(ray,k,context,geomID,primID));
  392. mask &= movemask(tNear <= vfloat<M>(ray.tfar[k]));
  393. }
  394. }
  395. template<typename Intersector, typename Epilog>
  396. static __forceinline bool occluded_h(Precalculations& pre, RayK<K>& ray, const size_t k, RayQueryContext* context, const Primitive& prim)
  397. {
  398. vfloat<M> tNear;
  399. vbool<M> valid = intersect(ray,k,prim,tNear);
  400. const size_t N = prim.N;
  401. size_t mask = movemask(valid);
  402. while (mask)
  403. {
  404. const size_t i = bscf(mask);
  405. STAT3(shadow.trav_prims,1,1,1);
  406. const unsigned int geomID = prim.geomID(N);
  407. const unsigned int primID = prim.primID(N)[i];
  408. const CurveGeometry* geom = context->scene->get<CurveGeometry>(geomID);
  409. Vec3ff p0,t0,p1,t1; geom->gather_hermite(p0,t0,p1,t1,geom->curve(primID),ray.time()[k]);
  410. if (Intersector().intersect(pre,ray,k,context,geom,primID,p0,t0,p1,t1,Epilog(ray,k,context,geomID,primID)))
  411. return true;
  412. mask &= movemask(tNear <= vfloat<M>(ray.tfar[k]));
  413. }
  414. return false;
  415. }
  416. template<typename Intersector, typename Epilog>
  417. static __forceinline void intersect_hn(Precalculations& pre, RayHitK<K>& ray, const size_t k, RayQueryContext* context, const Primitive& prim)
  418. {
  419. vfloat<M> tNear;
  420. vbool<M> valid = intersect(ray,k,prim,tNear);
  421. const size_t N = prim.N;
  422. size_t mask = movemask(valid);
  423. while (mask)
  424. {
  425. const size_t i = bscf(mask);
  426. STAT3(normal.trav_prims,1,1,1);
  427. const unsigned int geomID = prim.geomID(N);
  428. const unsigned int primID = prim.primID(N)[i];
  429. const CurveGeometry* geom = context->scene->get<CurveGeometry>(geomID);
  430. const Vec3fa ray_org(ray.org.x[k], ray.org.y[k], ray.org.z[k]);
  431. const TensorLinearCubicBezierSurface3fa curve = geom->getNormalOrientedHermiteCurve<typename Intersector::SourceCurve3ff, typename Intersector::SourceCurve3fa, TensorLinearCubicBezierSurface3fa>(context, ray_org, primID,ray.time()[k]);
  432. Intersector().intersect(pre,ray,k,context,geom,primID,curve,Epilog(ray,k,context,geomID,primID));
  433. mask &= movemask(tNear <= vfloat<M>(ray.tfar[k]));
  434. }
  435. }
  436. template<typename Intersector, typename Epilog>
  437. static __forceinline bool occluded_hn(Precalculations& pre, RayK<K>& ray, const size_t k, RayQueryContext* context, const Primitive& prim)
  438. {
  439. vfloat<M> tNear;
  440. vbool<M> valid = intersect(ray,k,prim,tNear);
  441. const size_t N = prim.N;
  442. size_t mask = movemask(valid);
  443. while (mask)
  444. {
  445. const size_t i = bscf(mask);
  446. STAT3(shadow.trav_prims,1,1,1);
  447. const unsigned int geomID = prim.geomID(N);
  448. const unsigned int primID = prim.primID(N)[i];
  449. const CurveGeometry* geom = context->scene->get<CurveGeometry>(geomID);
  450. const Vec3fa ray_org(ray.org.x[k], ray.org.y[k], ray.org.z[k]);
  451. const TensorLinearCubicBezierSurface3fa curve = geom->getNormalOrientedHermiteCurve<typename Intersector::SourceCurve3ff, typename Intersector::SourceCurve3fa, TensorLinearCubicBezierSurface3fa>(context, ray_org, primID,ray.time()[k]);
  452. if (Intersector().intersect(pre,ray,k,context,geom,primID,curve,Epilog(ray,k,context,geomID,primID)))
  453. return true;
  454. mask &= movemask(tNear <= vfloat<M>(ray.tfar[k]));
  455. }
  456. return false;
  457. }
  458. };
  459. }
  460. }