curveNi_mb_intersector.h 25 KB

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