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