3 #include <Core/Containers/Grid.hpp>
4 #include <Core/Math/LinearAlgebra.hpp>
5 #include <Core/RaCore.hpp>
15 template <
typename T, u
int N>
20 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
22 using Vector = Eigen::Matrix<Scalar, N, 1>;
23 using AabbND = Eigen::AlignedBox<Scalar, N>;
26 Tex(
const IdxVector& resolution,
const Vector& start,
const Vector&
end );
29 Tex(
const IdxVector& resolution,
const AabbND& aabb );
33 Tex& operator=(
const Tex& other ) =
default;
35 inline const AabbND& getAabb()
const;
38 T
fetch(
const Vector& v )
const;
59 struct NLinearInterpolator {
63 const typename Tex<T, N>::Vector& fact,
64 const typename Tex<T, N>::IdxVector& size,
65 const typename Tex<T, N>::IdxVector& clamped_nearest )
67 CORE_ERROR(
"N-linear interpolation not implemented for N= " << N );
73 struct NLinearInterpolator<2> {
76 static T interpolate(
const Grid<T, 2>& grid,
78 const Vector2ui& size,
79 const Vector2ui& clamped_nearest ) {
80 const uint i0 = clamped_nearest[0];
81 const uint j0 = clamped_nearest[1];
83 const uint i1 = i0 < size[0] ? i0 + 1 : i0;
84 const uint j1 = j0 < size[1] ? j0 + 1 : j0;
86 const T v00 = grid.at( { i0, j0 } );
87 const T v01 = grid.at( { i0, j1 } );
88 const T v10 = grid.at( { i1, j0 } );
89 const T v11 = grid.at( { i1, j1 } );
91 const T c0 = v00 * ( 1.0 - fact[0] ) + v10 * fact[0];
92 const T c1 = v01 * ( 1.0 - fact[0] ) + v11 * fact[0];
94 return c0 * ( 1.0 - fact[1] ) + c1 * fact[1];
99 struct NLinearInterpolator<3> {
101 template <
typename T>
102 static T interpolate(
const Grid<T, 3>& grid,
104 const Vector3ui& size,
105 const Vector3ui& clamped_nearest ) {
106 const uint i0 = clamped_nearest[0];
107 const uint j0 = clamped_nearest[1];
108 const uint k0 = clamped_nearest[2];
109 const uint i1 = i0 < size[0] ? i0 + 1 : i0;
110 const uint j1 = j0 < size[1] ? j0 + 1 : j0;
111 const uint k1 = k0 < size[2] ? k0 + 1 : k0;
113 const T v000 = grid.at( { i0, j0, k0 } );
114 const T v001 = grid.at( { i0, j0, k1 } );
115 const T v010 = grid.at( { i0, j1, k0 } );
116 const T v011 = grid.at( { i0, j1, k1 } );
117 const T v100 = grid.at( { i1, j0, k0 } );
118 const T v101 = grid.at( { i1, j0, k1 } );
119 const T v110 = grid.at( { i1, j1, k0 } );
120 const T v111 = grid.at( { i1, j1, k1 } );
122 const T c00 = v000 * ( 1.0 - fact[0] ) + v100 * fact[0];
123 const T c10 = v010 * ( 1.0 - fact[0] ) + v110 * fact[0];
124 const T c01 = v001 * ( 1.0 - fact[0] ) + v101 * fact[0];
125 const T c11 = v011 * ( 1.0 - fact[0] ) + v111 * fact[0];
127 const T c0 = c00 * ( 1.0 - fact[1] ) + c10 * fact[1];
128 const T c1 = c01 * ( 1.0 - fact[1] ) + c11 * fact[1];
130 return c0 * ( 1.0 - fact[2] ) + c1 * fact[2];
135 template <
typename T, u
int N>
136 Tex<T, N>::Tex(
const IdxVector& resolution,
const Vector& start,
const Vector& end ) :
137 Grid<T, N>( resolution ), m_aabb( start, end ) {
138 const Vector quotient = ( resolution - IdxVector::Ones() ).
template cast<Scalar>();
139 m_cellSize = m_aabb.sizes().cwiseQuotient( quotient );
142 template <
typename T, u
int N>
144 Grid<T, N>( resolution ), m_aabb( aabb ) {
145 const Vector quotient = ( resolution - IdxVector::Ones() ).
template cast<Scalar>();
146 m_cellSize = m_aabb.sizes().cwiseQuotient( quotient );
149 template <
typename T, u
int N>
154 template <
typename T, u
int N>
156 Vector scaled_coords( ( v - m_aabb.min() ).cwiseQuotient( m_cellSize ) );
160 CORE_ASSERT( !( ( tmp.array() < Vector::Zero().array() ).any() ),
"Cannot cast to uint" );
161 IdxVector nearest = tmp.template cast<uint>();
162 Vector fact = scaled_coords - tmp;
167 this->sizeVector() - IdxVector::Ones();
168 IdxVector clamped_nearest =
169 Ra::Core::Math::clamp<IdxVector>( nearest, IdxVector::Zero(), size );
171 return NLinearInterpolator<N>::interpolate( *
this, fact, size, clamped_nearest );
Iterator end()
Get an iterator on this grid past the last element.
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.