1 // Copyright 2019-2021 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 
4 #pragma once
5 
6 #include "ProceduralStructuredVolume.h"
7 #include "procedural_functions.h"
8 
9 using namespace rkcommon;
10 
11 namespace openvkl {
12   namespace testing {
13 
14     template <typename VOXEL_TYPE =
15                   VoidType /* should be void (we have static_assert to
16                           prevent such instantiation), but isn't due
17                           to Windows Visual Studio compiler bug */
18               ,
19               VOXEL_TYPE samplingFunction(const vec3f &, float) =
20                   samplingNotImplemented,
21               vec3f gradientFunction(const vec3f &, float) =
22                   gradientNotImplemented>
23     struct ProceduralStructuredRegularVolume
24         : public ProceduralStructuredVolume<VOXEL_TYPE,
25                                             samplingFunction,
26                                             gradientFunction>
27     {
28       ProceduralStructuredRegularVolume(
29           const vec3i &dimensions,
30           const vec3f &gridOrigin,
31           const vec3f &gridSpacing,
32           const TemporalConfig &temporalConfig   = TemporalConfig(),
33           VKLDataCreationFlags dataCreationFlags = VKL_DATA_DEFAULT,
34           size_t byteStride                      = 0);
35 
36       vec3f transformLocalToObjectCoordinates(
37           const vec3f &localCoordinates) const override;
38 
39       static void generateGridParameters(const vec3i &dimensions,
40                                          const float boundingBoxSize,
41                                          vec3f &gridOrigin,
42                                          vec3f &gridSpacing);
43     };
44 
45     // Inlined definitions ////////////////////////////////////////////////////
46 
47     template <typename VOXEL_TYPE,
48               VOXEL_TYPE samplingFunction(const vec3f &, float),
49               vec3f gradientFunction(const vec3f &, float)>
50     inline ProceduralStructuredRegularVolume<VOXEL_TYPE,
51                                              samplingFunction,
52                                              gradientFunction>::
ProceduralStructuredRegularVolume(const vec3i & dimensions,const vec3f & gridOrigin,const vec3f & gridSpacing,const TemporalConfig & temporalConfig,VKLDataCreationFlags dataCreationFlags,size_t byteStride)53         ProceduralStructuredRegularVolume(
54             const vec3i &dimensions,
55             const vec3f &gridOrigin,
56             const vec3f &gridSpacing,
57             const TemporalConfig &temporalConfig,
58             VKLDataCreationFlags dataCreationFlags,
59             size_t byteStride)
60         : ProceduralStructuredVolume<VOXEL_TYPE,
61                                      samplingFunction,
62                                      gradientFunction>("structuredRegular",
63                                                        dimensions,
64                                                        gridOrigin,
65                                                        gridSpacing,
66                                                        temporalConfig,
67                                                        dataCreationFlags,
68                                                        byteStride)
69     {
70     }
71 
72     template <typename VOXEL_TYPE,
73               VOXEL_TYPE samplingFunction(const vec3f &, float),
74               vec3f gradientFunction(const vec3f &, float)>
75     inline vec3f ProceduralStructuredRegularVolume<VOXEL_TYPE,
76                                                    samplingFunction,
77                                                    gradientFunction>::
transformLocalToObjectCoordinates(const vec3f & localCoordinates)78         transformLocalToObjectCoordinates(const vec3f &localCoordinates) const
79     {
80       return this->gridOrigin + localCoordinates * this->gridSpacing;
81     }
82 
83     template <typename VOXEL_TYPE,
84               VOXEL_TYPE samplingFunction(const vec3f &, float),
85               vec3f gradientFunction(const vec3f &, float)>
86     inline void ProceduralStructuredRegularVolume<
87         VOXEL_TYPE,
88         samplingFunction,
generateGridParameters(const vec3i & dimensions,const float boundingBoxSize,vec3f & gridOrigin,vec3f & gridSpacing)89         gradientFunction>::generateGridParameters(const vec3i &dimensions,
90                                                   const float boundingBoxSize,
91                                                   vec3f &gridOrigin,
92                                                   vec3f &gridSpacing)
93     {
94       // generate grid parameters for a bounding box centered at (0,0,0) with a
95       // maximum length boundingBoxSize
96 
97       const float minGridSpacing =
98           reduce_min(boundingBoxSize / (dimensions - 1));
99 
100       gridOrigin  = -0.5f * (dimensions - 1) * minGridSpacing;
101       gridSpacing = vec3f(minGridSpacing);
102     }
103 
104     ///////////////////////////////////////////////////////////////////////////
105     // Procedural volume types ////////////////////////////////////////////////
106     ///////////////////////////////////////////////////////////////////////////
107 
108     template <typename VOXEL_TYPE>
109     using WaveletStructuredRegularVolume =
110         ProceduralStructuredRegularVolume<VOXEL_TYPE,
111                                           getWaveletValue<VOXEL_TYPE>,
112                                           getWaveletGradient>;
113 
114     template <typename VOXEL_TYPE>
115     using XYZStructuredRegularVolume =
116         ProceduralStructuredRegularVolume<VOXEL_TYPE,
117                                           getXYZValue<VOXEL_TYPE>,
118                                           getXYZGradient>;
119 
120     using XProceduralVolume =
121         ProceduralStructuredRegularVolume<float, getXValue, getXGradient>;
122 
123     using YProceduralVolume =
124         ProceduralStructuredRegularVolume<float, getYValue, getYGradient>;
125 
126     using ZProceduralVolume =
127         ProceduralStructuredRegularVolume<float, getZValue, getZGradient>;
128 
129     // required due to Windows Visual Studio compiler bugs, which prevent us
130     // from writing e.g. WaveletStructuredRegularVolume<float>
131     using WaveletStructuredRegularVolumeUChar =
132         ProceduralStructuredRegularVolume<unsigned char,
133                                           getWaveletValue<unsigned char>,
134                                           getWaveletGradient>;
135     using WaveletStructuredRegularVolumeShort =
136         ProceduralStructuredRegularVolume<short,
137                                           getWaveletValue<short>,
138                                           getWaveletGradient>;
139     using WaveletStructuredRegularVolumeUShort =
140         ProceduralStructuredRegularVolume<unsigned short,
141                                           getWaveletValue<unsigned short>,
142                                           getWaveletGradient>;
143     using WaveletStructuredRegularVolumeHalf =
144         ProceduralStructuredRegularVolume<half_float::half,
145                                           getWaveletValue<half_float::half>,
146                                           getWaveletGradient>;
147     using WaveletStructuredRegularVolumeFloat =
148         ProceduralStructuredRegularVolume<float,
149                                           getWaveletValue<float>,
150                                           getWaveletGradient>;
151     using WaveletStructuredRegularVolumeDouble =
152         ProceduralStructuredRegularVolume<double,
153                                           getWaveletValue<double>,
154                                           getWaveletGradient>;
155 
156     using XYZStructuredRegularVolumeUChar =
157         ProceduralStructuredRegularVolume<unsigned char,
158                                           getXYZValue<unsigned char>,
159                                           getXYZGradient>;
160     using XYZStructuredRegularVolumeShort =
161         ProceduralStructuredRegularVolume<short,
162                                           getXYZValue<short>,
163                                           getXYZGradient>;
164     using XYZStructuredRegularVolumeUShort =
165         ProceduralStructuredRegularVolume<unsigned short,
166                                           getXYZValue<unsigned short>,
167                                           getXYZGradient>;
168     using XYZStructuredRegularVolumeHalf =
169         ProceduralStructuredRegularVolume<half_float::half,
170                                           getXYZValue<half_float::half>,
171                                           getXYZGradient>;
172     using XYZStructuredRegularVolumeFloat =
173         ProceduralStructuredRegularVolume<float,
174                                           getXYZValue<float>,
175                                           getXYZGradient>;
176     using XYZStructuredRegularVolumeDouble =
177         ProceduralStructuredRegularVolume<double,
178                                           getXYZValue<double>,
179                                           getXYZGradient>;
180 
181     using SphereStructuredRegularVolumeUChar =
182         ProceduralStructuredRegularVolume<unsigned char,
183                                           getWigglingSphereValue<unsigned char>,
184                                           getWigglingSphereGradient>;
185     using SphereStructuredRegularVolumeShort =
186         ProceduralStructuredRegularVolume<short,
187                                           getWigglingSphereValue<short>,
188                                           getWigglingSphereGradient>;
189     using SphereStructuredRegularVolumeUShort =
190         ProceduralStructuredRegularVolume<
191             unsigned short,
192             getWigglingSphereValue<unsigned short>,
193             getWigglingSphereGradient>;
194     using SphereStructuredRegularVolumeHalf = ProceduralStructuredRegularVolume<
195         half_float::half,
196         getWigglingSphereValue<half_float::half>,
197         getWigglingSphereGradient>;
198     using SphereStructuredRegularVolumeFloat =
199         ProceduralStructuredRegularVolume<float,
200                                           getWigglingSphereValue<float>,
201                                           getWigglingSphereGradient>;
202     using SphereStructuredRegularVolumeDouble =
203         ProceduralStructuredRegularVolume<double,
204                                           getWigglingSphereValue<double>,
205                                           getWigglingSphereGradient>;
206 
207     // using type traits to work around Visual Studio compiler templating bugs
208     template <typename VOXEL_TYPE>
209     struct ProceduralStructuredRegularVolumes
210     {
211       using Wavelet = void;
212     };
213 
214     template <>
215     struct ProceduralStructuredRegularVolumes<unsigned char>
216     {
217       using Wavelet =
218           ProceduralStructuredRegularVolume<unsigned char,
219                                             getWaveletValue<unsigned char>,
220                                             getWaveletGradient>;
221     };
222 
223     template <>
224     struct ProceduralStructuredRegularVolumes<short>
225     {
226       using Wavelet = ProceduralStructuredRegularVolume<short,
227                                                         getWaveletValue<short>,
228                                                         getWaveletGradient>;
229     };
230 
231     template <>
232     struct ProceduralStructuredRegularVolumes<unsigned short>
233     {
234       using Wavelet =
235           ProceduralStructuredRegularVolume<unsigned short,
236                                             getWaveletValue<unsigned short>,
237                                             getWaveletGradient>;
238     };
239 
240     template <>
241     struct ProceduralStructuredRegularVolumes<half_float::half>
242     {
243       using Wavelet =
244           ProceduralStructuredRegularVolume<half_float::half,
245                                             getWaveletValue<half_float::half>,
246                                             getWaveletGradient>;
247     };
248 
249     template <>
250     struct ProceduralStructuredRegularVolumes<float>
251     {
252       using Wavelet = ProceduralStructuredRegularVolume<float,
253                                                         getWaveletValue<float>,
254                                                         getWaveletGradient>;
255     };
256 
257     template <>
258     struct ProceduralStructuredRegularVolumes<double>
259     {
260       using Wavelet = ProceduralStructuredRegularVolume<double,
261                                                         getWaveletValue<double>,
262                                                         getWaveletGradient>;
263     };
264 
265   }  // namespace testing
266 }  // namespace openvkl
267