ray.h 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663
  1. // ======================================================================== //
  2. // Copyright 2009-2017 Intel Corporation //
  3. // //
  4. // Licensed under the Apache License, Version 2.0 (the "License"); //
  5. // you may not use this file except in compliance with the License. //
  6. // You may obtain a copy of the License at //
  7. // //
  8. // http://www.apache.org/licenses/LICENSE-2.0 //
  9. // //
  10. // Unless required by applicable law or agreed to in writing, software //
  11. // distributed under the License is distributed on an "AS IS" BASIS, //
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
  13. // See the License for the specific language governing permissions and //
  14. // limitations under the License. //
  15. // ======================================================================== //
  16. #pragma once
  17. #include "default.h"
  18. #define MAX_INTERNAL_STREAM_SIZE 64
  19. namespace embree
  20. {
  21. /* Ray structure for K rays */
  22. template<int K>
  23. struct RayK
  24. {
  25. /* Default construction does nothing */
  26. __forceinline RayK() {}
  27. /* Constructs a ray from origin, direction, and ray segment. Near
  28. * has to be smaller than far */
  29. __forceinline RayK(const Vec3<vfloat<K>>& org, const Vec3<vfloat<K>>& dir,
  30. const vfloat<K>& tnear = zero, const vfloat<K>& tfar = inf,
  31. const vfloat<K>& time = zero, const vint<K>& mask = -1)
  32. : org(org), dir(dir), tnear(tnear), tfar(tfar), time(time), mask(mask), geomID(-1), primID(-1), instID(-1) {}
  33. /* Returns the size of the ray */
  34. static __forceinline size_t size() { return K; }
  35. /* Tests if we hit something */
  36. __forceinline operator vbool<K>() const { return geomID != vint<K>(-1); }
  37. /* Calculates if this is a valid ray that does not cause issues during traversal */
  38. __forceinline vbool<K> valid() const
  39. {
  40. const vbool<K> vx = (abs(org.x) <= vfloat<K>(FLT_LARGE)) & (abs(dir.x) <= vfloat<K>(FLT_LARGE));
  41. const vbool<K> vy = (abs(org.y) <= vfloat<K>(FLT_LARGE)) & (abs(dir.y) <= vfloat<K>(FLT_LARGE));
  42. const vbool<K> vz = (abs(org.z) <= vfloat<K>(FLT_LARGE)) & (abs(dir.z) <= vfloat<K>(FLT_LARGE));
  43. const vbool<K> vn = abs(tnear) <= vfloat<K>(inf);
  44. const vbool<K> vf = abs(tfar) <= vfloat<K>(inf);
  45. return vx & vy & vz & vn & vf;
  46. }
  47. __forceinline void get(RayK<1>* ray) const;
  48. __forceinline void get(const size_t i, RayK<1>& ray) const;
  49. __forceinline void set(const RayK<1>* ray);
  50. __forceinline void set(const size_t i, const RayK<1>& ray);
  51. __forceinline void copy(const size_t dest, const size_t source);
  52. __forceinline void update(const vbool<K>& m_mask,
  53. const vfloat<K>& new_t,
  54. const vfloat<K>& new_u,
  55. const vfloat<K>& new_v,
  56. const vfloat<K>& new_gnormalx,
  57. const vfloat<K>& new_gnormaly,
  58. const vfloat<K>& new_gnormalz,
  59. const vint<K>& new_geomID,
  60. const vint<K>& new_primID)
  61. {
  62. vfloat<K>::store(m_mask,(float*)&tfar,new_t);
  63. vfloat<K>::store(m_mask,(float*)&u,new_u);
  64. vfloat<K>::store(m_mask,(float*)&v,new_v);
  65. vfloat<K>::store(m_mask,(float*)&Ng.x,new_gnormalx);
  66. vfloat<K>::store(m_mask,(float*)&Ng.y,new_gnormaly);
  67. vfloat<K>::store(m_mask,(float*)&Ng.z,new_gnormalz);
  68. vint<K>::store(m_mask,(int*)&geomID,new_geomID);
  69. vint<K>::store(m_mask,(int*)&primID,new_primID);
  70. }
  71. template<int M>
  72. __forceinline void updateK(const size_t i,
  73. const size_t rayIndex,
  74. const vfloat<M>& new_t,
  75. const vfloat<M>& new_u,
  76. const vfloat<M>& new_v,
  77. const vfloat<M>& new_gnormalx,
  78. const vfloat<M>& new_gnormaly,
  79. const vfloat<M>& new_gnormalz,
  80. const int new_geomID,
  81. const vint<M> &new_primID)
  82. {
  83. u[rayIndex] = new_u[i];
  84. v[rayIndex] = new_v[i];
  85. tfar[rayIndex] = new_t[i];
  86. Ng.x[rayIndex] = new_gnormalx[i];
  87. Ng.y[rayIndex] = new_gnormaly[i];
  88. Ng.z[rayIndex] = new_gnormalz[i];
  89. geomID[rayIndex] = new_geomID;
  90. primID[rayIndex] = new_primID[i];
  91. }
  92. /* Ray data */
  93. Vec3<vfloat<K>> org; // ray origin
  94. Vec3<vfloat<K>> dir; // ray direction
  95. vfloat<K> tnear; // start of ray segment
  96. vfloat<K> tfar; // end of ray segment
  97. vfloat<K> time; // time of this ray for motion blur.
  98. vint<K> mask; // used to mask out objects during traversal
  99. /* Hit data */
  100. Vec3<vfloat<K>> Ng; // geometry normal
  101. vfloat<K> u; // barycentric u coordinate of hit
  102. vfloat<K> v; // barycentric v coordinate of hit
  103. vint<K> geomID; // geometry ID
  104. vint<K> primID; // primitive ID
  105. vint<K> instID; // instance ID
  106. };
  107. #if defined(__AVX512F__)
  108. template<> template<>
  109. __forceinline void RayK<16>::updateK<16>(const size_t i,
  110. const size_t rayIndex,
  111. const vfloat16& new_t,
  112. const vfloat16& new_u,
  113. const vfloat16& new_v,
  114. const vfloat16& new_gnormalx,
  115. const vfloat16& new_gnormaly,
  116. const vfloat16& new_gnormalz,
  117. const int new_geomID,
  118. const vint16 &new_primID)
  119. {
  120. const vbool16 m_mask((unsigned int)1 << i);
  121. vfloat16::storeu_compact_single(m_mask,&tfar[rayIndex],new_t);
  122. vfloat16::storeu_compact_single(m_mask,&Ng.x[rayIndex],new_gnormalx);
  123. vfloat16::storeu_compact_single(m_mask,&Ng.y[rayIndex],new_gnormaly);
  124. vfloat16::storeu_compact_single(m_mask,&Ng.z[rayIndex],new_gnormalz);
  125. vfloat16::storeu_compact_single(m_mask,&u[rayIndex],new_u);
  126. vfloat16::storeu_compact_single(m_mask,&v[rayIndex],new_v);
  127. vint16::storeu_compact_single(m_mask,&primID[rayIndex],new_primID);
  128. geomID[rayIndex] = new_geomID;
  129. }
  130. #endif
  131. /* Specialization for a single ray */
  132. template<>
  133. struct RayK<1>
  134. {
  135. /* Default construction does nothing */
  136. __forceinline RayK() {}
  137. /* Constructs a ray from origin, direction, and ray segment. Near
  138. * has to be smaller than far */
  139. __forceinline RayK(const Vec3fa& org, const Vec3fa& dir, float tnear = zero, float tfar = inf, float time = zero, int mask = -1)
  140. : org(org), dir(dir), tnear(tnear), tfar(tfar), time(time), mask(mask), geomID(-1), primID(-1), instID(-1) {}
  141. /* Tests if we hit something */
  142. __forceinline operator bool() const { return geomID != RTC_INVALID_GEOMETRY_ID; }
  143. /* Calculates if this is a valid ray that does not cause issues during traversal */
  144. __forceinline bool valid() const {
  145. return all(le_mask(abs(org),Vec3fa(FLT_LARGE)) & le_mask(abs(dir),Vec3fa(FLT_LARGE))) && fabs(tnear) <= float(inf) && fabs(tfar) <= float(inf);
  146. }
  147. /* filter out all occluded rays from a stream of rays */
  148. __forceinline static void filterOutOccluded(RayK<1>** ray, size_t& N)
  149. {
  150. size_t l=0, r=N;
  151. while (l<r) {
  152. if (ray[l]->geomID != 0) l++;
  153. else std::swap(ray[l],ray[--r]);
  154. }
  155. N = l;
  156. }
  157. /* Ray data */
  158. Vec3fa org; // ray origin
  159. Vec3fa dir; // ray direction
  160. float tnear; // start of ray segment
  161. float tfar; // end of ray segment
  162. float time; // time of this ray for motion blur.
  163. int mask; // used to mask out objects during traversal
  164. /* Hit data */
  165. Vec3fa Ng; // not normalized geometry normal
  166. float u; // barycentric u coordinate of hit
  167. float v; // barycentric v coordinate of hit
  168. unsigned geomID; // geometry ID
  169. unsigned primID; // primitive ID
  170. unsigned instID; // instance ID
  171. #if defined(__AVX512F__)
  172. __forceinline void update(const vbool16& m_mask,
  173. const vfloat16& new_t,
  174. const vfloat16& new_u,
  175. const vfloat16& new_v,
  176. const vfloat16& new_gnormalx,
  177. const vfloat16& new_gnormaly,
  178. const vfloat16& new_gnormalz,
  179. const int new_geomID,
  180. const int new_primID)
  181. {
  182. geomID = new_geomID;
  183. primID = new_primID;
  184. vfloat16::storeu_compact_single(m_mask,&tfar,new_t);
  185. vfloat16::storeu_compact_single(m_mask,&u,new_u);
  186. vfloat16::storeu_compact_single(m_mask,&v,new_v);
  187. vfloat16::storeu_compact_single(m_mask,&Ng.x,new_gnormalx);
  188. vfloat16::storeu_compact_single(m_mask,&Ng.y,new_gnormaly);
  189. vfloat16::storeu_compact_single(m_mask,&Ng.z,new_gnormalz);
  190. }
  191. __forceinline void update(const vbool16& m_mask,
  192. const vfloat16& new_t,
  193. const vfloat16& new_u,
  194. const vfloat16& new_v,
  195. const vfloat16& new_gnormalx,
  196. const vfloat16& new_gnormaly,
  197. const vfloat16& new_gnormalz,
  198. const vint16 &new_geomID,
  199. const vint16 &new_primID)
  200. {
  201. vint16::storeu_compact_single(m_mask,&geomID,new_geomID);
  202. vint16::storeu_compact_single(m_mask,&primID,new_primID);
  203. vfloat16::storeu_compact_single(m_mask,&tfar,new_t);
  204. vfloat16::storeu_compact_single(m_mask,&u,new_u);
  205. vfloat16::storeu_compact_single(m_mask,&v,new_v);
  206. vfloat16::storeu_compact_single(m_mask,&Ng.x,new_gnormalx);
  207. vfloat16::storeu_compact_single(m_mask,&Ng.y,new_gnormaly);
  208. vfloat16::storeu_compact_single(m_mask,&Ng.z,new_gnormalz);
  209. }
  210. #endif
  211. };
  212. /* Converts ray packet to single rays */
  213. template<int K>
  214. __forceinline void RayK<K>::get(RayK<1>* ray) const
  215. {
  216. for (size_t i=0; i<K; i++) // FIXME: use SIMD transpose
  217. {
  218. ray[i].org.x = org.x[i]; ray[i].org.y = org.y[i]; ray[i].org.z = org.z[i];
  219. ray[i].dir.x = dir.x[i]; ray[i].dir.y = dir.y[i]; ray[i].dir.z = dir.z[i];
  220. ray[i].tnear = tnear[i]; ray[i].tfar = tfar [i]; ray[i].time = time[i]; ray[i].mask = mask[i];
  221. ray[i].Ng.x = Ng.x[i]; ray[i].Ng.y = Ng.y[i]; ray[i].Ng.z = Ng.z[i];
  222. ray[i].u = u[i]; ray[i].v = v[i];
  223. ray[i].geomID = geomID[i]; ray[i].primID = primID[i]; ray[i].instID = instID[i];
  224. }
  225. }
  226. /* Extracts a single ray out of a ray packet*/
  227. template<int K>
  228. __forceinline void RayK<K>::get(const size_t i, RayK<1>& ray) const
  229. {
  230. ray.org.x = org.x[i]; ray.org.y = org.y[i]; ray.org.z = org.z[i];
  231. ray.dir.x = dir.x[i]; ray.dir.y = dir.y[i]; ray.dir.z = dir.z[i];
  232. ray.tnear = tnear[i]; ray.tfar = tfar [i]; ray.time = time[i]; ray.mask = mask[i];
  233. ray.Ng.x = Ng.x[i]; ray.Ng.y = Ng.y[i]; ray.Ng.z = Ng.z[i];
  234. ray.u = u[i]; ray.v = v[i];
  235. ray.geomID = geomID[i]; ray.primID = primID[i]; ray.instID = instID[i];
  236. }
  237. /* Converts single rays to ray packet */
  238. template<int K>
  239. __forceinline void RayK<K>::set(const RayK<1>* ray)
  240. {
  241. for (size_t i=0; i<K; i++)
  242. {
  243. org.x[i] = ray[i].org.x; org.y[i] = ray[i].org.y; org.z[i] = ray[i].org.z;
  244. dir.x[i] = ray[i].dir.x; dir.y[i] = ray[i].dir.y; dir.z[i] = ray[i].dir.z;
  245. tnear[i] = ray[i].tnear; tfar [i] = ray[i].tfar; time[i] = ray[i].time; mask[i] = ray[i].mask;
  246. Ng.x[i] = ray[i].Ng.x; Ng.y[i] = ray[i].Ng.y; Ng.z[i] = ray[i].Ng.z;
  247. u[i] = ray[i].u; v[i] = ray[i].v;
  248. geomID[i] = ray[i].geomID; primID[i] = ray[i].primID; instID[i] = ray[i].instID;
  249. }
  250. }
  251. /* inserts a single ray into a ray packet element */
  252. template<int K>
  253. __forceinline void RayK<K>::set(const size_t i, const RayK<1>& ray)
  254. {
  255. org.x[i] = ray.org.x; org.y[i] = ray.org.y; org.z[i] = ray.org.z;
  256. dir.x[i] = ray.dir.x; dir.y[i] = ray.dir.y; dir.z[i] = ray.dir.z;
  257. tnear[i] = ray.tnear; tfar [i] = ray.tfar; time[i] = ray.time; mask[i] = ray.mask;
  258. Ng.x[i] = ray.Ng.x; Ng.y[i] = ray.Ng.y; Ng.z[i] = ray.Ng.z;
  259. u[i] = ray.u; v[i] = ray.v;
  260. geomID[i] = ray.geomID; primID[i] = ray.primID; instID[i] = ray.instID;
  261. }
  262. /* copies a ray packet element into another element*/
  263. template<int K>
  264. __forceinline void RayK<K>::copy(const size_t dest, const size_t source)
  265. {
  266. org.x[dest] = org.x[source]; org.y[dest] = org.y[source]; org.z[dest] = org.z[source];
  267. dir.x[dest] = dir.x[source]; dir.y[dest] = dir.y[source]; dir.z[dest] = dir.z[source];
  268. tnear[dest] = tnear[source]; tfar [dest] = tfar[source]; time[dest] = time[source]; mask[dest] = mask[source];
  269. Ng.x[dest] = Ng.x[source]; Ng.y[dest] = Ng.y[source]; Ng.z[dest] = Ng.z[source];
  270. u[dest] = u[source]; v[dest] = v[source];
  271. geomID[dest] = geomID[source]; primID[dest] = primID[source]; instID[dest] = instID[source];
  272. }
  273. /* Shortcuts */
  274. typedef RayK<1> Ray;
  275. typedef RayK<4> Ray4;
  276. typedef RayK<8> Ray8;
  277. typedef RayK<16> Ray16;
  278. /* Outputs ray to stream */
  279. template<int K>
  280. inline std::ostream& operator<<(std::ostream& cout, const RayK<K>& ray)
  281. {
  282. return cout << "{ " << std::endl
  283. << " org = " << ray.org << std::endl
  284. << " dir = " << ray.dir << std::endl
  285. << " near = " << ray.tnear << std::endl
  286. << " far = " << ray.tfar << std::endl
  287. << " time = " << ray.time << std::endl
  288. << " mask = " << ray.mask << std::endl
  289. << " instID = " << ray.instID << std::endl
  290. << " geomID = " << ray.geomID << std::endl
  291. << " primID = " << ray.primID << std::endl
  292. << " u = " << ray.u << std::endl
  293. << " v = " << ray.v << std::endl
  294. << " Ng = " << ray.Ng
  295. << "}";
  296. }
  297. struct RayPacket
  298. {
  299. public:
  300. __forceinline RayPacket(void* ptr, size_t K)
  301. : ptr((char*)ptr), K(K) {}
  302. public:
  303. /* ray data access functions */
  304. __forceinline float* orgx(size_t offset) { return (float*) &ptr[0*4*K+offset]; } //!< x coordinate of ray origin
  305. __forceinline float* orgy(size_t offset) { return (float*) &ptr[1*4*K+offset]; } //!< y coordinate of ray origin
  306. __forceinline float* orgz(size_t offset) { return (float*) &ptr[2*4*K+offset]; }; //!< z coordinate of ray origin
  307. __forceinline float* dirx(size_t offset) { return (float*) &ptr[3*4*K+offset]; }; //!< x coordinate of ray direction
  308. __forceinline float* diry(size_t offset) { return (float*) &ptr[4*4*K+offset]; }; //!< y coordinate of ray direction
  309. __forceinline float* dirz(size_t offset) { return (float*) &ptr[5*4*K+offset]; }; //!< z coordinate of ray direction
  310. __forceinline float* tnear(size_t offset) { return (float*) &ptr[6*4*K+offset]; }; //!< Start of ray segment
  311. __forceinline float* tfar (size_t offset) { return (float*) &ptr[7*4*K+offset]; }; //!< End of ray segment (set to hit distance)
  312. __forceinline float* time(size_t offset) { return (float*) &ptr[8*4*K+offset]; }; //!< Time of this ray for motion blur
  313. __forceinline int* mask(size_t offset) { return (int*) &ptr[9*4*K+offset]; }; //!< Used to mask out objects during traversal (optional)
  314. /* hit data access functions */
  315. __forceinline float* Ngx(size_t offset) { return (float*) &ptr[10*4*K+offset]; }; //!< x coordinate of geometry normal
  316. __forceinline float* Ngy(size_t offset) { return (float*) &ptr[11*4*K+offset]; }; //!< y coordinate of geometry normal
  317. __forceinline float* Ngz(size_t offset) { return (float*) &ptr[12*4*K+offset]; }; //!< z coordinate of geometry normal
  318. __forceinline float* u(size_t offset) { return (float*) &ptr[13*4*K+offset]; }; //!< Barycentric u coordinate of hit
  319. __forceinline float* v(size_t offset) { return (float*) &ptr[14*4*K+offset]; }; //!< Barycentric v coordinate of hit
  320. __forceinline int* geomID(size_t offset) { return (int*) &ptr[15*4*K+offset]; }; //!< geometry ID
  321. __forceinline int* primID(size_t offset) { return (int*) &ptr[16*4*K+offset]; }; //!< primitive ID
  322. __forceinline int* instID(size_t offset) { return (int*) &ptr[17*4*K+offset]; }; //!< instance ID
  323. public:
  324. __forceinline void writeRay(const size_t i, int* valid, Ray& ray)
  325. {
  326. const size_t offset = 4*i;
  327. valid[i] = -1;
  328. orgx(offset)[0] = ray.org.x;
  329. orgy(offset)[0] = ray.org.y;
  330. orgz(offset)[0] = ray.org.z;
  331. dirx(offset)[0] = ray.dir.x;
  332. diry(offset)[0] = ray.dir.y;
  333. dirz(offset)[0] = ray.dir.z;
  334. tnear(offset)[0] = ray.tnear;
  335. tfar(offset)[0] = ray.tfar;
  336. time(offset)[0] = ray.time;
  337. mask(offset)[0] = ray.mask;
  338. instID(offset)[0] = ray.instID;
  339. geomID(offset)[0] = RTC_INVALID_GEOMETRY_ID;
  340. }
  341. __forceinline void readHit(const size_t i, Ray& ray)
  342. {
  343. const size_t offset = 4*i;
  344. const unsigned int geometryID = geomID(offset)[0];
  345. if (geometryID != RTC_INVALID_GEOMETRY_ID)
  346. {
  347. ray.tfar = tfar(offset)[0];
  348. ray.u = u(offset)[0];
  349. ray.v = v(offset)[0];
  350. ray.Ng.x = Ngx(offset)[0];
  351. ray.Ng.y = Ngy(offset)[0];
  352. ray.Ng.z = Ngz(offset)[0];
  353. ray.instID = instID(offset)[0];
  354. ray.geomID = geometryID;
  355. ray.primID = primID(offset)[0];
  356. }
  357. }
  358. __forceinline void readOcclusion(const size_t i, Ray& ray) {
  359. ray.geomID = geomID(4*i)[0];
  360. }
  361. __forceinline Ray gather(const size_t offset)
  362. {
  363. Ray ray;
  364. ray.org.x = orgx(offset)[0];
  365. ray.org.y = orgy(offset)[0];
  366. ray.org.z = orgz(offset)[0];
  367. ray.dir.x = dirx(offset)[0];
  368. ray.dir.y = diry(offset)[0];
  369. ray.dir.z = dirz(offset)[0];
  370. ray.tnear = tnear(offset)[0];
  371. ray.tfar = tfar(offset)[0];
  372. ray.time = time(offset)[0];
  373. ray.mask = mask(offset)[0];
  374. ray.instID = instID(offset)[0];
  375. ray.geomID = RTC_INVALID_GEOMETRY_ID;
  376. return ray;
  377. }
  378. template<int K>
  379. __forceinline RayK<K> gather(const size_t offset)
  380. {
  381. RayK<K> ray;
  382. ray.org.x = vfloat<K>::loadu(orgx(offset));
  383. ray.org.y = vfloat<K>::loadu(orgy(offset));
  384. ray.org.z = vfloat<K>::loadu(orgz(offset));
  385. ray.dir.x = vfloat<K>::loadu(dirx(offset));
  386. ray.dir.y = vfloat<K>::loadu(diry(offset));
  387. ray.dir.z = vfloat<K>::loadu(dirz(offset));
  388. ray.tnear = vfloat<K>::loadu(tnear(offset));
  389. ray.tfar = vfloat<K>::loadu(tfar(offset));
  390. ray.time = vfloat<K>::loadu(time(offset));
  391. ray.mask = vint<K> ::loadu(mask(offset));
  392. ray.instID= vint<K> ::loadu(instID(offset));
  393. ray.geomID = RTC_INVALID_GEOMETRY_ID;
  394. return ray;
  395. }
  396. __forceinline void scatter(const size_t offset, const Ray& ray, const bool all)
  397. {
  398. geomID(offset)[0] = ray.geomID;
  399. if (all && ray.geomID != RTC_INVALID_GEOMETRY_ID)
  400. {
  401. tfar(offset)[0] = ray.tfar;
  402. u(offset)[0] = ray.u;
  403. v(offset)[0] = ray.v;
  404. primID(offset)[0] = ray.primID;
  405. Ngx(offset)[0] = ray.Ng.x;
  406. Ngy(offset)[0] = ray.Ng.y;
  407. Ngz(offset)[0] = ray.Ng.z;
  408. instID(offset)[0] = ray.instID;
  409. }
  410. }
  411. template<int K>
  412. __forceinline void scatter(const vbool<K>& valid_i, const size_t offset, const RayK<K>& ray, const bool all)
  413. {
  414. vbool<K> valid = valid_i;
  415. vint<K>::storeu(valid,geomID(offset),ray.geomID);
  416. if (!all) return;
  417. valid &= ray.geomID != RTC_INVALID_GEOMETRY_ID;
  418. if (none(valid)) return;
  419. vfloat<K>::storeu(valid,tfar(offset),ray.tfar);
  420. vfloat<K>::storeu(valid,u(offset),ray.u);
  421. vfloat<K>::storeu(valid,v(offset),ray.v);
  422. vint<K> ::storeu(valid,primID(offset),ray.primID);
  423. vfloat<K>::storeu(valid,Ngx(offset),ray.Ng.x);
  424. vfloat<K>::storeu(valid,Ngy(offset),ray.Ng.y);
  425. vfloat<K>::storeu(valid,Ngz(offset),ray.Ng.z);
  426. vint<K> ::storeu(valid,instID(offset),ray.instID);
  427. }
  428. __forceinline size_t getOctant(const size_t offset)
  429. {
  430. const float dx = dirx(offset)[0];
  431. const float dy = diry(offset)[0];
  432. const float dz = dirz(offset)[0];
  433. const size_t octantID = (dx < 0.0f ? 1 : 0) + (dy < 0.0f ? 2 : 0) + (dz < 0.0f ? 4 : 0);
  434. return octantID;
  435. }
  436. __forceinline bool isValid(const size_t offset)
  437. {
  438. const float nnear = tnear(offset)[0];
  439. const float ffar = tfar(offset)[0];
  440. return nnear <= ffar;
  441. }
  442. public:
  443. char* __restrict__ ptr;
  444. size_t K;
  445. };
  446. template<size_t MAX_K>
  447. struct StackRayPacket : public RayPacket
  448. {
  449. public:
  450. __forceinline StackRayPacket(size_t K)
  451. : RayPacket(data,K) { assert(K<=MAX_K); }
  452. public:
  453. char data[MAX_K/4*sizeof(Ray4)];
  454. };
  455. struct RayPN
  456. {
  457. /* ray data */
  458. public:
  459. float* __restrict__ orgx; //!< x coordinate of ray origin
  460. float* __restrict__ orgy; //!< y coordinate of ray origin
  461. float* __restrict__ orgz; //!< z coordinate of ray origin
  462. float* __restrict__ dirx; //!< x coordinate of ray direction
  463. float* __restrict__ diry; //!< y coordinate of ray direction
  464. float* __restrict__ dirz; //!< z coordinate of ray direction
  465. float* __restrict__ tnear; //!< Start of ray segment (optional)
  466. float* __restrict__ tfar; //!< End of ray segment (set to hit distance)
  467. float* __restrict__ time; //!< Time of this ray for motion blur (optional)
  468. unsigned* __restrict__ mask; //!< Used to mask out objects during traversal (optional)
  469. /* hit data */
  470. float* __restrict__ Ngx; //!< x coordinate of geometry normal (optional)
  471. float* __restrict__ Ngy; //!<y coordinate of geometry normal (optional)
  472. float* __restrict__ Ngz; //!< z coordinate of geometry normal (optional)
  473. float* __restrict__ u; //!< Barycentric u coordinate of hit
  474. float* __restrict__ v; //!< Barycentric v coordinate of hit
  475. unsigned* __restrict__ geomID; //!< geometry ID
  476. unsigned* __restrict__ primID; //!< primitive ID
  477. unsigned* __restrict__ instID; //!< instance ID (optional)
  478. template<class T>
  479. __forceinline void init(T &t)
  480. {
  481. orgx = (float*)&t.org.x;
  482. orgy = (float*)&t.org.y;
  483. orgz = (float*)&t.org.z;
  484. dirx = (float*)&t.dir.x;
  485. diry = (float*)&t.dir.y;
  486. dirz = (float*)&t.dir.z;
  487. tnear = (float*)&t.tnear;
  488. tfar = (float*)&t.tfar;
  489. time = (float*)&t.time;
  490. mask = (unsigned *)&t.mask;
  491. Ngx = (float*)&t.Ng.x;
  492. Ngy = (float*)&t.Ng.y;
  493. Ngz = (float*)&t.Ng.z;
  494. u = (float*)&t.u;
  495. v = (float*)&t.v;
  496. geomID = (unsigned *)&t.geomID;
  497. primID = (unsigned *)&t.primID;
  498. instID = (unsigned *)&t.instID;
  499. }
  500. __forceinline Ray gatherByOffset(const size_t offset)
  501. {
  502. Ray ray;
  503. ray.org.x = *(float* __restrict__ )((char*)orgx + offset);
  504. ray.org.y = *(float* __restrict__ )((char*)orgy + offset);
  505. ray.org.z = *(float* __restrict__ )((char*)orgz + offset);
  506. ray.dir.x = *(float* __restrict__ )((char*)dirx + offset);
  507. ray.dir.y = *(float* __restrict__ )((char*)diry + offset);
  508. ray.dir.z = *(float* __restrict__ )((char*)dirz + offset);
  509. ray.tfar = *(float* __restrict__ )((char*)tfar + offset);
  510. ray.tnear = tnear ? *(float* __restrict__ )((char*)tnear + offset) : 0.0f;
  511. ray.time = time ? *(float* __restrict__ )((char*)time + offset) : 0.0f;
  512. ray.mask = mask ? *(unsigned * __restrict__ )((char*)mask + offset) : -1;
  513. ray.instID = instID ? *(unsigned * __restrict__ )((char*)instID + offset) : -1;
  514. ray.geomID = RTC_INVALID_GEOMETRY_ID;
  515. return ray;
  516. }
  517. template<int K>
  518. __forceinline RayK<K> gather(const vbool<K>& valid, const size_t offset)
  519. {
  520. RayK<K> ray;
  521. ray.org.x = vfloat<K>::loadu(valid,(float* __restrict__ )((char*)orgx + offset));
  522. ray.org.y = vfloat<K>::loadu(valid,(float* __restrict__ )((char*)orgy + offset));
  523. ray.org.z = vfloat<K>::loadu(valid,(float* __restrict__ )((char*)orgz + offset));
  524. ray.dir.x = vfloat<K>::loadu(valid,(float* __restrict__ )((char*)dirx + offset));
  525. ray.dir.y = vfloat<K>::loadu(valid,(float* __restrict__ )((char*)diry + offset));
  526. ray.dir.z = vfloat<K>::loadu(valid,(float* __restrict__ )((char*)dirz + offset));
  527. ray.tfar = vfloat<K>::loadu(valid,(float* __restrict__ )((char*)tfar + offset));
  528. ray.tnear = tnear ? vfloat<K>::loadu(valid,(float* __restrict__ )((char*)tnear + offset)) : 0.0f;
  529. ray.time = time ? vfloat<K>::loadu(valid,(float* __restrict__ )((char*)time + offset)) : 0.0f;
  530. ray.mask = mask ? vint<K>::loadu(valid,(const void * __restrict__ )((char*)mask + offset)) : -1;
  531. ray.instID = instID ? vint<K>::loadu(valid,(const void * __restrict__ )((char*)instID + offset)) : -1;
  532. ray.geomID = RTC_INVALID_GEOMETRY_ID;
  533. return ray;
  534. }
  535. __forceinline void scatterByOffset(const size_t offset, const Ray& ray, const bool all=true)
  536. {
  537. *(unsigned * __restrict__ )((char*)geomID + offset) = ray.geomID;
  538. if (all)
  539. if (ray.geomID != RTC_INVALID_GEOMETRY_ID)
  540. {
  541. *(float* __restrict__ )((char*)tfar + offset) = ray.tfar;
  542. *(float* __restrict__ )((char*)u + offset) = ray.u;
  543. *(float* __restrict__ )((char*)v + offset) = ray.v;
  544. *(unsigned * __restrict__ )((char*)primID + offset) = ray.primID;
  545. if (likely(Ngx)) *(float* __restrict__ )((char*)Ngx + offset) = ray.Ng.x;
  546. if (likely(Ngy)) *(float* __restrict__ )((char*)Ngy + offset) = ray.Ng.y;
  547. if (likely(Ngz)) *(float* __restrict__ )((char*)Ngz + offset) = ray.Ng.z;
  548. if (likely(instID)) *(unsigned * __restrict__ )((char*)instID + offset) = ray.instID;
  549. }
  550. }
  551. template<int K>
  552. __forceinline void scatter(const vbool<K>& valid_i, const size_t offset, const RayK<K>& ray, const bool all=true)
  553. {
  554. vbool<K> valid = valid_i;
  555. vint<K>::storeu(valid,(int * __restrict__ )((char*)geomID + offset), ray.geomID);
  556. if (!all) return;
  557. valid &= ray.geomID != RTC_INVALID_GEOMETRY_ID;
  558. if (none(valid)) return;
  559. vfloat<K>::storeu(valid,(float* __restrict__ )((char*)tfar + offset), ray.tfar);
  560. vfloat<K>::storeu(valid,(float* __restrict__ )((char*)u + offset), ray.u);
  561. vfloat<K>::storeu(valid,(float* __restrict__ )((char*)v + offset), ray.v);
  562. vint<K>::storeu(valid,(int * __restrict__ )((char*)primID + offset), ray.primID);
  563. if (likely(Ngx)) vfloat<K>::storeu(valid,(float* __restrict__ )((char*)Ngx + offset), ray.Ng.x);
  564. if (likely(Ngy)) vfloat<K>::storeu(valid,(float* __restrict__ )((char*)Ngy + offset), ray.Ng.y);
  565. if (likely(Ngz)) vfloat<K>::storeu(valid,(float* __restrict__ )((char*)Ngz + offset), ray.Ng.z);
  566. if (likely(instID)) vint<K>::storeu(valid,(int * __restrict__ )((char*)instID + offset), ray.instID);
  567. }
  568. __forceinline size_t getOctantByOffset(const size_t offset)
  569. {
  570. const float dx = *(float* __restrict__ )((char*)dirx + offset);
  571. const float dy = *(float* __restrict__ )((char*)diry + offset);
  572. const float dz = *(float* __restrict__ )((char*)dirz + offset);
  573. const size_t octantID = (dx < 0.0f ? 1 : 0) + (dy < 0.0f ? 2 : 0) + (dz < 0.0f ? 4 : 0);
  574. return octantID;
  575. }
  576. __forceinline bool isValidByOffset(const size_t offset)
  577. {
  578. const float nnear = tnear ? *(float* __restrict__ )((char*)tnear + offset) : 0.0f;
  579. const float ffar = *(float* __restrict__ )((char*)tfar + offset);
  580. return nnear <= ffar;
  581. }
  582. };
  583. }