glm_alias.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #define GLM_ENABLE_EXPERIMENTAL
4 
5 #include "StringIO.hpp"
6 #include "SS.hpp"
7 #include "Interpolator.hpp"
8 #include <glm/glm.hpp>
9 #include <glm/ext.hpp>
10 #include <array>
11 #include <iomanip>
12 
13 
14 //-------------- float3 -----------------------
15 namespace iv
16 {
17 
18 using int2 = glm::tvec2< int >;
19 using int3 = glm::tvec3< int >;
20 
21 using float2 = glm::tvec2< float >;
22 //using float3 = glm::tvec3< float >;
23 using float3 = glm::vec3;
24 using float4 = glm::tvec4< float >;
25 
26 using bool2 = glm::tvec2< bool >;
27 using bool3 = glm::tvec3< bool >;
28 
29 using uchar = unsigned char;
30 using uchar4 = glm::tvec4< unsigned char >;
31 
32 using float4x4 = glm::tmat4x4< float >;
33 
34 using floatQuat = glm::tquat< float >;
35 
36 
37 template< typename Type >
38 struct StringIO< glm::tvec2< Type > >
39 {
40  glm::tvec2< Type > Read( const char * source, Context const * context ) const
41  {
42  return glm::tvec2< Type >( 0, 0 );
43  }
44 
45  std::string Write( glm::tvec2< Type > val, Context const * context ) const
46  {
47  return SS() << "(" << val.x << ", " << val.y << ")" << SS::str();
48  }
49 };
50 
51 template< typename Type >
52 struct StringIO< glm::tvec3< Type > >
53 {
54  glm::tvec3< Type > Read( const char * source, Context const * context ) const
55  {
56  return glm::tvec3< Type >( 0, 0, 0 );
57  }
58 
59  std::string Write( glm::tvec3< Type > val, Context const * context ) const
60  {
61  return SS() << "(" << val.x << ", " << val.y << ", " << val.z << ")" << SS::str();
62  }
63 };
64 
65 template< typename Type >
66 struct StringIO< glm::tvec4< Type > >
67 {
68  glm::tvec4< Type > Read( const char * source, Context const * context ) const
69  {
70  return glm::tvec4< Type >( 0, 0, 0, 0 );
71  }
72 
73  std::string Write( glm::tvec4< Type > val, Context const * context ) const
74  {
75  return SS() << "(" << val.x << ", " << val.y << ", " << val.z << ", " << val.w << ")" << SS::str();
76  }
77 };
78 
79 template<>
81 {
82  floatQuat Read( const char * source, Context const * context ) const
83  {
84  return floatQuat( 0, 0, 0, 0 );
85  }
86 
87  std::string Write( floatQuat val, Context const * context ) const
88  {
89  return SS() << "(" << val.w << " | " << val.x << ", " << val.y << ", " << val.z << ")" << SS::str();
90  }
91 };
92 
93 template<>
94 struct StringIO< float4x4 >
95 {
96  float4x4 Read( const char * source, Context const * context ) const
97  {
98  return float4x4( 1 );
99  }
100 
101  std::string Write( float4x4 val, Context const * context ) const
102  {
103  // prepare
104  std::array< std::array< std::string, 4 >, 4 > parts;
105  std::array< size_t, 4 > widths;
106  widths.fill( 0 );
107 
108  for( size_t x = 0; x < 4; x++ )
109  for( size_t y = 0; y < 4; y++ )
110  {
111  std::stringstream ss;
112  ss << std::setprecision( 3 ) << val[ x ][ y ];
113  parts[ y ][ x ] = ss.str();
114  auto w = parts[ y ][ x ].length();
115  if( widths[ x ] < w )
116  widths[ x ] = w;
117  }
118 
119  std::stringstream out;
120 
121  // first line
122  out << "╭ ";
123  for( size_t i = 0; i < widths[ 0 ] + widths[ 1 ] + widths[ 2 ] + widths[ 3 ] + 6; i++ )
124  out << " ";
125  out << " ╮" << std::endl;
126 
127  // middle lines
128  out << "│ ( " << std::setw( widths[ 0 ] ) << parts[ 0 ][ 0 ] << ", " << std::setw( widths[ 1 ] ) << parts[ 0 ][ 1 ] << ", " << std::setw( widths[ 2 ] ) << parts[ 0 ][ 2 ] << ", " << std::setw( widths[ 3 ] ) << parts[ 0 ][ 3 ] << " ) │" << std::endl;
129  out << "│ ( " << std::setw( widths[ 0 ] ) << parts[ 1 ][ 0 ] << ", " << std::setw( widths[ 1 ] ) << parts[ 1 ][ 1 ] << ", " << std::setw( widths[ 2 ] ) << parts[ 1 ][ 2 ] << ", " << std::setw( widths[ 3 ] ) << parts[ 1 ][ 3 ] << " ) │" << std::endl;
130  out << "│ ( " << std::setw( widths[ 0 ] ) << parts[ 2 ][ 0 ] << ", " << std::setw( widths[ 1 ] ) << parts[ 2 ][ 1 ] << ", " << std::setw( widths[ 2 ] ) << parts[ 2 ][ 2 ] << ", " << std::setw( widths[ 3 ] ) << parts[ 2 ][ 3 ] << " ) │" << std::endl;
131  out << "│ ( " << std::setw( widths[ 0 ] ) << parts[ 3 ][ 0 ] << ", " << std::setw( widths[ 1 ] ) << parts[ 3 ][ 1 ] << ", " << std::setw( widths[ 2 ] ) << parts[ 3 ][ 2 ] << ", " << std::setw( widths[ 3 ] ) << parts[ 3 ][ 3 ] << " ) │" << std::endl;
132 
133  // last line
134  out << "╰ ";
135  for( size_t i = 0; i < widths[ 0 ] + widths[ 1 ] + widths[ 2 ] + widths[ 3 ] + 6; i++ )
136  out << " ";
137  out << " ╯";
138 
139  return out.str();
140  }
141 };
142 
143 
144 
145 //------------------------------------- interpolator -----------------------------------------------------
146 template<>
148 {
149  Interpolator_float Distance( float3 const & from, float3 const & to ) const
150  {
151  return glm::distance( from, to );
152  }
153 
154  std::pair< float3, Interpolator_float > Interpolate( float3 const & from, float3 const & to, Interpolator_float distance ) const
155  {
156  if( distance == std::numeric_limits< Interpolator_float >::infinity() )
157  return std::pair( to, Interpolator_float( 0.0 ) );
158 
159  if( glm::distance( to, from ) <= distance )
160  return std::pair( to, Interpolator_float( 0.0 ) );
161 
162  return std::pair( from + glm::normalize( to - from ) * distance, Interpolator_float( 0.0 ) );
163  }
164 };
165 
166 
167 
168 template<>
170 {
171  Interpolator_float Distance( float4x4 const & from, float4x4 const & to ) const
172  {
173  float4x4 diff( to - from );
174  float distance_sq = glm::length2( glm::row( diff, 0 ) ) + glm::length2( glm::row( diff, 1 ) ) + glm::length2( glm::row( diff, 2 ) ) + glm::length2( glm::row( diff, 3 ) );
175  return sqrt( distance_sq );
176  }
177 
178  std::pair< float4x4, Interpolator_float > Interpolate( float4x4 const & from, float4x4 const & to, Interpolator_float distance ) const
179  {
180  float4x4 diff( to - from );
181  float current_distance_sq = glm::length2( glm::row( diff, 0 ) ) + glm::length2( glm::row( diff, 1 ) ) + glm::length2( glm::row( diff, 2 ) ) + glm::length2( glm::row( diff, 3 ) );
182  float current_distance = sqrt( current_distance_sq );
183 
184  float4x4 result;
185 
186  result[ 0 ][ 0 ] = from[ 0 ][ 0 ] + diff[ 0 ][ 0 ] / current_distance * distance;
187  result[ 0 ][ 1 ] = from[ 0 ][ 1 ] + diff[ 0 ][ 1 ] / current_distance * distance;
188  result[ 0 ][ 2 ] = from[ 0 ][ 2 ] + diff[ 0 ][ 2 ] / current_distance * distance;
189  result[ 0 ][ 3 ] = from[ 0 ][ 3 ] + diff[ 0 ][ 3 ] / current_distance * distance;
190 
191  result[ 1 ][ 0 ] = from[ 1 ][ 0 ] + diff[ 1 ][ 0 ] / current_distance * distance;
192  result[ 1 ][ 1 ] = from[ 1 ][ 1 ] + diff[ 1 ][ 1 ] / current_distance * distance;
193  result[ 1 ][ 2 ] = from[ 1 ][ 2 ] + diff[ 1 ][ 2 ] / current_distance * distance;
194  result[ 1 ][ 3 ] = from[ 1 ][ 3 ] + diff[ 1 ][ 3 ] / current_distance * distance;
195 
196  result[ 2 ][ 0 ] = from[ 2 ][ 0 ] + diff[ 2 ][ 0 ] / current_distance * distance;
197  result[ 2 ][ 1 ] = from[ 2 ][ 1 ] + diff[ 2 ][ 1 ] / current_distance * distance;
198  result[ 2 ][ 2 ] = from[ 2 ][ 2 ] + diff[ 2 ][ 2 ] / current_distance * distance;
199  result[ 2 ][ 3 ] = from[ 2 ][ 3 ] + diff[ 2 ][ 3 ] / current_distance * distance;
200 
201  result[ 3 ][ 0 ] = from[ 3 ][ 0 ] + diff[ 3 ][ 0 ] / current_distance * distance;
202  result[ 3 ][ 1 ] = from[ 3 ][ 1 ] + diff[ 3 ][ 1 ] / current_distance * distance;
203  result[ 3 ][ 2 ] = from[ 3 ][ 2 ] + diff[ 3 ][ 2 ] / current_distance * distance;
204  result[ 3 ][ 3 ] = from[ 3 ][ 3 ] + diff[ 3 ][ 3 ] / current_distance * distance;
205 
206  return std::pair( result, Interpolator_float( 0.0 ) );
207  }
208 };
209 
211 {
212  bool operator()( int2 const & left, int2 const & right ) const
213  {
214  return std::pair( left.x, left.y ) < std::pair( right.x, right.y );
215  }
216 };
217 
219 {
220  bool operator()( int2 const & left, int2 const & right ) const
221  {
222  return std::pair( left.y, left.x ) < std::pair( right.y, right.x );
223  }
224 };
225 
226 }
227 
228 inline std::ostream & operator<<( std::ostream & out, iv::int2 const & val )
229 {
230  out << "( " << val.x << ", " << val.y << " )";
231  return out;
232 }
233 
234 inline std::ostream & operator<<( std::ostream & out, iv::int3 const & val )
235 {
236  out << "( " << val.x << ", " << val.y << ", " << val.z << " )";
237  return out;
238 }
239 
240 inline std::ostream & operator<<( std::ostream & out, iv::float2 const & val )
241 {
242  out << "( " << val.x << ", " << val.y << " )";
243  return out;
244 }
245 
246 inline std::ostream & operator<<( std::ostream & out, iv::float3 const & val )
247 {
248  out << "( " << val.x << ", " << val.y << ", " << val.z << " )";
249  return out;
250 }
251 
252 inline std::ostream & operator<<( std::ostream & out, iv::float4 const & val )
253 {
254  out << "( " << val.x << ", " << val.y << ", " << val.z << ", " << val.w << " )";
255  return out;
256 }
257 
258 inline std::ostream & operator<<( std::ostream & out, iv::bool2 const & val )
259 {
260  out << "( " << val.x << ", " << val.y << " )";
261  return out;
262 }
263 
264 inline std::ostream & operator<<( std::ostream & out, iv::bool3 const & val )
265 {
266  out << "( " << val.x << ", " << val.y << ", " << val.z << " )";
267  return out;
268 }
269 
270 inline std::ostream & operator<<( std::ostream & out, iv::uchar4 const & val )
271 {
272  out << "( " << val.x << ", " << val.y << ", " << val.z << ", " << val.w << " )";
273  return out;
274 }
275