3#include <Core/Containers/Grid.hpp>
4#include <Core/Math/LinearAlgebra.hpp>
5#include <Core/RaCore.hpp>
15template <
typename T, u
int N>
21 using Vector = Eigen::Matrix<Scalar, N, 1>;
22 using AabbND = Eigen::AlignedBox<Scalar, N>;
25 Tex(
const IdxVector& resolution,
const Vector& start,
const Vector& end );
28 Tex(
const IdxVector& resolution,
const AabbND& aabb );
32 Tex& operator=(
const Tex& other ) =
default;
34 inline const AabbND& getAabb()
const;
37 T
fetch(
const Vector& v )
const;
58struct NLinearInterpolator {
62 const typename Tex<T, N>::Vector& fact,
63 const typename Tex<T, N>::IdxVector& size,
64 const typename Tex<T, N>::IdxVector& clamped_nearest )
66 CORE_ERROR(
"N-linear interpolation not implemented for N= " << N );
72struct NLinearInterpolator<2> {
75 static T interpolate(
const Grid<T, 2>& grid,
77 const Vector2ui& size,
78 const Vector2ui& clamped_nearest ) {
79 const uint i0 = clamped_nearest[0];
80 const uint j0 = clamped_nearest[1];
82 const uint i1 = i0 < size[0] ? i0 + 1 : i0;
83 const uint j1 = j0 < size[1] ? j0 + 1 : j0;
85 const T v00 = grid.at( { i0, j0 } );
86 const T v01 = grid.at( { i0, j1 } );
87 const T v10 = grid.at( { i1, j0 } );
88 const T v11 = grid.at( { i1, j1 } );
90 const T c0 = v00 * ( 1.0 - fact[0] ) + v10 * fact[0];
91 const T c1 = v01 * ( 1.0 - fact[0] ) + v11 * fact[0];
93 return c0 * ( 1.0 - fact[1] ) + c1 * fact[1];
98struct NLinearInterpolator<3> {
100 template <
typename T>
101 static T interpolate(
const Grid<T, 3>& grid,
103 const Vector3ui& size,
104 const Vector3ui& clamped_nearest ) {
105 const uint i0 = clamped_nearest[0];
106 const uint j0 = clamped_nearest[1];
107 const uint k0 = clamped_nearest[2];
108 const uint i1 = i0 < size[0] ? i0 + 1 : i0;
109 const uint j1 = j0 < size[1] ? j0 + 1 : j0;
110 const uint k1 = k0 < size[2] ? k0 + 1 : k0;
112 const T v000 = grid.at( { i0, j0, k0 } );
113 const T v001 = grid.at( { i0, j0, k1 } );
114 const T v010 = grid.at( { i0, j1, k0 } );
115 const T v011 = grid.at( { i0, j1, k1 } );
116 const T v100 = grid.at( { i1, j0, k0 } );
117 const T v101 = grid.at( { i1, j0, k1 } );
118 const T v110 = grid.at( { i1, j1, k0 } );
119 const T v111 = grid.at( { i1, j1, k1 } );
121 const T c00 = v000 * ( 1.0 - fact[0] ) + v100 * fact[0];
122 const T c10 = v010 * ( 1.0 - fact[0] ) + v110 * fact[0];
123 const T c01 = v001 * ( 1.0 - fact[0] ) + v101 * fact[0];
124 const T c11 = v011 * ( 1.0 - fact[0] ) + v111 * fact[0];
126 const T c0 = c00 * ( 1.0 - fact[1] ) + c10 * fact[1];
127 const T c1 = c01 * ( 1.0 - fact[1] ) + c11 * fact[1];
129 return c0 * ( 1.0 - fact[2] ) + c1 * fact[2];
134template <
typename T, u
int N>
135Tex<T, N>::Tex(
const IdxVector& resolution,
const Vector& start,
const Vector& end ) :
136 Grid<T, N>( resolution ), m_aabb( start, end ) {
137 const Vector quotient = ( resolution - IdxVector::Ones() ).template cast<Scalar>();
138 m_cellSize = m_aabb.sizes().cwiseQuotient( quotient );
141template <
typename T, u
int N>
143 Grid<T, N>( resolution ), m_aabb( aabb ) {
144 const Vector quotient = ( resolution - IdxVector::Ones() ).template cast<Scalar>();
145 m_cellSize = m_aabb.sizes().cwiseQuotient( quotient );
148template <
typename T, u
int N>
153template <
typename T, u
int N>
155 Vector scaled_coords( ( v - m_aabb.min() ).cwiseQuotient( m_cellSize ) );
159 CORE_ASSERT( !( ( tmp.array() < Vector::Zero().array() ).any() ),
"Cannot cast to uint" );
160 IdxVector nearest = tmp.template cast<uint>();
161 Vector fact = scaled_coords - tmp;
166 this->sizeVector() - IdxVector::Ones();
167 IdxVector clamped_nearest =
170 return NLinearInterpolator<N>::interpolate( *
this, fact, size, clamped_nearest );
Eigen::Matrix< uint, D, 1 > IdxVector
Dimension of our grid.
Tex(const IdxVector &resolution, const Vector &start, const Vector &end)
Construct a Tex with the given resolution in the box given by two points.
T fetch(const Vector &v) const
Tri-linear interpolation of the grid values at position v.
Tex(const Tex &other)=default
Copy constructor and assignment operator perform a deep copy.
Vector trunc(const Vector &v)
Component-wise trunc() function on a floating-point vector.
Derived::PlainMatrix clamp(const Eigen::MatrixBase< Derived > &v, const Eigen::MatrixBase< DerivedA > &min, const Eigen::MatrixBase< DerivedB > &max)
Component-wise clamp() function on a floating-point vector.
hepler function to manage enum as underlying types in VariableSet