Loading [MathJax]/extensions/TeX/AMSmath.js
Radium Engine  1.5.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
Tex.hpp
1 #pragma once
2 
3 #include <Core/Containers/Grid.hpp>
4 #include <Core/Math/LinearAlgebra.hpp>
5 #include <Core/RaCore.hpp>
6 #include <Core/Types.hpp>
7 
8 #include <Eigen/Core>
9 
10 namespace Ra {
11 namespace Core {
15 template <typename T, uint N>
16 class Tex : public Grid<T, N>
17 {
18 
19  public:
20  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
21  using IdxVector = typename Grid<T, N>::IdxVector;
22  using Vector = Eigen::Matrix<Scalar, N, 1>;
23  using AabbND = Eigen::AlignedBox<Scalar, N>;
24 
26  Tex( const IdxVector& resolution, const Vector& start, const Vector& end );
27 
29  Tex( const IdxVector& resolution, const AabbND& aabb );
30 
32  Tex( const Tex& other ) = default;
33  Tex& operator=( const Tex& other ) = default;
34 
35  inline const AabbND& getAabb() const;
36 
38  T fetch( const Vector& v ) const;
39 
40  private:
42  AabbND m_aabb;
45  Vector m_cellSize;
46 };
47 
48 template <typename T>
49 using Tex2D = Tex<T, 2>;
50 
51 template <typename T>
52 using Tex3D = Tex<T, 3>;
53 
54 // Helper functions
55 namespace {
56 // This is a helper class for the texture fetch implementation. This interpolate linear
57 // interpolation from values at a corner of a grid.
58 template <uint N>
59 struct NLinearInterpolator {
60  template <typename T>
61  static T interpolate(
62  const Grid<T, N>& grid, // grid from which values are read
63  const typename Tex<T, N>::Vector& fact, // factors of the interpolation (between 0 and 1)
64  const typename Tex<T, N>::IdxVector& size, // size of the dual grid
65  const typename Tex<T, N>::IdxVector& clamped_nearest ) // base indices of the cell
66  {
67  CORE_ERROR( "N-linear interpolation not implemented for N= " << N );
68  return T();
69  }
70 };
71 
72 template <>
73 struct NLinearInterpolator<2> {
74  // bilinear interpolation in a quad cell
75  template <typename T>
76  static T interpolate( const Grid<T, 2>& grid,
77  const Vector2& fact,
78  const Vector2ui& size,
79  const Vector2ui& clamped_nearest ) {
80  const uint i0 = clamped_nearest[0];
81  const uint j0 = clamped_nearest[1];
82 
83  const uint i1 = i0 < size[0] ? i0 + 1 : i0;
84  const uint j1 = j0 < size[1] ? j0 + 1 : j0;
85 
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 } );
90 
91  const T c0 = v00 * ( 1.0 - fact[0] ) + v10 * fact[0];
92  const T c1 = v01 * ( 1.0 - fact[0] ) + v11 * fact[0];
93 
94  return c0 * ( 1.0 - fact[1] ) + c1 * fact[1];
95  }
96 };
97 
98 template <>
99 struct NLinearInterpolator<3> {
100  // tri-linear interpolation in a cubic cell
101  template <typename T>
102  static T interpolate( const Grid<T, 3>& grid,
103  const Vector3& fact,
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;
112 
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 } );
121 
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];
126 
127  const T c0 = c00 * ( 1.0 - fact[1] ) + c10 * fact[1];
128  const T c1 = c01 * ( 1.0 - fact[1] ) + c11 * fact[1];
129 
130  return c0 * ( 1.0 - fact[2] ) + c1 * fact[2];
131  }
132 };
133 } // namespace
134 
135 template <typename T, uint 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 );
140 }
141 
142 template <typename T, uint N>
143 Tex<T, N>::Tex( const IdxVector& resolution, const AabbND& aabb ) :
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 );
147 }
148 
149 template <typename T, uint N>
150 inline const typename Tex<T, N>::AabbND& Tex<T, N>::getAabb() const {
151  return m_aabb;
152 }
153 
154 template <typename T, uint N>
155 inline T Tex<T, N>::fetch( const Vector& v ) const {
156  Vector scaled_coords( ( v - m_aabb.min() ).cwiseQuotient( m_cellSize ) );
157  // Sometimes due to float imprecision, a value of 0 is passed as -1e7
158  // which floors incorrectly rounds down to -1, hence the use of trunc().
159  Vector tmp = Ra::Core::Math::trunc( scaled_coords );
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;
163 
164  // TODO: Give other texture behaviour (such as wrapping) ?
165 
166  IdxVector size =
167  this->sizeVector() - IdxVector::Ones(); // TODO check this code on borders of the grid
168  IdxVector clamped_nearest =
169  Ra::Core::Math::clamp<IdxVector>( nearest, IdxVector::Zero(), size );
170 
171  return NLinearInterpolator<N>::interpolate( *this, fact, size, clamped_nearest );
172 }
173 } // namespace Core
174 } // namespace Ra
Iterator end()
Get an iterator on this grid past the last element.
Definition: Grid.hpp:375
Tex(const IdxVector &resolution, const Vector &start, const Vector &end)
Construct a Tex with the given resolution in the box given by two points.
Definition: Tex.hpp:136
T fetch(const Vector &v) const
Tri-linear interpolation of the grid values at position v.
Definition: Tex.hpp:155
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.
Definition: Cage.cpp:3