1// Copyright 2009-2021 Intel Corporation
2// SPDX-License-Identifier: Apache-2.0
3
4#pragma once
5
6#include "common/Ray.ih"
7#include "math/AffineSpace.ih"
8#include "rkcommon/math/box.ih"
9// openvkl
10#include "openvkl/openvkl.isph"
11
12struct TransferFunction;
13
14//! \brief Variables and methods common to all subtypes of the Volume
15//!  class, an abstraction for the concrete object which performs the
16//!  volume sampling (this struct must be the first field of a struct
17//!  representing a "derived" class to allow casting to that class).
18//!
19struct Volume
20{
21  int32 volumeID;
22
23  VKLVolume vklVolume;
24  VKLSampler vklSampler;
25
26  //! Find the next isosurface hit point in the volume for ray casting based
27  //! renderers.
28  void (*intersectIsosurface)(const void *uniform _self,
29      uniform float *uniform isovalues,
30      uniform int numIsovalues,
31      uniform size_t geomID,
32      // ray.u contains ray-space intersection error, i.e. the epsilon
33      varying Ray &ray);
34
35  /*! Bounding box for the volume in world coordinates.
36      This is an internal derived parameter and not meant to be
37      redefined externally.
38  */
39  box3f boundingBox;
40};
41
42void Volume_Constructor(Volume *uniform volume);
43
44// Helper functions ///////////////////////////////////////////////////////////
45
46inline float Volume_getSample(const Volume *uniform volume, const vec3f &P)
47{
48  return vklComputeSampleV(volume->vklSampler, &((const vkl_vec3f &)P));
49}
50
51inline vec3f Volume_getGradient(const Volume *uniform volume, const vec3f &P)
52{
53  vkl_vec3f result =
54      vklComputeGradientV(volume->vklSampler, &((const vkl_vec3f &)P));
55
56  // TODO: remove it once VKL no longer returns sporadic NaNs
57  if (isnan(result.x))
58    result.x = 1.f;
59  if (isnan(result.y))
60    result.y = 1.f;
61  if (isnan(result.z))
62    result.z = 1.f;
63
64  return *((varying vec3f *)&result);
65}
66