curveNi_intersector.h 28 KB

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