1// Copyright 2021 Intel Corporation
2// SPDX-License-Identifier: Apache-2.0
3
4#pragma once
5
6#include "VdbGrid.h"
7#include "common/temporal_data_interpolation.ih"
8
9// ---------------------------------------------------------------------------
10// Helpers.
11// ---------------------------------------------------------------------------
12
13// allows correct handling of partially filled leaves (i.e. when denseDimensions
14// is not an even multiple of VKL_VDB_RES_LEAF)
15inline uniform bool VdbSampler_isInDenseDomain(const VdbGrid *uniform grid,
16                                               const uniform vec3ui &offset)
17{
18  return offset.x < grid->denseDimensions.x &&
19         offset.y < grid->denseDimensions.y &&
20         offset.z < grid->denseDimensions.z;
21}
22
23inline bool VdbSampler_isInDenseDomain(const VdbGrid *uniform grid,
24                                       const vec3ui &offset)
25{
26  return offset.x < grid->denseDimensions.x &&
27         offset.y < grid->denseDimensions.y &&
28         offset.z < grid->denseDimensions.z;
29}
30
31// ---------------------------------------------------------------------------
32// Value range.
33// ---------------------------------------------------------------------------
34
35#define __vkl_template_VdbSampler_computeValueRange_dense_constant(voxelType) \
36  inline uniform box1f                                                        \
37      VdbSampler_computeValueRange_dense_32_constant_##voxelType(             \
38          const VdbGrid *uniform grid,                                        \
39          uniform uint32 attributeIndex,                                      \
40          const uniform vec3ui &domainOffset,                                 \
41          const uniform vec2ui &xRange,                                       \
42          const uniform vec2ui &yRange,                                       \
43          const uniform vec2ui &zRange)                                       \
44  {                                                                           \
45    uniform box1f valueRange = make_box1f(pos_inf, neg_inf);                  \
46    for (uniform unsigned int x = xRange.x; x < xRange.y; ++x) {              \
47      for (uniform unsigned int y = yRange.x; y < yRange.y; ++y) {            \
48        for (uniform unsigned int z = zRange.x; z < zRange.y; ++z) {          \
49          if (!VdbSampler_isInDenseDomain(                                    \
50                  grid, domainOffset + make_vec3ui(x, y, z))) {               \
51            continue;                                                         \
52          }                                                                   \
53          const uniform uint64 voxelIdx =                                     \
54              (domainOffset.z + z) * grid->activeSize.y *                     \
55                  (uint64)grid->activeSize.x +                                \
56              (domainOffset.y + y) * (uint64)grid->activeSize.x +             \
57              (uint64)(domainOffset.x + x);                                   \
58          assert(voxelIdx < ((uniform uint64)1) << 32);                       \
59          const uniform uint32 v32 = ((uniform uint32)voxelIdx);              \
60          extend(valueRange,                                                  \
61                 get_##voxelType(grid->denseData[attributeIndex], v32));      \
62        }                                                                     \
63      }                                                                       \
64    }                                                                         \
65    return valueRange;                                                        \
66  }                                                                           \
67                                                                              \
68  inline uniform box1f                                                        \
69      VdbSampler_computeValueRange_dense_64_constant_##voxelType(             \
70          const VdbGrid *uniform grid,                                        \
71          uniform uint32 attributeIndex,                                      \
72          const uniform vec3ui &domainOffset,                                 \
73          const uniform vec2ui &xRange,                                       \
74          const uniform vec2ui &yRange,                                       \
75          const uniform vec2ui &zRange)                                       \
76  {                                                                           \
77    uniform box1f valueRange = make_box1f(pos_inf, neg_inf);                  \
78    for (uniform unsigned int x = xRange.x; x < xRange.y; ++x) {              \
79      for (uniform unsigned int y = yRange.x; y < yRange.y; ++y) {            \
80        for (uniform unsigned int z = zRange.x; z < zRange.y; ++z) {          \
81          if (!VdbSampler_isInDenseDomain(                                    \
82                  grid, domainOffset + make_vec3ui(x, y, z))) {               \
83            continue;                                                         \
84          }                                                                   \
85          const uniform uint64 voxelIdx =                                     \
86              (domainOffset.z + z) * grid->activeSize.y *                     \
87                  (uint64)grid->activeSize.x +                                \
88              (domainOffset.y + y) * (uint64)grid->activeSize.x +             \
89              (uint64)(domainOffset.x + x);                                   \
90          extend(valueRange,                                                  \
91                 get_##voxelType(grid->denseData[attributeIndex], voxelIdx)); \
92        }                                                                     \
93      }                                                                       \
94    }                                                                         \
95    return valueRange;                                                        \
96  }
97
98__vkl_template_VdbSampler_computeValueRange_dense_constant(uint8);
99__vkl_template_VdbSampler_computeValueRange_dense_constant(int16);
100__vkl_template_VdbSampler_computeValueRange_dense_constant(uint16);
101__vkl_template_VdbSampler_computeValueRange_dense_constant(half);
102__vkl_template_VdbSampler_computeValueRange_dense_constant(float);
103__vkl_template_VdbSampler_computeValueRange_dense_constant(double);
104
105#undef __vkl_template_VdbSampler_computeValueRange_dense_constant
106
107#define __vkl_template_VdbSampler_computeValueRange_dense_structured(      \
108    voxelType)                                                             \
109  inline uniform box1f                                                     \
110      VdbSampler_computeValueRange_dense_32_structured_##voxelType(        \
111          const VdbGrid *uniform grid,                                     \
112          uniform uint32 attributeIndex,                                   \
113          const uniform vec3ui &domainOffset,                              \
114          const uniform vec2ui &xRange,                                    \
115          const uniform vec2ui &yRange,                                    \
116          const uniform vec2ui &zRange)                                    \
117  {                                                                        \
118    const uniform uint32 numTimesteps =                                    \
119        grid->denseTemporallyStructuredNumTimesteps;                       \
120    uniform box1f valueRange = make_box1f(pos_inf, neg_inf);               \
121                                                                           \
122    for (uniform unsigned int x = xRange.x; x < xRange.y; ++x) {           \
123      for (uniform unsigned int y = yRange.x; y < yRange.y; ++y) {         \
124        for (uniform unsigned int z = zRange.x; z < zRange.y; ++z) {       \
125          if (!VdbSampler_isInDenseDomain(                                 \
126                  grid, domainOffset + make_vec3ui(x, y, z))) {            \
127            continue;                                                      \
128          }                                                                \
129          const uniform uint64 voxelIdx =                                  \
130              numTimesteps *                                               \
131              ((domainOffset.z + z) * grid->activeSize.y *                 \
132                   (uint64)grid->activeSize.x +                            \
133               (domainOffset.y + y) * (uint64)grid->activeSize.x +         \
134               (uint64)(domainOffset.x + x));                              \
135          for (uniform unsigned int t = 0; t < numTimesteps; ++t) {        \
136            assert((voxelIdx + t) < ((uniform uint64)1) << 32);            \
137            const uniform uint32 v32 = ((uniform uint32)(voxelIdx + t));   \
138            extend(valueRange,                                             \
139                   get_##voxelType(grid->denseData[attributeIndex], v32)); \
140          }                                                                \
141        }                                                                  \
142      }                                                                    \
143    }                                                                      \
144    return valueRange;                                                     \
145  }                                                                        \
146                                                                           \
147  inline uniform box1f                                                     \
148      VdbSampler_computeValueRange_dense_64_structured_##voxelType(        \
149          const VdbGrid *uniform grid,                                     \
150          uniform uint32 attributeIndex,                                   \
151          const uniform vec3ui &domainOffset,                              \
152          const uniform vec2ui &xRange,                                    \
153          const uniform vec2ui &yRange,                                    \
154          const uniform vec2ui &zRange)                                    \
155  {                                                                        \
156    const uniform uint32 numTimesteps =                                    \
157        grid->denseTemporallyStructuredNumTimesteps;                       \
158    uniform box1f valueRange = make_box1f(pos_inf, neg_inf);               \
159                                                                           \
160    for (uniform unsigned int x = xRange.x; x < xRange.y; ++x) {           \
161      for (uniform unsigned int y = yRange.x; y < yRange.y; ++y) {         \
162        for (uniform unsigned int z = zRange.x; z < zRange.y; ++z) {       \
163          if (!VdbSampler_isInDenseDomain(                                 \
164                  grid, domainOffset + make_vec3ui(x, y, z))) {            \
165            continue;                                                      \
166          }                                                                \
167          const uniform uint64 voxelIdx =                                  \
168              numTimesteps *                                               \
169              ((domainOffset.z + z) * grid->activeSize.y *                 \
170                   (uint64)grid->activeSize.x +                            \
171               (domainOffset.y + y) * (uint64)grid->activeSize.x +         \
172               (uint64)(domainOffset.x + x));                              \
173          for (uniform unsigned int t = 0; t < numTimesteps; ++t) {        \
174            const uniform uint64 v64 = ((uniform uint64)(voxelIdx + t));   \
175            extend(valueRange,                                             \
176                   get_##voxelType(grid->denseData[attributeIndex], v64)); \
177          }                                                                \
178        }                                                                  \
179      }                                                                    \
180    }                                                                      \
181    return valueRange;                                                     \
182  }
183
184__vkl_template_VdbSampler_computeValueRange_dense_structured(uint8);
185__vkl_template_VdbSampler_computeValueRange_dense_structured(uint16);
186__vkl_template_VdbSampler_computeValueRange_dense_structured(int16);
187__vkl_template_VdbSampler_computeValueRange_dense_structured(half);
188__vkl_template_VdbSampler_computeValueRange_dense_structured(float);
189__vkl_template_VdbSampler_computeValueRange_dense_structured(double);
190
191#undef __vkl_template_VdbSampler_computeValueRange_dense_structured
192
193#define __vkl_template_VdbSampler_computeValueRange_dense_unstructured(       \
194    voxelType)                                                                \
195  inline uniform box1f                                                        \
196      VdbSampler_computeValueRange_dense_32_unstructured_##voxelType(         \
197          const VdbGrid *uniform grid,                                        \
198          uniform uint32 attributeIndex,                                      \
199          const uniform vec3ui &domainOffset,                                 \
200          const uniform vec2ui &xRange,                                       \
201          const uniform vec2ui &yRange,                                       \
202          const uniform vec2ui &zRange)                                       \
203  {                                                                           \
204    uniform box1f valueRange = make_box1f(pos_inf, neg_inf);                  \
205                                                                              \
206    for (uniform unsigned int x = xRange.x; x < xRange.y; ++x) {              \
207      for (uniform unsigned int y = yRange.x; y < yRange.y; ++y) {            \
208        for (uniform unsigned int z = zRange.x; z < zRange.y; ++z) {          \
209          if (!VdbSampler_isInDenseDomain(                                    \
210                  grid, domainOffset + make_vec3ui(x, y, z))) {               \
211            continue;                                                         \
212          }                                                                   \
213          const uniform uint64 voxelIdx =                                     \
214              (domainOffset.z + z) * grid->activeSize.y *                     \
215                  (uint64)grid->activeSize.x +                                \
216              (domainOffset.y + y) * (uint64)grid->activeSize.x +             \
217              (uint64)(domainOffset.x + x);                                   \
218          assert(voxelIdx < ((uniform uint64)1) << 32);                       \
219          const uniform uint32 v32 = ((uniform uint32)voxelIdx);              \
220          valueRange =                                                        \
221              box_extend(valueRange,                                          \
222                         computeValueRangeTemporallyUnstructured_##voxelType( \
223                             &grid->denseData[attributeIndex],                \
224                             &grid->denseTemporallyUnstructuredIndices,       \
225                             v32));                                           \
226        }                                                                     \
227      }                                                                       \
228    }                                                                         \
229                                                                              \
230    return valueRange;                                                        \
231  }                                                                           \
232                                                                              \
233  inline uniform box1f                                                        \
234      VdbSampler_computeValueRange_dense_64_unstructured_##voxelType(         \
235          const VdbGrid *uniform grid,                                        \
236          uniform uint32 attributeIndex,                                      \
237          const uniform vec3ui &domainOffset,                                 \
238          const uniform vec2ui &xRange,                                       \
239          const uniform vec2ui &yRange,                                       \
240          const uniform vec2ui &zRange)                                       \
241  {                                                                           \
242    uniform box1f valueRange = make_box1f(pos_inf, neg_inf);                  \
243                                                                              \
244    for (uniform unsigned int x = xRange.x; x < xRange.y; ++x) {              \
245      for (uniform unsigned int y = yRange.x; y < yRange.y; ++y) {            \
246        for (uniform unsigned int z = zRange.x; z < zRange.y; ++z) {          \
247          if (!VdbSampler_isInDenseDomain(                                    \
248                  grid, domainOffset + make_vec3ui(x, y, z))) {               \
249            continue;                                                         \
250          }                                                                   \
251          const uniform uint64 voxelIdx =                                     \
252              (domainOffset.z + z) * grid->activeSize.y *                     \
253                  (uint64)grid->activeSize.x +                                \
254              (domainOffset.y + y) * (uint64)grid->activeSize.x +             \
255              (uint64)(domainOffset.x + x);                                   \
256          valueRange =                                                        \
257              box_extend(valueRange,                                          \
258                         computeValueRangeTemporallyUnstructured_##voxelType( \
259                             &grid->denseData[attributeIndex],                \
260                             &grid->denseTemporallyUnstructuredIndices,       \
261                             voxelIdx));                                      \
262        }                                                                     \
263      }                                                                       \
264    }                                                                         \
265                                                                              \
266    return valueRange;                                                        \
267  }
268
269__vkl_template_VdbSampler_computeValueRange_dense_unstructured(uint8);
270__vkl_template_VdbSampler_computeValueRange_dense_unstructured(uint16);
271__vkl_template_VdbSampler_computeValueRange_dense_unstructured(int16);
272__vkl_template_VdbSampler_computeValueRange_dense_unstructured(half);
273__vkl_template_VdbSampler_computeValueRange_dense_unstructured(float);
274__vkl_template_VdbSampler_computeValueRange_dense_unstructured(double);
275
276#undef __vkl_template_VdbSampler_computeValueRange_dense_unstructured
277
278// ---------------------------------------------------------------------------
279// Constant leaf sampling.
280// ---------------------------------------------------------------------------
281
282#define __vkl_template_VdbSampler_sample_dense_constant(voxelType)        \
283  inline uniform float                                                    \
284      VdbSampler_sample_dense_uniform_32_constant_##voxelType(            \
285          const VdbGrid *uniform grid,                                    \
286          uniform uint32 attributeIndex,                                  \
287          const uniform vec3ui &offset,                                   \
288          uniform float /*time*/)                                         \
289  {                                                                       \
290    assert(VdbSampler_isInDenseDomain(grid, offset));                     \
291    assert(offset.z * grid->activeSize.y * (uint64)grid->activeSize.x +   \
292               offset.y * (uint64)grid->activeSize.x + (uint64)offset.x < \
293           ((uniform uint64)1) << 32);                                    \
294    const uniform uint32 voxelIdx =                                       \
295        offset.z * grid->activeSize.y * grid->activeSize.x +              \
296        offset.y * grid->activeSize.x + offset.x;                         \
297                                                                          \
298    return get_##voxelType(grid->denseData[attributeIndex], voxelIdx);    \
299  }                                                                       \
300                                                                          \
301  inline float VdbSampler_sample_dense_varying_32_constant_##voxelType(   \
302      const VdbGrid *uniform grid,                                        \
303      uniform uint32 attributeIndex,                                      \
304      const vec3ui &offset,                                               \
305      const float & /*time*/)                                             \
306  {                                                                       \
307    assert(VdbSampler_isInDenseDomain(grid, offset));                     \
308    assert(offset.z * grid->activeSize.y * (uint64)grid->activeSize.x +   \
309               offset.y * (uint64)grid->activeSize.x + (uint64)offset.x < \
310           ((uint64)1) << 32);                                            \
311    const uint32 voxelIdx =                                               \
312        offset.z * grid->activeSize.y * grid->activeSize.x +              \
313        offset.y * grid->activeSize.x + offset.x;                         \
314                                                                          \
315    return get_##voxelType(grid->denseData[attributeIndex], voxelIdx);    \
316  }                                                                       \
317                                                                          \
318  inline uniform float                                                    \
319      VdbSampler_sample_dense_uniform_64_constant_##voxelType(            \
320          const VdbGrid *uniform grid,                                    \
321          uniform uint32 attributeIndex,                                  \
322          const uniform vec3ui &offset,                                   \
323          uniform float /*time*/)                                         \
324  {                                                                       \
325    assert(VdbSampler_isInDenseDomain(grid, offset));                     \
326    const uniform uint64 voxelIdx =                                       \
327        offset.z * grid->activeSize.y * (uint64)grid->activeSize.x +      \
328        offset.y * (uint64)grid->activeSize.x + (uint64)offset.x;         \
329                                                                          \
330    return get_##voxelType(grid->denseData[attributeIndex], voxelIdx);    \
331  }                                                                       \
332                                                                          \
333  inline float VdbSampler_sample_dense_varying_64_constant_##voxelType(   \
334      const VdbGrid *uniform grid,                                        \
335      uniform uint32 attributeIndex,                                      \
336      const vec3ui &offset,                                               \
337      const float & /*time*/)                                             \
338  {                                                                       \
339    assert(VdbSampler_isInDenseDomain(grid, offset));                     \
340    const uint64 voxelIdx =                                               \
341        offset.z * grid->activeSize.y * (uint64)grid->activeSize.x +      \
342        offset.y * (uint64)grid->activeSize.x + (uint64)offset.x;         \
343                                                                          \
344    return get_##voxelType(grid->denseData[attributeIndex], voxelIdx);    \
345  }
346
347__vkl_template_VdbSampler_sample_dense_constant(uint8);
348__vkl_template_VdbSampler_sample_dense_constant(int16);
349__vkl_template_VdbSampler_sample_dense_constant(uint16);
350__vkl_template_VdbSampler_sample_dense_constant(half);
351__vkl_template_VdbSampler_sample_dense_constant(float);
352__vkl_template_VdbSampler_sample_dense_constant(double);
353
354#undef __vkl_template_VdbSampler_sample_dense_constant
355
356// ---------------------------------------------------------------------------
357// Structured leaf sampling.
358// ---------------------------------------------------------------------------
359
360#define __vkl_template_VdbSampler_sample_dense_structured(voxelType)         \
361  inline uniform float                                                       \
362      VdbSampler_sample_dense_uniform_32_structured_##voxelType(             \
363          const VdbGrid *uniform grid,                                       \
364          uniform uint32 attributeIndex,                                     \
365          const uniform vec3ui &offset,                                      \
366          uniform float time)                                                \
367  {                                                                          \
368    assert(VdbSampler_isInDenseDomain(grid, offset));                        \
369    const uniform int32 numTimesteps =                                       \
370        grid->denseTemporallyStructuredNumTimesteps;                         \
371    assert(numTimesteps *(                                                   \
372               offset.z * grid->activeSize.y * (uint64)grid->activeSize.x +  \
373               offset.y * (uint64)grid->activeSize.x + (uint64)offset.x) <   \
374           ((uniform uint64)1) << 32);                                       \
375    const uniform uint32 v32 =                                               \
376        numTimesteps * (offset.z * grid->activeSize.y * grid->activeSize.x + \
377                        offset.y * grid->activeSize.x + offset.x);           \
378                                                                             \
379    return interpolateTemporallyStructured_##voxelType(                      \
380        &grid->denseData[attributeIndex], numTimesteps, v32, time);          \
381  }                                                                          \
382                                                                             \
383  inline float VdbSampler_sample_dense_varying_32_structured_##voxelType(    \
384      const VdbGrid *uniform grid,                                           \
385      uniform uint32 attributeIndex,                                         \
386      const vec3ui &offset,                                                  \
387      const float &time)                                                     \
388  {                                                                          \
389    assert(VdbSampler_isInDenseDomain(grid, offset));                        \
390    const uniform int32 numTimesteps =                                       \
391        grid->denseTemporallyStructuredNumTimesteps;                         \
392    assert(numTimesteps *(                                                   \
393               offset.z * grid->activeSize.y * (uint64)grid->activeSize.x +  \
394               offset.y * (uint64)grid->activeSize.x + (uint64)offset.x) <   \
395           ((uint64)1) << 32);                                               \
396    const uint32 v32 =                                                       \
397        numTimesteps * (offset.z * grid->activeSize.y * grid->activeSize.x + \
398                        offset.y * grid->activeSize.x + offset.x);           \
399                                                                             \
400    return interpolateTemporallyStructured_##voxelType(                      \
401        &grid->denseData[attributeIndex], numTimesteps, v32, time);          \
402  }                                                                          \
403                                                                             \
404  inline uniform float                                                       \
405      VdbSampler_sample_dense_uniform_64_structured_##voxelType(             \
406          const VdbGrid *uniform grid,                                       \
407          uniform uint32 attributeIndex,                                     \
408          const uniform vec3ui &offset,                                      \
409          uniform float time)                                                \
410  {                                                                          \
411    assert(VdbSampler_isInDenseDomain(grid, offset));                        \
412    const uniform int32 numTimesteps =                                       \
413        grid->denseTemporallyStructuredNumTimesteps;                         \
414    const uniform uint64 voxelIdx =                                          \
415        numTimesteps *                                                       \
416        (offset.z * grid->activeSize.y * (uint64)grid->activeSize.x +        \
417         offset.y * (uint64)grid->activeSize.x + (uint64)offset.x);          \
418                                                                             \
419    return interpolateTemporallyStructured_##voxelType(                      \
420        &grid->denseData[attributeIndex], numTimesteps, voxelIdx, time);     \
421  }                                                                          \
422                                                                             \
423  inline float VdbSampler_sample_dense_varying_64_structured_##voxelType(    \
424      const VdbGrid *uniform grid,                                           \
425      uniform uint32 attributeIndex,                                         \
426      const vec3ui &offset,                                                  \
427      const float &time)                                                     \
428  {                                                                          \
429    assert(VdbSampler_isInDenseDomain(grid, offset));                        \
430    const uniform int32 numTimesteps =                                       \
431        grid->denseTemporallyStructuredNumTimesteps;                         \
432    const uint64 voxelIdx =                                                  \
433        numTimesteps *                                                       \
434        (offset.z * grid->activeSize.y * (uint64)grid->activeSize.x +        \
435         offset.y * (uint64)grid->activeSize.x + (uint64)offset.x);          \
436                                                                             \
437    return interpolateTemporallyStructured_##voxelType(                      \
438        &grid->denseData[attributeIndex], numTimesteps, voxelIdx, time);     \
439  }
440
441__vkl_template_VdbSampler_sample_dense_structured(uint8);
442__vkl_template_VdbSampler_sample_dense_structured(int16);
443__vkl_template_VdbSampler_sample_dense_structured(uint16);
444__vkl_template_VdbSampler_sample_dense_structured(half);
445__vkl_template_VdbSampler_sample_dense_structured(float);
446__vkl_template_VdbSampler_sample_dense_structured(double);
447
448#undef __vkl_template_VdbSampler_sample_dense_structured
449
450// ---------------------------------------------------------------------------
451// Unstructured leaf sampling.
452// ---------------------------------------------------------------------------
453
454#define __vkl_template_VdbSampler_sample_dense_unstructured(voxelType)      \
455  inline uniform float                                                      \
456      VdbSampler_sample_dense_uniform_32_unstructured_##voxelType(          \
457          const VdbGrid *uniform grid,                                      \
458          uniform uint32 attributeIndex,                                    \
459          const uniform vec3ui &offset,                                     \
460          uniform float time)                                               \
461  {                                                                         \
462    assert(VdbSampler_isInDenseDomain(grid, offset));                       \
463    const uniform uint64 voxelIdx64 =                                       \
464        offset.z * grid->activeSize.y * (uint64)grid->activeSize.x +        \
465        offset.y * (uint64)grid->activeSize.x + (uint64)offset.x;           \
466    assert(voxelIdx64 < ((uniform uint64)1) << 32);                         \
467    const uniform uint32 voxelIdx = ((uniform uint32)voxelIdx64);           \
468                                                                            \
469    return interpolateTemporallyUnstructured_##voxelType(                   \
470        &grid->denseData[attributeIndex],                                   \
471        &grid->denseTemporallyUnstructuredIndices,                          \
472        &grid->denseTemporallyUnstructuredTimes,                            \
473        voxelIdx,                                                           \
474        time);                                                              \
475  }                                                                         \
476                                                                            \
477  inline float VdbSampler_sample_dense_varying_32_unstructured_##voxelType( \
478      const VdbGrid *uniform grid,                                          \
479      uniform uint32 attributeIndex,                                        \
480      const vec3ui &offset,                                                 \
481      const float &time)                                                    \
482  {                                                                         \
483    assert(VdbSampler_isInDenseDomain(grid, offset));                       \
484    const uint64 voxelIdx64 =                                               \
485        offset.z * grid->activeSize.y * (uint64)grid->activeSize.x +        \
486        offset.y * (uint64)grid->activeSize.x + (uint64)offset.x;           \
487    assert(voxelIdx64 < ((uint64)1) << 32);                                 \
488    const varying uint32 voxelIdx = ((uint32)voxelIdx64);                   \
489                                                                            \
490    return interpolateTemporallyUnstructured_##voxelType(                   \
491        &grid->denseData[attributeIndex],                                   \
492        &grid->denseTemporallyUnstructuredIndices,                          \
493        &grid->denseTemporallyUnstructuredTimes,                            \
494        voxelIdx,                                                           \
495        time);                                                              \
496  }                                                                         \
497                                                                            \
498  inline uniform float                                                      \
499      VdbSampler_sample_dense_uniform_64_unstructured_##voxelType(          \
500          const VdbGrid *uniform grid,                                      \
501          uniform uint32 attributeIndex,                                    \
502          const uniform vec3ui &offset,                                     \
503          uniform float time)                                               \
504  {                                                                         \
505    assert(VdbSampler_isInDenseDomain(grid, offset));                       \
506    const uniform uint64 voxelIdx64 =                                       \
507        offset.z * grid->activeSize.y * (uint64)grid->activeSize.x +        \
508        offset.y * (uint64)grid->activeSize.x + (uint64)offset.x;           \
509                                                                            \
510    return interpolateTemporallyUnstructured_##voxelType(                   \
511        &grid->denseData[attributeIndex],                                   \
512        &grid->denseTemporallyUnstructuredIndices,                          \
513        &grid->denseTemporallyUnstructuredTimes,                            \
514        voxelIdx64,                                                         \
515        time);                                                              \
516  }                                                                         \
517                                                                            \
518  inline float VdbSampler_sample_dense_varying_64_unstructured_##voxelType( \
519      const VdbGrid *uniform grid,                                          \
520      uniform uint32 attributeIndex,                                        \
521      const vec3ui &offset,                                                 \
522      const float &time)                                                    \
523  {                                                                         \
524    assert(VdbSampler_isInDenseDomain(grid, offset));                       \
525    const uint64 voxelIdx64 =                                               \
526        offset.z * grid->activeSize.y * (uint64)grid->activeSize.x +        \
527        offset.y * (uint64)grid->activeSize.x + (uint64)offset.x;           \
528                                                                            \
529    return interpolateTemporallyUnstructured_##voxelType(                   \
530        &grid->denseData[attributeIndex],                                   \
531        &grid->denseTemporallyUnstructuredIndices,                          \
532        &grid->denseTemporallyUnstructuredTimes,                            \
533        voxelIdx64,                                                         \
534        time);                                                              \
535  }
536
537__vkl_template_VdbSampler_sample_dense_unstructured(uint8);
538__vkl_template_VdbSampler_sample_dense_unstructured(int16);
539__vkl_template_VdbSampler_sample_dense_unstructured(uint16);
540__vkl_template_VdbSampler_sample_dense_unstructured(half);
541__vkl_template_VdbSampler_sample_dense_unstructured(float);
542__vkl_template_VdbSampler_sample_dense_unstructured(double);
543
544#undef __vkl_template_VdbSampler_sample_dense_unstructured
545