subgrid.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. // Copyright 2009-2021 Intel Corporation
  2. // SPDX-License-Identifier: Apache-2.0
  3. #pragma once
  4. #include "../common/ray.h"
  5. #include "../common/scene_grid_mesh.h"
  6. #include "../bvh/bvh.h"
  7. namespace embree
  8. {
  9. /* Stores M quads from an indexed face set */
  10. struct SubGrid
  11. {
  12. /* Virtual interface to query information about the quad type */
  13. struct Type : public PrimitiveType
  14. {
  15. const char* name() const;
  16. size_t sizeActive(const char* This) const;
  17. size_t sizeTotal(const char* This) const;
  18. size_t getBytes(const char* This) const;
  19. };
  20. static Type type;
  21. public:
  22. /* primitive supports multiple time segments */
  23. static const bool singleTimeSegment = false;
  24. /* Returns maximum number of stored quads */
  25. static __forceinline size_t max_size() { return 1; }
  26. /* Returns required number of primitive blocks for N primitives */
  27. static __forceinline size_t blocks(size_t N) { return (N+max_size()-1)/max_size(); }
  28. public:
  29. /* Default constructor */
  30. __forceinline SubGrid() { }
  31. /* Construction from vertices and IDs */
  32. __forceinline SubGrid(const unsigned int x,
  33. const unsigned int y,
  34. const unsigned int geomID,
  35. const unsigned int primID)
  36. : _x(x), _y(y), _geomID(geomID), _primID(primID)
  37. {
  38. }
  39. __forceinline bool invalid3x3X() const { return (unsigned int)_x & (1<<15); }
  40. __forceinline bool invalid3x3Y() const { return (unsigned int)_y & (1<<15); }
  41. /* Gather the quads */
  42. __forceinline void gather(Vec3vf4& p0,
  43. Vec3vf4& p1,
  44. Vec3vf4& p2,
  45. Vec3vf4& p3,
  46. const GridMesh* const mesh,
  47. const GridMesh::Grid &g) const
  48. {
  49. /* first quad always valid */
  50. const size_t vtxID00 = g.startVtxID + x() + y() * g.lineVtxOffset;
  51. const size_t vtxID01 = vtxID00 + 1;
  52. const vfloat4 vtx00 = vfloat4::loadu(mesh->vertexPtr(vtxID00));
  53. const vfloat4 vtx01 = vfloat4::loadu(mesh->vertexPtr(vtxID01));
  54. const size_t vtxID10 = vtxID00 + g.lineVtxOffset;
  55. const size_t vtxID11 = vtxID01 + g.lineVtxOffset;
  56. const vfloat4 vtx10 = vfloat4::loadu(mesh->vertexPtr(vtxID10));
  57. const vfloat4 vtx11 = vfloat4::loadu(mesh->vertexPtr(vtxID11));
  58. /* deltaX => vtx02, vtx12 */
  59. const size_t deltaX = invalid3x3X() ? 0 : 1;
  60. const size_t vtxID02 = vtxID01 + deltaX;
  61. const vfloat4 vtx02 = vfloat4::loadu(mesh->vertexPtr(vtxID02));
  62. const size_t vtxID12 = vtxID11 + deltaX;
  63. const vfloat4 vtx12 = vfloat4::loadu(mesh->vertexPtr(vtxID12));
  64. /* deltaY => vtx20, vtx21 */
  65. const size_t deltaY = invalid3x3Y() ? 0 : g.lineVtxOffset;
  66. const size_t vtxID20 = vtxID10 + deltaY;
  67. const size_t vtxID21 = vtxID11 + deltaY;
  68. const vfloat4 vtx20 = vfloat4::loadu(mesh->vertexPtr(vtxID20));
  69. const vfloat4 vtx21 = vfloat4::loadu(mesh->vertexPtr(vtxID21));
  70. /* deltaX/deltaY => vtx22 */
  71. const size_t vtxID22 = vtxID11 + deltaX + deltaY;
  72. const vfloat4 vtx22 = vfloat4::loadu(mesh->vertexPtr(vtxID22));
  73. transpose(vtx00,vtx01,vtx11,vtx10,p0.x,p0.y,p0.z);
  74. transpose(vtx01,vtx02,vtx12,vtx11,p1.x,p1.y,p1.z);
  75. transpose(vtx11,vtx12,vtx22,vtx21,p2.x,p2.y,p2.z);
  76. transpose(vtx10,vtx11,vtx21,vtx20,p3.x,p3.y,p3.z);
  77. }
  78. template<typename T>
  79. __forceinline vfloat4 getVertexMB(const GridMesh* const mesh, const size_t offset, const size_t itime, const float ftime) const
  80. {
  81. const T v0 = T::loadu(mesh->vertexPtr(offset,itime+0));
  82. const T v1 = T::loadu(mesh->vertexPtr(offset,itime+1));
  83. return lerp(v0,v1,ftime);
  84. }
  85. /* Gather the quads */
  86. __forceinline void gatherMB(Vec3vf4& p0,
  87. Vec3vf4& p1,
  88. Vec3vf4& p2,
  89. Vec3vf4& p3,
  90. const GridMesh* const mesh,
  91. const GridMesh::Grid &g,
  92. const size_t itime,
  93. const float ftime) const
  94. {
  95. /* first quad always valid */
  96. const size_t vtxID00 = g.startVtxID + x() + y() * g.lineVtxOffset;
  97. const size_t vtxID01 = vtxID00 + 1;
  98. const vfloat4 vtx00 = getVertexMB<vfloat4>(mesh,vtxID00,itime,ftime);
  99. const vfloat4 vtx01 = getVertexMB<vfloat4>(mesh,vtxID01,itime,ftime);
  100. const size_t vtxID10 = vtxID00 + g.lineVtxOffset;
  101. const size_t vtxID11 = vtxID01 + g.lineVtxOffset;
  102. const vfloat4 vtx10 = getVertexMB<vfloat4>(mesh,vtxID10,itime,ftime);
  103. const vfloat4 vtx11 = getVertexMB<vfloat4>(mesh,vtxID11,itime,ftime);
  104. /* deltaX => vtx02, vtx12 */
  105. const size_t deltaX = invalid3x3X() ? 0 : 1;
  106. const size_t vtxID02 = vtxID01 + deltaX;
  107. const vfloat4 vtx02 = getVertexMB<vfloat4>(mesh,vtxID02,itime,ftime);
  108. const size_t vtxID12 = vtxID11 + deltaX;
  109. const vfloat4 vtx12 = getVertexMB<vfloat4>(mesh,vtxID12,itime,ftime);
  110. /* deltaY => vtx20, vtx21 */
  111. const size_t deltaY = invalid3x3Y() ? 0 : g.lineVtxOffset;
  112. const size_t vtxID20 = vtxID10 + deltaY;
  113. const size_t vtxID21 = vtxID11 + deltaY;
  114. const vfloat4 vtx20 = getVertexMB<vfloat4>(mesh,vtxID20,itime,ftime);
  115. const vfloat4 vtx21 = getVertexMB<vfloat4>(mesh,vtxID21,itime,ftime);
  116. /* deltaX/deltaY => vtx22 */
  117. const size_t vtxID22 = vtxID11 + deltaX + deltaY;
  118. const vfloat4 vtx22 = getVertexMB<vfloat4>(mesh,vtxID22,itime,ftime);
  119. transpose(vtx00,vtx01,vtx11,vtx10,p0.x,p0.y,p0.z);
  120. transpose(vtx01,vtx02,vtx12,vtx11,p1.x,p1.y,p1.z);
  121. transpose(vtx11,vtx12,vtx22,vtx21,p2.x,p2.y,p2.z);
  122. transpose(vtx10,vtx11,vtx21,vtx20,p3.x,p3.y,p3.z);
  123. }
  124. /* Gather the quads */
  125. __forceinline void gather(Vec3vf4& p0,
  126. Vec3vf4& p1,
  127. Vec3vf4& p2,
  128. Vec3vf4& p3,
  129. const Scene *const scene) const
  130. {
  131. const GridMesh* const mesh = scene->get<GridMesh>(geomID());
  132. const GridMesh::Grid &g = mesh->grid(primID());
  133. gather(p0,p1,p2,p3,mesh,g);
  134. }
  135. /* Gather the quads in the motion blur case */
  136. __forceinline void gatherMB(Vec3vf4& p0,
  137. Vec3vf4& p1,
  138. Vec3vf4& p2,
  139. Vec3vf4& p3,
  140. const Scene *const scene,
  141. const size_t itime,
  142. const float ftime) const
  143. {
  144. const GridMesh* const mesh = scene->get<GridMesh>(geomID());
  145. const GridMesh::Grid &g = mesh->grid(primID());
  146. gatherMB(p0,p1,p2,p3,mesh,g,itime,ftime);
  147. }
  148. /* Gather the quads */
  149. __forceinline void gather(Vec3fa vtx[16], const Scene *const scene) const
  150. {
  151. const GridMesh* mesh = scene->get<GridMesh>(geomID());
  152. const GridMesh::Grid &g = mesh->grid(primID());
  153. /* first quad always valid */
  154. const size_t vtxID00 = g.startVtxID + x() + y() * g.lineVtxOffset;
  155. const size_t vtxID01 = vtxID00 + 1;
  156. const Vec3fa vtx00 = Vec3fa::loadu(mesh->vertexPtr(vtxID00));
  157. const Vec3fa vtx01 = Vec3fa::loadu(mesh->vertexPtr(vtxID01));
  158. const size_t vtxID10 = vtxID00 + g.lineVtxOffset;
  159. const size_t vtxID11 = vtxID01 + g.lineVtxOffset;
  160. const Vec3fa vtx10 = Vec3fa::loadu(mesh->vertexPtr(vtxID10));
  161. const Vec3fa vtx11 = Vec3fa::loadu(mesh->vertexPtr(vtxID11));
  162. /* deltaX => vtx02, vtx12 */
  163. const size_t deltaX = invalid3x3X() ? 0 : 1;
  164. const size_t vtxID02 = vtxID01 + deltaX;
  165. const Vec3fa vtx02 = Vec3fa::loadu(mesh->vertexPtr(vtxID02));
  166. const size_t vtxID12 = vtxID11 + deltaX;
  167. const Vec3fa vtx12 = Vec3fa::loadu(mesh->vertexPtr(vtxID12));
  168. /* deltaY => vtx20, vtx21 */
  169. const size_t deltaY = invalid3x3Y() ? 0 : g.lineVtxOffset;
  170. const size_t vtxID20 = vtxID10 + deltaY;
  171. const size_t vtxID21 = vtxID11 + deltaY;
  172. const Vec3fa vtx20 = Vec3fa::loadu(mesh->vertexPtr(vtxID20));
  173. const Vec3fa vtx21 = Vec3fa::loadu(mesh->vertexPtr(vtxID21));
  174. /* deltaX/deltaY => vtx22 */
  175. const size_t vtxID22 = vtxID11 + deltaX + deltaY;
  176. const Vec3fa vtx22 = Vec3fa::loadu(mesh->vertexPtr(vtxID22));
  177. vtx[ 0] = vtx00; vtx[ 1] = vtx01; vtx[ 2] = vtx11; vtx[ 3] = vtx10;
  178. vtx[ 4] = vtx01; vtx[ 5] = vtx02; vtx[ 6] = vtx12; vtx[ 7] = vtx11;
  179. vtx[ 8] = vtx10; vtx[ 9] = vtx11; vtx[10] = vtx21; vtx[11] = vtx20;
  180. vtx[12] = vtx11; vtx[13] = vtx12; vtx[14] = vtx22; vtx[15] = vtx21;
  181. }
  182. /* Gather the quads */
  183. __forceinline void gatherMB(vfloat4 vtx[16], const Scene *const scene, const size_t itime, const float ftime) const
  184. {
  185. const GridMesh* mesh = scene->get<GridMesh>(geomID());
  186. const GridMesh::Grid &g = mesh->grid(primID());
  187. /* first quad always valid */
  188. const size_t vtxID00 = g.startVtxID + x() + y() * g.lineVtxOffset;
  189. const size_t vtxID01 = vtxID00 + 1;
  190. const vfloat4 vtx00 = getVertexMB<vfloat4>(mesh,vtxID00,itime,ftime);
  191. const vfloat4 vtx01 = getVertexMB<vfloat4>(mesh,vtxID01,itime,ftime);
  192. const size_t vtxID10 = vtxID00 + g.lineVtxOffset;
  193. const size_t vtxID11 = vtxID01 + g.lineVtxOffset;
  194. const vfloat4 vtx10 = getVertexMB<vfloat4>(mesh,vtxID10,itime,ftime);
  195. const vfloat4 vtx11 = getVertexMB<vfloat4>(mesh,vtxID11,itime,ftime);
  196. /* deltaX => vtx02, vtx12 */
  197. const size_t deltaX = invalid3x3X() ? 0 : 1;
  198. const size_t vtxID02 = vtxID01 + deltaX;
  199. const vfloat4 vtx02 = getVertexMB<vfloat4>(mesh,vtxID02,itime,ftime);
  200. const size_t vtxID12 = vtxID11 + deltaX;
  201. const vfloat4 vtx12 = getVertexMB<vfloat4>(mesh,vtxID12,itime,ftime);
  202. /* deltaY => vtx20, vtx21 */
  203. const size_t deltaY = invalid3x3Y() ? 0 : g.lineVtxOffset;
  204. const size_t vtxID20 = vtxID10 + deltaY;
  205. const size_t vtxID21 = vtxID11 + deltaY;
  206. const vfloat4 vtx20 = getVertexMB<vfloat4>(mesh,vtxID20,itime,ftime);
  207. const vfloat4 vtx21 = getVertexMB<vfloat4>(mesh,vtxID21,itime,ftime);
  208. /* deltaX/deltaY => vtx22 */
  209. const size_t vtxID22 = vtxID11 + deltaX + deltaY;
  210. const vfloat4 vtx22 = getVertexMB<vfloat4>(mesh,vtxID22,itime,ftime);
  211. vtx[ 0] = vtx00; vtx[ 1] = vtx01; vtx[ 2] = vtx11; vtx[ 3] = vtx10;
  212. vtx[ 4] = vtx01; vtx[ 5] = vtx02; vtx[ 6] = vtx12; vtx[ 7] = vtx11;
  213. vtx[ 8] = vtx10; vtx[ 9] = vtx11; vtx[10] = vtx21; vtx[11] = vtx20;
  214. vtx[12] = vtx11; vtx[13] = vtx12; vtx[14] = vtx22; vtx[15] = vtx21;
  215. }
  216. /* Calculate the bounds of the subgrid */
  217. __forceinline const BBox3fa bounds(const Scene *const scene, const size_t itime=0) const
  218. {
  219. BBox3fa bounds = empty;
  220. FATAL("not implemented yet");
  221. return bounds;
  222. }
  223. /* Calculate the linear bounds of the primitive */
  224. __forceinline LBBox3fa linearBounds(const Scene* const scene, const size_t itime)
  225. {
  226. return LBBox3fa(bounds(scene,itime+0),bounds(scene,itime+1));
  227. }
  228. __forceinline LBBox3fa linearBounds(const Scene *const scene, size_t itime, size_t numTimeSteps)
  229. {
  230. LBBox3fa allBounds = empty;
  231. FATAL("not implemented yet");
  232. return allBounds;
  233. }
  234. __forceinline LBBox3fa linearBounds(const Scene *const scene, const BBox1f time_range)
  235. {
  236. LBBox3fa allBounds = empty;
  237. FATAL("not implemented yet");
  238. return allBounds;
  239. }
  240. friend embree_ostream operator<<(embree_ostream cout, const SubGrid& sg) {
  241. return cout << "SubGrid " << " ( x " << sg.x() << ", y = " << sg.y() << ", geomID = " << sg.geomID() << ", primID = " << sg.primID() << " )";
  242. }
  243. __forceinline unsigned int geomID() const { return _geomID; }
  244. __forceinline unsigned int primID() const { return _primID; }
  245. __forceinline unsigned int x() const { return (unsigned int)_x & 0x7fff; }
  246. __forceinline unsigned int y() const { return (unsigned int)_y & 0x7fff; }
  247. private:
  248. unsigned short _x;
  249. unsigned short _y;
  250. unsigned int _geomID; // geometry ID of mesh
  251. unsigned int _primID; // primitive ID of primitive inside mesh
  252. };
  253. struct SubGridID {
  254. unsigned short x;
  255. unsigned short y;
  256. unsigned int primID;
  257. __forceinline SubGridID() {}
  258. __forceinline SubGridID(const unsigned int x, const unsigned int y, const unsigned int primID) :
  259. x(x), y(y), primID(primID) {}
  260. };
  261. /* QuantizedBaseNode as large subgrid leaf */
  262. template<int N>
  263. struct SubGridQBVHN
  264. {
  265. /* Virtual interface to query information about the quad type */
  266. struct Type : public PrimitiveType
  267. {
  268. const char* name() const;
  269. size_t sizeActive(const char* This) const;
  270. size_t sizeTotal(const char* This) const;
  271. size_t getBytes(const char* This) const;
  272. };
  273. static Type type;
  274. public:
  275. __forceinline size_t size() const
  276. {
  277. for (size_t i=0;i<N;i++)
  278. if (primID(i) == -1) return i;
  279. return N;
  280. }
  281. __forceinline void clear() {
  282. for (size_t i=0;i<N;i++)
  283. subgridIDs[i] = SubGridID(0,0,(unsigned int)-1);
  284. qnode.clear();
  285. }
  286. /* Default constructor */
  287. __forceinline SubGridQBVHN() { }
  288. /* Construction from vertices and IDs */
  289. __forceinline SubGridQBVHN(const unsigned int x[N],
  290. const unsigned int y[N],
  291. const unsigned int primID[N],
  292. const BBox3fa * const subGridBounds,
  293. const unsigned int geomID,
  294. const unsigned int items)
  295. {
  296. clear();
  297. _geomID = geomID;
  298. __aligned(64) typename BVHN<N>::AABBNode node;
  299. node.clear();
  300. for (size_t i=0;i<items;i++)
  301. {
  302. subgridIDs[i] = SubGridID(x[i],y[i],primID[i]);
  303. node.setBounds(i,subGridBounds[i]);
  304. }
  305. qnode.init_dim(node);
  306. }
  307. __forceinline unsigned int geomID() const { return _geomID; }
  308. __forceinline unsigned int primID(const size_t i) const { assert(i < N); return subgridIDs[i].primID; }
  309. __forceinline unsigned int x(const size_t i) const { assert(i < N); return subgridIDs[i].x; }
  310. __forceinline unsigned int y(const size_t i) const { assert(i < N); return subgridIDs[i].y; }
  311. __forceinline SubGrid subgrid(const size_t i) const {
  312. assert(i < N);
  313. assert(primID(i) != -1);
  314. return SubGrid(x(i),y(i),geomID(),primID(i));
  315. }
  316. public:
  317. SubGridID subgridIDs[N];
  318. typename BVHN<N>::QuantizedBaseNode qnode;
  319. unsigned int _geomID; // geometry ID of mesh
  320. friend embree_ostream operator<<(embree_ostream cout, const SubGridQBVHN& sg) {
  321. cout << "SubGridQBVHN " << embree_endl;
  322. for (size_t i=0;i<N;i++)
  323. cout << i << " ( x = " << sg.subgridIDs[i].x << ", y = " << sg.subgridIDs[i].y << ", primID = " << sg.subgridIDs[i].primID << " )" << embree_endl;
  324. cout << "geomID " << sg._geomID << embree_endl;
  325. cout << "lowerX " << sg.qnode.dequantizeLowerX() << embree_endl;
  326. cout << "upperX " << sg.qnode.dequantizeUpperX() << embree_endl;
  327. cout << "lowerY " << sg.qnode.dequantizeLowerY() << embree_endl;
  328. cout << "upperY " << sg.qnode.dequantizeUpperY() << embree_endl;
  329. cout << "lowerZ " << sg.qnode.dequantizeLowerZ() << embree_endl;
  330. cout << "upperZ " << sg.qnode.dequantizeUpperZ() << embree_endl;
  331. return cout;
  332. }
  333. };
  334. template<int N>
  335. typename SubGridQBVHN<N>::Type SubGridQBVHN<N>::type;
  336. typedef SubGridQBVHN<4> SubGridQBVH4;
  337. typedef SubGridQBVHN<8> SubGridQBVH8;
  338. /* QuantizedBaseNode as large subgrid leaf */
  339. template<int N>
  340. struct SubGridMBQBVHN
  341. {
  342. /* Virtual interface to query information about the quad type */
  343. struct Type : public PrimitiveType
  344. {
  345. const char* name() const;
  346. size_t sizeActive(const char* This) const;
  347. size_t sizeTotal(const char* This) const;
  348. size_t getBytes(const char* This) const;
  349. };
  350. static Type type;
  351. public:
  352. __forceinline size_t size() const
  353. {
  354. for (size_t i=0;i<N;i++)
  355. if (primID(i) == -1) return i;
  356. return N;
  357. }
  358. __forceinline void clear() {
  359. for (size_t i=0;i<N;i++)
  360. subgridIDs[i] = SubGridID(0,0,(unsigned int)-1);
  361. qnode.clear();
  362. }
  363. /* Default constructor */
  364. __forceinline SubGridMBQBVHN() { }
  365. /* Construction from vertices and IDs */
  366. __forceinline SubGridMBQBVHN(const unsigned int x[N],
  367. const unsigned int y[N],
  368. const unsigned int primID[N],
  369. const BBox3fa * const subGridBounds0,
  370. const BBox3fa * const subGridBounds1,
  371. const unsigned int geomID,
  372. const float toffset,
  373. const float tscale,
  374. const unsigned int items)
  375. {
  376. clear();
  377. _geomID = geomID;
  378. time_offset = toffset;
  379. time_scale = tscale;
  380. __aligned(64) typename BVHN<N>::AABBNode node0,node1;
  381. node0.clear();
  382. node1.clear();
  383. for (size_t i=0;i<items;i++)
  384. {
  385. subgridIDs[i] = SubGridID(x[i],y[i],primID[i]);
  386. node0.setBounds(i,subGridBounds0[i]);
  387. node1.setBounds(i,subGridBounds1[i]);
  388. }
  389. qnode.node0.init_dim(node0);
  390. qnode.node1.init_dim(node1);
  391. }
  392. __forceinline unsigned int geomID() const { return _geomID; }
  393. __forceinline unsigned int primID(const size_t i) const { assert(i < N); return subgridIDs[i].primID; }
  394. __forceinline unsigned int x(const size_t i) const { assert(i < N); return subgridIDs[i].x; }
  395. __forceinline unsigned int y(const size_t i) const { assert(i < N); return subgridIDs[i].y; }
  396. __forceinline SubGrid subgrid(const size_t i) const {
  397. assert(i < N);
  398. assert(primID(i) != -1);
  399. return SubGrid(x(i),y(i),geomID(),primID(i));
  400. }
  401. __forceinline float adjustTime(const float t) const { return time_scale * (t-time_offset); }
  402. template<int K>
  403. __forceinline vfloat<K> adjustTime(const vfloat<K> &t) const { return time_scale * (t-time_offset); }
  404. public:
  405. SubGridID subgridIDs[N];
  406. typename BVHN<N>::QuantizedBaseNodeMB qnode;
  407. float time_offset;
  408. float time_scale;
  409. unsigned int _geomID; // geometry ID of mesh
  410. friend embree_ostream operator<<(embree_ostream cout, const SubGridMBQBVHN& sg) {
  411. cout << "SubGridMBQBVHN " << embree_endl;
  412. for (size_t i=0;i<N;i++)
  413. cout << i << " ( x = " << sg.subgridIDs[i].x << ", y = " << sg.subgridIDs[i].y << ", primID = " << sg.subgridIDs[i].primID << " )" << embree_endl;
  414. cout << "geomID " << sg._geomID << embree_endl;
  415. cout << "time_offset " << sg.time_offset << embree_endl;
  416. cout << "time_scale " << sg.time_scale << embree_endl;
  417. cout << "lowerX " << sg.qnode.node0.dequantizeLowerX() << embree_endl;
  418. cout << "upperX " << sg.qnode.node0.dequantizeUpperX() << embree_endl;
  419. cout << "lowerY " << sg.qnode.node0.dequantizeLowerY() << embree_endl;
  420. cout << "upperY " << sg.qnode.node0.dequantizeUpperY() << embree_endl;
  421. cout << "lowerZ " << sg.qnode.node0.dequantizeLowerZ() << embree_endl;
  422. cout << "upperZ " << sg.qnode.node0.dequantizeUpperZ() << embree_endl;
  423. cout << "lowerX " << sg.qnode.node1.dequantizeLowerX() << embree_endl;
  424. cout << "upperX " << sg.qnode.node1.dequantizeUpperX() << embree_endl;
  425. cout << "lowerY " << sg.qnode.node1.dequantizeLowerY() << embree_endl;
  426. cout << "upperY " << sg.qnode.node1.dequantizeUpperY() << embree_endl;
  427. cout << "lowerZ " << sg.qnode.node1.dequantizeLowerZ() << embree_endl;
  428. cout << "upperZ " << sg.qnode.node1.dequantizeUpperZ() << embree_endl;
  429. return cout;
  430. }
  431. };
  432. }