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 */ |
31 | static __forceinline size_t max_size() { return 1; } |
32 | |
33 | /* Returns required number of primitive blocks for N primitives */ |
34 | static __forceinline size_t blocks(size_t N) { return (N+max_size()-1)/max_size(); } |
35 | |
36 | public: |
37 | |
38 | /* Default constructor */ |
39 | __forceinline SubGrid() { } |
40 | |
41 | /* Construction from vertices and IDs */ |
42 | __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 | |
50 | __forceinline bool invalid3x3X() const { return (unsigned int)_x & (1<<15); } |
51 | __forceinline bool invalid3x3Y() const { return (unsigned int)_y & (1<<15); } |
52 | |
53 | /* Gather the quads */ |
54 | __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(a: mesh->vertexPtr(i: vtxID00)); |
65 | const vfloat4 vtx01 = vfloat4::loadu(a: mesh->vertexPtr(i: vtxID01)); |
66 | const size_t vtxID10 = vtxID00 + g.lineVtxOffset; |
67 | const size_t vtxID11 = vtxID01 + g.lineVtxOffset; |
68 | const vfloat4 vtx10 = vfloat4::loadu(a: mesh->vertexPtr(i: vtxID10)); |
69 | const vfloat4 vtx11 = vfloat4::loadu(a: mesh->vertexPtr(i: 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(a: mesh->vertexPtr(i: vtxID02)); |
75 | const size_t vtxID12 = vtxID11 + deltaX; |
76 | const vfloat4 vtx12 = vfloat4::loadu(a: mesh->vertexPtr(i: 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(a: mesh->vertexPtr(i: vtxID20)); |
83 | const vfloat4 vtx21 = vfloat4::loadu(a: mesh->vertexPtr(i: vtxID21)); |
84 | |
85 | /* deltaX/deltaY => vtx22 */ |
86 | const size_t vtxID22 = vtxID11 + deltaX + deltaY; |
87 | const vfloat4 vtx22 = vfloat4::loadu(a: mesh->vertexPtr(i: vtxID22)); |
88 | |
89 | transpose(r0: vtx00,r1: vtx01,r2: vtx11,r3: vtx10,c0&: p0.x,c1&: p0.y,c2&: p0.z); |
90 | transpose(r0: vtx01,r1: vtx02,r2: vtx12,r3: vtx11,c0&: p1.x,c1&: p1.y,c2&: p1.z); |
91 | transpose(r0: vtx11,r1: vtx12,r2: vtx22,r3: vtx21,c0&: p2.x,c1&: p2.y,c2&: p2.z); |
92 | transpose(r0: vtx10,r1: vtx11,r2: vtx21,r3: vtx20,c0&: p3.x,c1&: p3.y,c2&: p3.z); |
93 | } |
94 | |
95 | template<typename T> |
96 | __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(i: offset,itime: itime+0)); |
99 | const T v1 = T::loadu(mesh->vertexPtr(i: offset,itime: itime+1)); |
100 | return lerp(v0,v1,ftime); |
101 | } |
102 | |
103 | /* Gather the quads */ |
104 | __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,offset: vtxID00,itime,ftime); |
117 | const vfloat4 vtx01 = getVertexMB<vfloat4>(mesh,offset: 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,offset: vtxID10,itime,ftime); |
121 | const vfloat4 vtx11 = getVertexMB<vfloat4>(mesh,offset: 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,offset: vtxID02,itime,ftime); |
127 | const size_t vtxID12 = vtxID11 + deltaX; |
128 | const vfloat4 vtx12 = getVertexMB<vfloat4>(mesh,offset: 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,offset: vtxID20,itime,ftime); |
135 | const vfloat4 vtx21 = getVertexMB<vfloat4>(mesh,offset: vtxID21,itime,ftime); |
136 | |
137 | /* deltaX/deltaY => vtx22 */ |
138 | const size_t vtxID22 = vtxID11 + deltaX + deltaY; |
139 | const vfloat4 vtx22 = getVertexMB<vfloat4>(mesh,offset: vtxID22,itime,ftime); |
140 | |
141 | transpose(r0: vtx00,r1: vtx01,r2: vtx11,r3: vtx10,c0&: p0.x,c1&: p0.y,c2&: p0.z); |
142 | transpose(r0: vtx01,r1: vtx02,r2: vtx12,r3: vtx11,c0&: p1.x,c1&: p1.y,c2&: p1.z); |
143 | transpose(r0: vtx11,r1: vtx12,r2: vtx22,r3: vtx21,c0&: p2.x,c1&: p2.y,c2&: p2.z); |
144 | transpose(r0: vtx10,r1: vtx11,r2: vtx21,r3: vtx20,c0&: p3.x,c1&: p3.y,c2&: p3.z); |
145 | } |
146 | |
147 | |
148 | |
149 | /* Gather the quads */ |
150 | __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>(i: geomID()); |
157 | const GridMesh::Grid &g = mesh->grid(i: primID()); |
158 | gather(p0,p1,p2,p3,mesh,g); |
159 | } |
160 | |
161 | /* Gather the quads in the motion blur case */ |
162 | __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>(i: geomID()); |
171 | const GridMesh::Grid &g = mesh->grid(i: primID()); |
172 | gatherMB(p0,p1,p2,p3,mesh,g,itime,ftime); |
173 | } |
174 | |
175 | /* Gather the quads */ |
176 | __forceinline void gather(Vec3fa vtx[16], const Scene *const scene) const |
177 | { |
178 | const GridMesh* mesh = scene->get<GridMesh>(i: geomID()); |
179 | const GridMesh::Grid &g = mesh->grid(i: 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(a: mesh->vertexPtr(i: vtxID00)); |
185 | const Vec3fa vtx01 = Vec3fa::loadu(a: mesh->vertexPtr(i: vtxID01)); |
186 | const size_t vtxID10 = vtxID00 + g.lineVtxOffset; |
187 | const size_t vtxID11 = vtxID01 + g.lineVtxOffset; |
188 | const Vec3fa vtx10 = Vec3fa::loadu(a: mesh->vertexPtr(i: vtxID10)); |
189 | const Vec3fa vtx11 = Vec3fa::loadu(a: mesh->vertexPtr(i: 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(a: mesh->vertexPtr(i: vtxID02)); |
195 | const size_t vtxID12 = vtxID11 + deltaX; |
196 | const Vec3fa vtx12 = Vec3fa::loadu(a: mesh->vertexPtr(i: 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(a: mesh->vertexPtr(i: vtxID20)); |
203 | const Vec3fa vtx21 = Vec3fa::loadu(a: mesh->vertexPtr(i: vtxID21)); |
204 | |
205 | /* deltaX/deltaY => vtx22 */ |
206 | const size_t vtxID22 = vtxID11 + deltaX + deltaY; |
207 | const Vec3fa vtx22 = Vec3fa::loadu(a: mesh->vertexPtr(i: 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 */ |
216 | __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>(i: geomID()); |
219 | const GridMesh::Grid &g = mesh->grid(i: 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,offset: vtxID00,itime,ftime); |
225 | const vfloat4 vtx01 = getVertexMB<vfloat4>(mesh,offset: 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,offset: vtxID10,itime,ftime); |
229 | const vfloat4 vtx11 = getVertexMB<vfloat4>(mesh,offset: 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,offset: vtxID02,itime,ftime); |
235 | const size_t vtxID12 = vtxID11 + deltaX; |
236 | const vfloat4 vtx12 = getVertexMB<vfloat4>(mesh,offset: 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,offset: vtxID20,itime,ftime); |
243 | const vfloat4 vtx21 = getVertexMB<vfloat4>(mesh,offset: vtxID21,itime,ftime); |
244 | |
245 | /* deltaX/deltaY => vtx22 */ |
246 | const size_t vtxID22 = vtxID11 + deltaX + deltaY; |
247 | const vfloat4 vtx22 = getVertexMB<vfloat4>(mesh,offset: 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 */ |
265 | __forceinline LBBox3fa linearBounds(const Scene* const scene, const size_t itime) |
266 | { |
267 | return LBBox3fa(bounds(scene,itime: itime+0),bounds(scene,itime: itime+1)); |
268 | } |
269 | |
270 | __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 | |
277 | __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 | |
289 | __forceinline unsigned int geomID() const { return _geomID; } |
290 | __forceinline unsigned int primID() const { return _primID; } |
291 | __forceinline unsigned int x() const { return (unsigned int)_x & 0x7fff; } |
292 | __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 | |
306 | __forceinline SubGridID() {} |
307 | __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 | |
327 | __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 | |
334 | __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 */ |
341 | __forceinline SubGridQBVHN() { } |
342 | |
343 | /* Construction from vertices and IDs */ |
344 | __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 | |
364 | __forceinline unsigned int geomID() const { return _geomID; } |
365 | __forceinline unsigned int primID(const size_t i) const { assert(i < N); return subgridIDs[i].primID; } |
366 | __forceinline unsigned int x(const size_t i) const { assert(i < N); return subgridIDs[i].x; } |
367 | __forceinline unsigned int y(const size_t i) const { assert(i < N); return subgridIDs[i].y; } |
368 | |
369 | __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 | |
422 | __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 | |
429 | __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 */ |
436 | __forceinline SubGridMBQBVHN() { } |
437 | |
438 | /* Construction from vertices and IDs */ |
439 | __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 | |
467 | __forceinline unsigned int geomID() const { return _geomID; } |
468 | __forceinline unsigned int primID(const size_t i) const { assert(i < N); return subgridIDs[i].primID; } |
469 | __forceinline unsigned int x(const size_t i) const { assert(i < N); return subgridIDs[i].x; } |
470 | __forceinline unsigned int y(const size_t i) const { assert(i < N); return subgridIDs[i].y; } |
471 | |
472 | __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 | |
478 | __forceinline float adjustTime(const float t) const { return time_scale * (t-time_offset); } |
479 | |
480 | template<int K> |
481 | __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 | |