File indexing completed on 2026-04-09 07:49:55
0001 #pragma once
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include <glm/glm.hpp>
0017 #include <glm/gtc/type_ptr.hpp>
0018
0019 #include <vector>
0020 #include <string>
0021 #include <iomanip>
0022 #include <sstream>
0023
0024 struct strid
0025 {
0026 union uif64_t {
0027 uint64_t u ;
0028 int64_t i ;
0029 double f ;
0030 };
0031
0032 union uif32_t {
0033 uint32_t u ;
0034 int32_t i ;
0035 float f ;
0036 };
0037
0038
0039 static void Encode( glm::tmat4x4<double>& tr, const glm::tvec4<uint64_t>& col3 );
0040 static void Encode( double* ptr , uint64_t e );
0041 static void Decode( const glm::tmat4x4<double>& tr, glm::tvec4<uint64_t>& col3 );
0042 static void Decode( const double* ptr , uint64_t& e );
0043
0044
0045 static void Encode( glm::tmat4x4<double>& tr, const glm::tvec4<int64_t>& col3 );
0046 static void Encode( double* ptr , int64_t e );
0047 static void Decode( const glm::tmat4x4<double>& tr, glm::tvec4<int64_t>& col3 );
0048 static void Decode( const double* ptr , int64_t& e );
0049
0050
0051 static void Encode( glm::tmat4x4<float>& tr, const glm::tvec4<uint32_t>& col3 );
0052 static void Encode( float* ptr , uint32_t e );
0053 static void Decode( const glm::tmat4x4<float>& tr, glm::tvec4<uint32_t>& col3 );
0054 static void Decode( const float* ptr , uint32_t& e );
0055
0056
0057 static void Encode( glm::tmat4x4<float>& tr, const glm::tvec4<int32_t>& col3 );
0058 static void Encode( float* ptr , int32_t e );
0059 static void Decode( const glm::tmat4x4<float>& tr, glm::tvec4<int32_t>& col3 );
0060 static void Decode( const float* ptr , int32_t& e );
0061
0062
0063
0064 template<typename T>
0065 static void Clear( glm::tmat4x4<T>& tr);
0066
0067 template<typename T>
0068 static bool IsClear( const glm::tmat4x4<T>& tr);
0069
0070
0071 template<typename T, typename S>
0072 static std::string Desc( const glm::tmat4x4<T>& tr);
0073
0074 template<typename T>
0075 static std::string Desc_( const glm::tmat4x4<T>& tr);
0076
0077 template<typename T>
0078 static std::string Desc_( const char* a_label, const char* b_label, const glm::tmat4x4<T>& a, const glm::tmat4x4<T>& b );
0079
0080 template<typename T>
0081 static std::string Desc_( const char* a_label, const char* b_label, const char* c_label,
0082 const glm::tmat4x4<T>& a, const glm::tmat4x4<T>& b, const glm::tmat4x4<T>& c );
0083
0084 static void NarrowClear( glm::tmat4x4<float>& dst, const glm::tmat4x4<double>& src );
0085 static void NarrowDecodeClear( glm::tmat4x4<float>& dst , glm::tvec4<int32_t>& col3, const glm::tmat4x4<double>& src );
0086 static void Narrow( glm::tmat4x4<float>& dst, const glm::tmat4x4<double>& src );
0087
0088 static void NarrowClear( std::vector<glm::tmat4x4<float>>& dst, const std::vector<glm::tmat4x4<double>>& src );
0089 static void NarrowDecodeClear( std::vector<glm::tmat4x4<float>>& dst, std::vector<glm::tvec4<int32_t>>& col3, const std::vector<glm::tmat4x4<double>>& src );
0090
0091 static void Narrow( std::vector<glm::tmat4x4<float>>& dst, const std::vector<glm::tmat4x4<double>>& src );
0092
0093 template<typename T>
0094 static T DiffFromIdentity( const glm::tmat4x4<T>& tr );
0095
0096
0097 template<typename T>
0098 static void Read_( glm::tmat4x4<T>& dst, const T* src );
0099
0100 template<typename T, typename S>
0101 static void Read( glm::tmat4x4<T>& dst, const S* src, bool transpose );
0102
0103
0104 };
0105
0106
0107
0108 inline void strid::Encode( glm::tmat4x4<double>& tr, const glm::tvec4<uint64_t>& col3 )
0109 {
0110 double* tr00 = glm::value_ptr(tr) ;
0111 for(int r=0 ; r < 4 ; r++) Encode( tr00+4*r+3, col3[r] ) ;
0112 }
0113 inline void strid::Encode( double* ptr, uint64_t e)
0114 {
0115 uif64_t uif ;
0116 uif.u = e ;
0117 *ptr = uif.f ;
0118 }
0119 inline void strid::Decode( const glm::tmat4x4<double>& tr, glm::tvec4<uint64_t>& col3 )
0120 {
0121 const double* tr00 = glm::value_ptr(tr) ;
0122 for(int r=0 ; r < 4 ; r++) Decode( tr00+4*r+3, col3[r] ) ;
0123 }
0124 inline void strid::Decode( const double* ptr, uint64_t& e )
0125 {
0126 uif64_t uif ;
0127 uif.f = *ptr ;
0128 e = uif.u ;
0129 }
0130
0131
0132
0133
0134
0135
0136 inline void strid::Encode( glm::tmat4x4<double>& tr, const glm::tvec4<int64_t>& col3 )
0137 {
0138 double* tr00 = glm::value_ptr(tr) ;
0139 for(int r=0 ; r < 4 ; r++) Encode( tr00+4*r+3, col3[r] ) ;
0140 }
0141 inline void strid::Encode( double* ptr, int64_t e)
0142 {
0143 uif64_t uif ;
0144 uif.i = e ;
0145 *ptr = uif.f ;
0146 }
0147 inline void strid::Decode( const glm::tmat4x4<double>& tr, glm::tvec4<int64_t>& col3 )
0148 {
0149 const double* tr00 = glm::value_ptr(tr) ;
0150 for(int r=0 ; r < 4 ; r++) Decode( tr00+4*r+3, col3[r] ) ;
0151 }
0152 inline void strid::Decode( const double* ptr, int64_t& e )
0153 {
0154 uif64_t uif ;
0155 uif.f = *ptr ;
0156 e = uif.i ;
0157 }
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171 inline void strid::Encode( glm::tmat4x4<float>& tr, const glm::tvec4<uint32_t>& col3 )
0172 {
0173 float* tr00 = glm::value_ptr(tr) ;
0174 for(int r=0 ; r < 4 ; r++) Encode( tr00+4*r+3, col3[r] ) ;
0175 }
0176 inline void strid::Encode( float* ptr, uint32_t e)
0177 {
0178 uif32_t uif ;
0179 uif.u = e ;
0180 *ptr = uif.f ;
0181 }
0182 inline void strid::Decode( const glm::tmat4x4<float>& tr, glm::tvec4<uint32_t>& col3 )
0183 {
0184 const float* tr00 = glm::value_ptr(tr) ;
0185 for(int r=0 ; r < 4 ; r++) Decode( tr00+4*r+3, col3[r] ) ;
0186 }
0187 inline void strid::Decode( const float* ptr, uint32_t& e )
0188 {
0189 uif32_t uif ;
0190 uif.f = *ptr ;
0191 e = uif.u ;
0192 }
0193
0194
0195
0196
0197
0198
0199
0200
0201 inline void strid::Encode( glm::tmat4x4<float>& tr, const glm::tvec4<int32_t>& col3 )
0202 {
0203 float* tr00 = glm::value_ptr(tr) ;
0204 for(int r=0 ; r < 4 ; r++) Encode( tr00+4*r+3, col3[r] ) ;
0205 }
0206 inline void strid::Encode( float* ptr, int32_t e)
0207 {
0208 uif32_t uif ;
0209 uif.i = e ;
0210 *ptr = uif.f ;
0211 }
0212 inline void strid::Decode( const glm::tmat4x4<float>& tr, glm::tvec4<int32_t>& col3 )
0213 {
0214 const float* tr00 = glm::value_ptr(tr) ;
0215 for(int r=0 ; r < 4 ; r++) Decode( tr00+4*r+3, col3[r] ) ;
0216 }
0217 inline void strid::Decode( const float* ptr, int32_t& e )
0218 {
0219 uif32_t uif ;
0220 uif.f = *ptr ;
0221 e = uif.i ;
0222 }
0223
0224
0225
0226
0227
0228
0229 template<typename T>
0230 inline void strid::Clear( glm::tmat4x4<T>& tr )
0231 {
0232 T* tr00 = glm::value_ptr(tr) ;
0233 *(tr00+4*0+3) = T(0.) ;
0234 *(tr00+4*1+3) = T(0.) ;
0235 *(tr00+4*2+3) = T(0.) ;
0236 *(tr00+4*3+3) = T(1.) ;
0237 }
0238
0239
0240 template<typename T>
0241 inline bool strid::IsClear( const glm::tmat4x4<T>& tr )
0242 {
0243 const T* tr00 = glm::value_ptr(tr) ;
0244 return
0245 *(tr00+4*0+3) == T(0.) &&
0246 *(tr00+4*1+3) == T(0.) &&
0247 *(tr00+4*2+3) == T(0.) &&
0248 *(tr00+4*3+3) == T(1.) ;
0249 }
0250
0251
0252 template<typename T>
0253 inline std::string strid::Desc_( const glm::tmat4x4<T>& tr )
0254 {
0255 const T* tr00 = glm::value_ptr(tr) ;
0256 std::stringstream ss ;
0257 for(int r=0 ; r < 4 ; r++) for(int c=0 ; c < 4 ; c++)
0258 {
0259 int i = r*4 + c ;
0260 if( c == 0 ) ss << std::endl ;
0261 ss << std::fixed << std::setw(10) << std::setprecision(3) << tr00[i] << " " ;
0262 if( i == 15 ) ss << std::endl ;
0263 }
0264 std::string s = ss.str();
0265 return s ;
0266 }
0267
0268
0269 template<typename T>
0270 inline std::string strid::Desc_( const char* a_label, const char* b_label, const glm::tmat4x4<T>& a, const glm::tmat4x4<T>& b )
0271 {
0272 const T* aa = glm::value_ptr(a) ;
0273 const T* bb = glm::value_ptr(b) ;
0274 unsigned num = 2 ;
0275
0276 std::stringstream ss ;
0277
0278 ss << std::setw(10) << a_label << std::setw(40) << " " << std::setw(10) << b_label << std::endl ;
0279
0280 for(unsigned r=0 ; r < 4 ; r++)
0281 for(unsigned t=0 ; t < num ; t++)
0282 for(unsigned c=0 ; c < 4 ; c++)
0283 {
0284 const T* vv = nullptr ;
0285 switch(t)
0286 {
0287 case 0: vv = aa ; break ;
0288 case 1: vv = bb ; break ;
0289 }
0290 unsigned i = r*4 + c ;
0291 if( c == 0 && t == 0) ss << std::endl ;
0292 ss << std::fixed << std::setw(10) << std::setprecision(3) << vv[i] << " " ;
0293 if( c == 3 && t == 0) ss << std::setw(10) << " " ;
0294 if( i == 15 && t == num - 1) ss << std::endl ;
0295 }
0296 std::string s = ss.str();
0297 return s ;
0298 }
0299
0300
0301
0302 template<typename T>
0303 inline std::string strid::Desc_(
0304 const char* a_label,
0305 const char* b_label,
0306 const char* c_label,
0307 const glm::tmat4x4<T>& a,
0308 const glm::tmat4x4<T>& b,
0309 const glm::tmat4x4<T>& c
0310 )
0311 {
0312 const T* aa = glm::value_ptr(a) ;
0313 const T* bb = glm::value_ptr(b) ;
0314 const T* cc = glm::value_ptr(c) ;
0315 unsigned num = 3 ;
0316 std::stringstream ss ;
0317 ss
0318 << std::setw(10) << a_label << std::setw(40) << " "
0319 << std::setw(10) << b_label << std::setw(40) << " "
0320 << std::setw(10) << c_label << std::setw(40) << " "
0321 << std::endl
0322 ;
0323
0324 for(unsigned r=0 ; r < 4 ; r++)
0325 for(unsigned t=0 ; t < num ; t++)
0326 for(unsigned c=0 ; c < 4 ; c++)
0327 {
0328 unsigned i = r*4 + c ;
0329 const T* vv = nullptr ;
0330 switch(t)
0331 {
0332 case 0: vv = aa ; break ;
0333 case 1: vv = bb ; break ;
0334 case 2: vv = cc ; break ;
0335 }
0336 if( c == 0 && t == 0) ss << std::endl ;
0337 ss << std::fixed << std::setw(10) << std::setprecision(3) << vv[i] << " " ;
0338 if( c == 3 && t < num - 1 ) ss << std::setw(10) << " " ;
0339 if( i == 15 && t == num - 1) ss << std::endl ;
0340 }
0341 std::string s = ss.str();
0342 return s ;
0343 }
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358 template<typename T, typename S>
0359 inline std::string strid::Desc( const glm::tmat4x4<T>& tr )
0360 {
0361 glm::tvec4<S> col3 ;
0362 Decode(tr, col3);
0363
0364 bool clear = IsClear(tr);
0365
0366 std::string spc(5, ' ');
0367
0368 const T* tr00 = glm::value_ptr(tr) ;
0369 std::stringstream ss ;
0370 for(unsigned r=0 ; r < 4 ; r++) for(unsigned c=0 ; c < 4 ; c++)
0371 {
0372 unsigned i = r*4 + c ;
0373 if( c == 0 ) ss << std::endl ;
0374
0375 if( c < 3 || ( c == 3 && clear) )
0376 {
0377 ss << std::fixed << std::setw(10) << std::setprecision(3) << tr00[i] << " " ;
0378 }
0379 else
0380 {
0381 ss << spc << std::setw(16) << std::dec << col3[r] << std::dec ; break ;
0382 }
0383 if( i == 15 ) ss << std::endl ;
0384 }
0385 std::string s = ss.str();
0386 return s ;
0387 }
0388
0389 template std::string strid::Desc<double, uint64_t>(const glm::tmat4x4<double>& tr );
0390 template std::string strid::Desc<float, uint32_t>(const glm::tmat4x4<float>& tr );
0391
0392
0393
0394 inline void strid::NarrowClear( glm::tmat4x4<float>& dst_, const glm::tmat4x4<double>& src_ )
0395 {
0396 float* dst = glm::value_ptr(dst_);
0397 const double* src = glm::value_ptr(src_);
0398 for(int i=0 ; i < 16 ; i++) dst[i] = float(src[i]);
0399 Clear<float>(dst_);
0400 }
0401
0402
0403 inline void strid::NarrowDecodeClear( glm::tmat4x4<float>& dst_, glm::tvec4<int32_t>& col3_, const glm::tmat4x4<double>& src_ )
0404 {
0405 float* dst = glm::value_ptr(dst_);
0406 const double* src = glm::value_ptr(src_);
0407 for(int i=0 ; i < 16 ; i++) dst[i] = float(src[i]);
0408
0409 glm::tvec4<int64_t> dcol3 ;
0410 Decode( src_, dcol3 );
0411
0412 col3_.x = dcol3.x ;
0413 col3_.y = dcol3.y ;
0414 col3_.z = dcol3.z ;
0415 col3_.w = dcol3.w ;
0416
0417 Clear<float>(dst_);
0418 }
0419
0420
0421
0422
0423
0424
0425 inline void strid::Narrow( glm::tmat4x4<float>& dst_, const glm::tmat4x4<double>& src_ )
0426 {
0427 glm::tvec4<uint64_t> src_col3 ;
0428 Decode(src_, src_col3);
0429
0430 float* dst = glm::value_ptr(dst_);
0431 const double* src = glm::value_ptr(src_);
0432
0433 for(int r=0 ; r < 4 ; r++)
0434 for(int c=0 ; c < 4 ; c++)
0435 {
0436 int i=r*4 + c ;
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447 dst[i] = float(src[i]);
0448 }
0449
0450
0451 glm::tvec4<uint32_t> dst_col3 ;
0452 for(int r=0 ; r < 4 ; r++) dst_col3[r] = ( src_col3[r] & 0xffffffff ) ;
0453
0454 Encode(dst_, dst_col3);
0455
0456 }
0457
0458 inline void strid::NarrowClear( std::vector<glm::tmat4x4<float>>& dst_, const std::vector<glm::tmat4x4<double>>& src_ )
0459 {
0460 dst_.resize(src_.size());
0461 for(unsigned i=0 ; i < src_.size() ; i++)
0462 {
0463 const glm::tmat4x4<double>& src = src_[i] ;
0464 glm::tmat4x4<float>& dst = dst_[i] ;
0465 NarrowClear(dst, src);
0466 }
0467 }
0468
0469
0470
0471
0472
0473 inline void strid::NarrowDecodeClear( std::vector<glm::tmat4x4<float>>& dst_, std::vector<glm::tvec4<int32_t>>& col3_, const std::vector<glm::tmat4x4<double>>& src_ )
0474 {
0475 dst_.resize(src_.size());
0476 col3_.resize(src_.size());
0477
0478 for(unsigned i=0 ; i < src_.size() ; i++)
0479 {
0480 const glm::tmat4x4<double>& src = src_[i] ;
0481 glm::tmat4x4<float>& dst = dst_[i] ;
0482 glm::tvec4<int32_t>& col3 = col3_[i] ;
0483
0484 NarrowDecodeClear(dst, col3, src);
0485 }
0486 }
0487
0488
0489
0490
0491
0492
0493 inline void strid::Narrow( std::vector<glm::tmat4x4<float>>& dst_, const std::vector<glm::tmat4x4<double>>& src_ )
0494 {
0495 dst_.resize(src_.size());
0496 for(unsigned i=0 ; i < src_.size() ; i++)
0497 {
0498 const glm::tmat4x4<double>& src = src_[i] ;
0499 glm::tmat4x4<float>& dst = dst_[i] ;
0500 Narrow(dst, src);
0501 }
0502 }
0503
0504 template<typename T>
0505 inline T strid::DiffFromIdentity(const glm::tmat4x4<T>& tr)
0506 {
0507 const T* tt = glm::value_ptr(tr);
0508 T max_delta = T(0.) ;
0509 for(int r=0 ; r < 4 ; r++) for(int c=0 ; c < 4 ; c++)
0510 {
0511 int i = r*4 + c ;
0512 T id = r == c ? T(1.) : T(0.) ;
0513 T delta = std::abs( tt[i] - id ) ;
0514 if(delta > max_delta) max_delta = delta ;
0515 }
0516 return max_delta ;
0517 }
0518
0519
0520
0521
0522 template<typename T>
0523 inline void strid::Read_( glm::tmat4x4<T>& dst, const T* src )
0524 {
0525 memcpy( glm::value_ptr(dst), src, sizeof(T)*16 );
0526 }
0527
0528 template<typename T, typename S>
0529 inline void strid::Read( glm::tmat4x4<T>& dst, const S* src, bool transpose )
0530 {
0531 T* d = glm::value_ptr(dst) ;
0532 for(int r=0 ; r < 4 ; r++) for(int c=0 ; c < 4 ; c++)
0533 {
0534 int i = r*4+c ;
0535 int j = transpose ? c*4+r : i ;
0536
0537 d[j] = T(src[i]) ;
0538 }
0539 }
0540
0541