curveNi_intersector.h 24 KB

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