File indexing completed on 2026-04-09 07:49:20
0001
0002
0003 #include "scuda.h"
0004 #include "squad.h"
0005 #include "sqat4.h"
0006 #include "saabb.h"
0007 #include "stran.h"
0008
0009 #include <cmath>
0010 #include <sstream>
0011 #include <string>
0012 #include <vector>
0013 #include <iostream>
0014 #include <iomanip>
0015
0016
0017 #include <glm/mat4x4.hpp>
0018 #include <glm/gtx/string_cast.hpp>
0019 #include <glm/gtx/transform.hpp>
0020 #include <glm/gtc/type_ptr.hpp>
0021
0022 #include <glm/gtc/random.hpp>
0023
0024 const float EPSILON = 1e-6 ;
0025
0026
0027 bool check( const float& a, const float& b, const char* msg )
0028 {
0029 float cf = std::abs(a - b) ;
0030 bool chk = cf < EPSILON ;
0031 if(!chk)
0032 std::cout
0033 << msg
0034 << " cf "
0035 << std::fixed << std::setprecision(8) << cf
0036 << " ( "
0037 << std::fixed << std::setprecision(8) << a
0038 << ","
0039 << std::fixed << std::setprecision(8) << b
0040 << ") "
0041 << std::endl
0042 ;
0043 return chk ;
0044 }
0045
0046 int check( const float* a , const float* b, unsigned num, const char* msg )
0047 {
0048 int chk = 0 ;
0049 for(unsigned i=0 ; i < num ; i++)
0050 {
0051 float fa = a[i] ;
0052 float fb = b[i] ;
0053 bool ck = check(fa, fb, msg);
0054 if(!ck) chk += 1 ;
0055 }
0056 return chk ;
0057 }
0058
0059
0060 void check( const glm::vec4& a , const glm::vec4& b, const char* msg )
0061 {
0062 bool chk = check(a.x,b.x,"x") && check(a.y,b.y,"y") && check(a.z,b.z,"z") && check(a.w,b.w,"w") ;
0063 if(!chk) std::cout << msg << std::endl ;
0064 assert(chk);
0065 }
0066 void check( const float3& a , const float3& b, const char* msg )
0067 {
0068 bool chk = check(a.x,b.x,"x") && check(a.y,b.y,"y") && check(a.z,b.z,"z") ;
0069 if(!chk) std::cout << msg << std::endl ;
0070 assert(chk);
0071 }
0072 void check( const float3& a , const glm::vec4& b, const char* msg )
0073 {
0074 bool chk = check(a.x,b.x,"x") && check(a.y,b.y,"y") && check(a.z,b.z,"z") ;
0075 if(!chk) std::cout << msg << std::endl ;
0076 assert(chk);
0077 }
0078 void check( const glm::vec4& a , const float3& b, const char* msg )
0079 {
0080 bool chk = check(a.x,b.x,"x") && check(a.y,b.y,"y") && check(a.z,b.z,"z") ;
0081 if(!chk) std::cout << msg << std::endl ;
0082 assert(chk);
0083 }
0084
0085
0086
0087
0088 struct points
0089 {
0090 std::vector<std::string> vn ;
0091 std::vector<glm::vec3> vv ;
0092 std::vector<float3> ff ;
0093
0094 void add(float x, float y, float z, const char* label )
0095 {
0096 ff.push_back(make_float3(x,y,z));
0097 vv.push_back(glm::vec3(x,y,z)) ;
0098 vn.push_back(label);
0099 }
0100
0101 void dump(const char* msg)
0102 {
0103 for(unsigned i=0 ; i < vn.size() ; i++)
0104 {
0105 std::cout
0106 << vn[i]
0107 << " vv: " << glm::to_string(vv[i])
0108 << " ff: " << ff[i]
0109 << std::endl
0110 ;
0111 }
0112 }
0113
0114
0115 void test_multiply( const float* d )
0116 {
0117 dump16(d, "d:");
0118
0119 glm::mat4 g = glm::make_mat4(d);
0120 glm::mat4 t = glm::transpose(g);
0121 std::cout << "g " << glm::to_string(g) << std::endl ;
0122 std::cout << "t " << glm::to_string(t) << std::endl ;
0123
0124 qat4 q(glm::value_ptr(g));
0125 qat4 r(glm::value_ptr(t));
0126 std::cout << "q " << q << std::endl ;
0127 std::cout << "r " << r << std::endl ;
0128
0129 float w = 1.f ;
0130
0131 for(unsigned i=0 ; i < vn.size() ; i++)
0132 {
0133 const glm::vec3& v = vv[i] ;
0134 const float3& f = ff[i] ;
0135
0136 glm::vec4 v4( v.x, v.y, v.z, w );
0137
0138
0139
0140 float3 qf = q.right_multiply(f, w) ;
0141 glm::vec4 gv = g * v4 ;
0142
0143 check(qf, gv, "qf == gv : glm/qat consistency for mat*vec ");
0144
0145
0146 float3 fr = r.left_multiply(f, w) ;
0147 glm::vec4 vt = v4 * t ;
0148
0149 check(fr, vt, "fr == vt : glm/qat consisency of vec*transposed(mat)");
0150 check(qf, fr, "qf == fr : qat consistency mat*vec == vec*transposed(mat) ");
0151 check(gv, vt, "gv == vt : glm consistency mat*vec == vec*transposed(mat)");
0152
0153
0154 float3 fq = q.left_multiply(f, w) ;
0155 glm::vec4 vg = v4 * g ;
0156
0157 check(fq, vg, "fq == vg : glm/qat consisency of vec*mat");
0158
0159
0160 float3 rf = r.right_multiply(f, w);
0161 glm::vec4 tv = t * v4 ;
0162
0163 check(rf, tv, "rf == tv : glm/qat consistency vec*mat == transposed(mat)*vec ");
0164 check(fq, rf, "fq == rf : qat consistency vec*mat == transposed(mat)*vec ");
0165 check(vg, tv, "vg == tv : glm consistency vec*mat == transposted(mat)*vec " );
0166
0167
0168 std::cout
0169 << vn[i]
0170 << " v: " << glm::to_string(v)
0171 << " gv: " << glm::to_string(gv)
0172 << " qf: " << qf
0173 << std::endl
0174 ;
0175
0176 std::cout
0177 << vn[i]
0178 << " v: " << glm::to_string(v)
0179 << " vg: " << glm::to_string(vg)
0180 << " fq: " << fq
0181 << std::endl
0182 ;
0183
0184 }
0185 }
0186
0187
0188
0189 void dump16( const float* f, const char* label)
0190 {
0191 std::cout << label << " " ;
0192 for(unsigned i=0 ; i < 16 ; i++ ) std::cout << *(f+i) << " " ;
0193 std::cout << std::endl;
0194 }
0195 };
0196
0197 glm::mat4 make_transform(float tx, float ty, float tz, float sx, float sy, float sz, float ax, float ay, float az, float degrees )
0198 {
0199 float radians = (degrees/180.f)*glm::pi<float>() ;
0200
0201 glm::mat4 m(1.f);
0202 m = glm::translate( m, glm::vec3(tx, ty, tz) ); std::cout << " t " << glm::to_string(m) << std::endl ;
0203 m = glm::rotate( m, radians, glm::vec3(ax, ay, az) ); std::cout << " rt " << glm::to_string(m) << std::endl ;
0204 m = glm::scale( m, glm::vec3(sx, sy, sz) ); std::cout << " srt " << glm::to_string(m) << std::endl ;
0205
0206 return m ;
0207 }
0208
0209 glm::mat4 make_transform_0()
0210 {
0211 float tx = 100.f ;
0212 float ty = 200.f ;
0213 float tz = 300.f ;
0214
0215 float sx = 10.f ;
0216 float sy = 10.f ;
0217 float sz = 10.f ;
0218
0219 float ax = 0.f ;
0220 float ay = 0.f ;
0221 float az = 1.f ;
0222
0223 float degrees = 45.0 ;
0224
0225 glm::mat4 srt = make_transform(tx, ty, tz, sx, sy, sz, ax, ay, az, degrees);
0226 return srt ;
0227 }
0228
0229 glm::mat4 make_transform_1()
0230 {
0231 glm::vec3 t = glm::sphericalRand(20000.f);
0232 glm::vec3 a = glm::sphericalRand(1.f);
0233
0234 glm::vec3 s(1.f,1.f,1.f );
0235 float degrees = glm::linearRand(0.f, 360.f );
0236 glm::mat4 srt = make_transform(t.x, t.y, t.z, s.x, s.y, s.z, a.x, a.y, a.z, degrees);
0237 return srt ;
0238 }
0239
0240
0241 void test_multiply()
0242 {
0243 points p ;
0244 p.add(0.f, 0.f, 0.f, "po");
0245 p.add(1.f, 0.f, 0.f, "px");
0246 p.add(0.f, 1.f, 0.f, "py");
0247 p.add(0.f, 0.f, 1.f, "pz");
0248
0249 for(unsigned i=0 ; i < 100 ; i++)
0250 {
0251 glm::vec3 r = glm::sphericalRand(20000.f);
0252 p.add( r.x, r.y, r.z, "r" );
0253 }
0254 p.dump("points.p");
0255 glm::mat4 t0 = make_transform_0();
0256 p.test_multiply( glm::value_ptr(t0) );
0257
0258
0259
0260
0261
0262
0263
0264
0265 }
0266
0267 void test_multiply_inplace()
0268 {
0269 glm::mat4 m(1.f);
0270 glm::vec3 s(1.f, 1.f, 1.f) ;
0271
0272 m = glm::scale(m, s );
0273 std::cout << glm::to_string( m) << std::endl ;
0274
0275 qat4 q(glm::value_ptr(m));
0276 float4 isect = make_float4(10.f, 10.f, 10.f, 42.f );
0277 q.right_multiply_inplace( isect, 0.f ) ;
0278 printf("isect: (%10.4f, %10.4f, %10.4f, %10.4f) \n", isect.x, isect.y, isect.z, isect.w );
0279 }
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291 void test_transform_aabb_inplace()
0292 {
0293 float tx = 100.f ;
0294 float ty = 200.f ;
0295 float tz = 300.f ;
0296
0297 glm::mat4 m(1.f);
0298 m = glm::translate(m, glm::vec3(tx, ty, tz));
0299
0300 qat4 q(glm::value_ptr(m));
0301 std::cout << q << std::endl ;
0302
0303 AABB aabb = { -100.f, -100.f, -100.f, 100.f, 100.f, 100.f } ;
0304 std::cout << "aabb " << aabb << std::endl ;
0305 q.transform_aabb_inplace((float*)&aabb);
0306 std::cout << "aabb " << aabb << std::endl ;
0307 }
0308
0309
0310 std::string desc_(const char* label, const std::vector<int>& uu )
0311 {
0312 std::stringstream ss ;
0313 ss
0314 << std::setw(10) << label
0315 << std::setw(4) << uu.size()
0316 << " ( "
0317 ;
0318
0319 for(int i=0 ; i < int(uu.size()) ; i++) ss << uu[i] << " " ;
0320 ss << " ) " ;
0321 std::string s = ss.str();
0322 return s ;
0323 }
0324
0325
0326 void test_find_unique()
0327 {
0328 std::vector<qat4> qq ;
0329
0330 qat4 a ; a.setIdentity( 1, 10, 100, 0 );
0331 qat4 b ; b.setIdentity( 2, 20, 200, 0 );
0332 qat4 c ; c.setIdentity( 3, 30, 300, 0 );
0333 qat4 d ; d.setIdentity( 4, 40, 400, 0 );
0334
0335 qq.push_back(a) ;
0336
0337 qq.push_back(b) ;
0338 qq.push_back(b) ;
0339
0340 qq.push_back(c) ;
0341 qq.push_back(c) ;
0342 qq.push_back(c) ;
0343
0344 qq.push_back(d) ;
0345 qq.push_back(d) ;
0346 qq.push_back(d) ;
0347 qq.push_back(d) ;
0348
0349
0350 std::vector<int> ins, gas, ias, idx ;
0351 qat4::find_unique(qq, ins, gas, ias, idx );
0352
0353 std::cout
0354 << desc_("ins", ins ) << std::endl
0355 << desc_("gas", gas ) << std::endl
0356 << desc_("ias", ias ) << std::endl
0357 << desc_("idx", idx ) << std::endl
0358 ;
0359
0360
0361 unsigned long long emm = 0ull ;
0362 for(unsigned i=0 ; i < ias.size() ; i++)
0363 {
0364 unsigned ias_idx = ias[i];
0365 unsigned num_ins = qat4::count_ias(qq, ias_idx, emm );
0366 std::cout
0367 << " ias_idx " << std::setw(3) << ias_idx
0368 << " num_ins " << std::setw(3) << num_ins
0369 << std::endl
0370 ;
0371 }
0372 }
0373
0374
0375 void test_right_multiply_translate()
0376 {
0377 float3 t = make_float3( 100.f, 200.f, 300.f );
0378
0379 qat4 q ;
0380 q.q3.f.x = t.x ;
0381 q.q3.f.y = t.y ;
0382 q.q3.f.z = t.z ;
0383
0384 q.setIdentity( 42, 43, 44, 45 );
0385
0386 std::cout << q << std::endl ;
0387
0388 float3 a = make_float3(0.f, 0.f, 0.f);
0389 float3 b = q.right_multiply(a, 1.f );
0390
0391 std::cout << " t " << t << std::endl ;
0392 std::cout << " a " << a << std::endl ;
0393 std::cout << " b " << b << std::endl ;
0394
0395 assert( b.x == a.x + t.x );
0396 assert( b.y == a.y + t.y );
0397 assert( b.z == a.z + t.z );
0398 }
0399
0400 void test_right_multiply_scale()
0401 {
0402 float3 s = make_float3( 1.f, 2.f, 3.f );
0403
0404 qat4 q ;
0405 q.q0.f.x = s.x ;
0406 q.q1.f.y = s.y ;
0407 q.q2.f.z = s.z ;
0408
0409 q.setIdentity( 42, 43, 44, 45 );
0410
0411 std::cout << q << std::endl ;
0412
0413 float3 a = make_float3(1.f, 1.f, 1.f);
0414 float3 b = q.right_multiply(a, 1.f );
0415
0416 std::cout << " s " << s << std::endl ;
0417 std::cout << " a " << a << std::endl ;
0418 std::cout << " b " << b << std::endl ;
0419
0420 assert( b.x == a.x*s.x );
0421 assert( b.y == a.y*s.y );
0422 assert( b.z == a.z*s.z );
0423 }
0424
0425 void test_right_multiply_rotate()
0426 {
0427 float th = M_PI/4.f ;
0428 float ct = cos(th);
0429 float st = sin(th);
0430
0431 qat4 q ;
0432 q.q0.f.x = ct ; q.q0.f.y = -st ; q.q0.f.z = 0.f ;
0433 q.q1.f.x = st ; q.q1.f.y = ct ; q.q1.f.z = 0.f ;
0434 q.q2.f.x = 0.f ; q.q2.f.y = 0.f ; q.q2.f.z = 1.f ;
0435
0436 q.setIdentity( 42, 43, 44, 45 );
0437
0438 float3 a = make_float3(0.f, 1.f, 0.f);
0439 float3 b = q.right_multiply(a, 1.f );
0440
0441 std::cout << " q " << q << std::endl ;
0442 std::cout << " a " << a << std::endl ;
0443 std::cout << " b " << b << std::endl ;
0444 }
0445
0446 void test_cube_corners()
0447 {
0448 float4 ce = make_float4( 0.f , 0.f, 0.f, 1.f );
0449 std::vector<float3> corners ;
0450 AABB::cube_corners(corners, ce);
0451
0452 for(int i=0 ; i < int(corners.size()) ; i++)
0453 {
0454 const float3& a = corners[i] ;
0455 std::cout << i << ":" << a << std::endl ;
0456 }
0457 }
0458
0459
0460
0461 void test_transform_aabb_inplace_2()
0462 {
0463 float tx = 100.f ;
0464 float ty = 0.f ;
0465 float tz = 0.f ;
0466
0467 qat4 q ;
0468 q.q3.f.x = tx ;
0469 q.q3.f.y = ty ;
0470 q.q3.f.z = tz ;
0471
0472 std::cout << q << std::endl ;
0473
0474 AABB aabb = { -100.f, -100.f, -100.f, 100.f, 100.f, 100.f } ;
0475 std::cout << "aabb " << aabb << std::endl ;
0476 q.transform_aabb_inplace((float*)&aabb);
0477 std::cout << "aabb " << aabb << std::endl ;
0478 }
0479
0480 void test_from_string()
0481 {
0482 const char* str = "(-0.585,-0.805, 0.098, 0.000) (-0.809, 0.588, 0.000, 0.000) (-0.057,-0.079,-0.995, 0.000) (1022.116,1406.822,17734.953, 1.000)" ;
0483 qat4* q = qat4::from_string(str);
0484 std::cout << q->desc('q') << std::endl ;
0485
0486 float s = 1000.f ;
0487 float3 o0 = make_float3( 0.f, 0.f, 0.f);
0488 float3 x0 = make_float3( s, 0.f, 0.f);
0489 float3 y0 = make_float3( 0.f, s, 0.f);
0490 float3 z0 = make_float3( 0.f, 0.f, s);
0491
0492 float3 o1 = q->right_multiply(o0, 1.f);
0493 float3 x1 = q->right_multiply(x0, 1.f);
0494 float3 y1 = q->right_multiply(y0, 1.f);
0495 float3 z1 = q->right_multiply(z0, 1.f);
0496
0497 std::cout << "o0 " << o0 << std::endl ;
0498 std::cout << "o1 " << o1 << std::endl ;
0499 std::cout << "x0 " << x0 << std::endl ;
0500 std::cout << "x1 " << x1 << std::endl ;
0501 std::cout << "y0 " << y0 << std::endl ;
0502 std::cout << "y1 " << y1 << std::endl ;
0503 std::cout << "z0 " << z0 << std::endl ;
0504 std::cout << "z1 " << z1 << std::endl ;
0505 }
0506
0507 void test_from_string_tr()
0508 {
0509 const char* str_0 = "(1022.116,1406.822,17734.953)" ;
0510 qat4* q0 = qat4::from_string(str_0);
0511 std::cout
0512 << " str_0 " << str_0
0513 << std::endl
0514 << q0->desc('q')
0515 << std::endl
0516 ;
0517
0518
0519 const char* str_1 = "(1022.116,1406.822,17734.953,1)" ;
0520 qat4* q1 = qat4::from_string(str_1);
0521 std::cout
0522 << " str_1 " << str_1
0523 << std::endl
0524 << q1->desc('q')
0525 << std::endl
0526 ;
0527
0528
0529 }
0530
0531
0532 void test_copy()
0533 {
0534 const char* str = "(-0.585,-0.805, 0.098, 0.000) (-0.809, 0.588, 0.000, 0.000) (-0.057,-0.079,-0.995, 0.000) (1022.116,1406.822,17734.953, 1.000)" ;
0535 qat4* q = qat4::from_string(str);
0536
0537 for(unsigned i=0 ; i < 10 ; i++ )
0538 {
0539 qat4* c = q->copy();
0540 c->add_translate( 0.f, 0.f, 1000.f*float(i) );
0541 std::cout << c->desc('c') << std::endl ;
0542 }
0543 }
0544
0545 void test_multiply_ctor()
0546 {
0547 const char* a_str = "(-0.585,-0.805, 0.098, 0.000) (-0.809, 0.588, 0.000, 0.000) (-0.057,-0.079,-0.995, 0.000) (1022.116,1406.822,17734.953, 1.000)" ;
0548 const char* b_str = "1 0 0 0 0 1 0 0 0 0 1 0 1000 0 0 1" ;
0549
0550
0551 qat4* a = qat4::from_string(a_str);
0552 glm::mat4 A = glm::make_mat4(a->cdata());
0553
0554 qat4* b = qat4::from_string(b_str);
0555 glm::mat4 B = glm::make_mat4(b->cdata());
0556
0557 qat4 ab = qat4(*a, *b, true);
0558 glm::mat4 AB = A*B ;
0559
0560 qat4 ba = qat4(*b, *a, true);
0561 glm::mat4 BA = B*A ;
0562
0563 std::cout << "AB" << glm::to_string(AB) << std::endl ;
0564 std::cout << "ab" << ab.desc(' ') << std::endl ;
0565 int chk_ab = check( glm::value_ptr(AB), ab.cdata(), 16, "AB" );
0566 std::cout << "chk_ab " << chk_ab << std::endl ;
0567
0568 std::cout << "BA" << glm::to_string(BA) << std::endl ;
0569 std::cout << "ba" << ba.desc(' ') << std::endl ;
0570 int chk_ba = check( glm::value_ptr(BA), ba.cdata(), 16, "BA" );
0571 std::cout << "chk_ba " << chk_ba << std::endl ;
0572 }
0573
0574
0575 void test_quad6_ctor()
0576 {
0577 quad6 gs ;
0578 gs.zero();
0579
0580 gs.q2.f.x = 1.f ; gs.q2.f.y = 2.f ; gs.q2.f.z = 3.f ; gs.q2.f.w = 4.f ;
0581 gs.q3.f.x = 5.f ; gs.q3.f.y = 6.f ; gs.q3.f.z = 7.f ; gs.q3.f.w = 8.f ;
0582 gs.q4.f.x = 9.f ; gs.q4.f.y = 10.f ; gs.q4.f.z = 11.f ; gs.q4.f.w = 12.f ;
0583 gs.q5.f.x = 13.f ; gs.q5.f.y = 14.f ; gs.q5.f.z = 15.f ; gs.q5.f.w = 16.f ;
0584
0585 qat4 qt(gs);
0586 std::cout << qt.desc('q') << std::endl ;
0587 }
0588
0589 void test_transform()
0590 {
0591
0592 const Tran<float>* tr = Tran<float>::make_rotate( 0.f , 0.f , 1.f , 45.f );
0593
0594 qat4 qt(tr->tdata());
0595 std::cout << "qt" << qt << std::endl ;
0596
0597 quad4 p ;
0598 p.zero();
0599
0600 p.q0.f = make_float4( 0.f, 0.f, 0.f, 1.f );
0601 p.q1.f = make_float4( 1.f, 0.f, 0.f, 0.f );
0602 p.q2.f = make_float4( 0.f, 1.f, 0.f, 0.f );
0603 p.q3.f = make_float4( 0.f, 0.f, 1.f, 0.f );
0604
0605 qt.right_multiply_inplace( p.q0.f, 1.f );
0606 qt.right_multiply_inplace( p.q1.f, 0.f );
0607 qt.right_multiply_inplace( p.q2.f, 0.f );
0608 qt.right_multiply_inplace( p.q3.f, 0.f );
0609
0610 std::cout << "p " << p << std::endl ;
0611 }
0612
0613
0614 void test_transform_from_qat4()
0615 {
0616 const char* t_str = "(-0.585,-0.805, 0.098, 0.000) (-0.809, 0.588, 0.000, 0.000) (-0.057,-0.079,-0.995, 0.000) (1022.116,1406.822,17734.953, 1.000)" ;
0617 qat4* t = qat4::from_string(t_str);
0618 const float* tdata = t->cdata();
0619
0620 glm::tmat4x4<double> T(1.);
0621 double* ptr = glm::value_ptr(T) ;
0622 for(int i=0 ; i < 16 ; i++) ptr[i] = double(tdata[i]) ;
0623
0624 glm::mat4 V = glm::inverse(T) ;
0625
0626 Tran<double>* tr = new Tran<double>(T, V);
0627 std::cout << *tr << std::endl ;
0628
0629 }
0630
0631 void test_is_identity()
0632 {
0633 qat4* a = new qat4 ;
0634 qat4* b = new qat4() ;
0635 qat4* c = qat4::identity() ;
0636
0637 std::cout
0638 << " a " << a->is_identity()
0639 << " b " << b->is_identity()
0640 << " c " << c->is_identity()
0641 << std::endl
0642 ;
0643 }
0644
0645 void test_ctor()
0646 {
0647 qat4* a = new qat4(100., 200., 300.) ;
0648 std::cout << *a << std::endl ;
0649 }
0650
0651 int main(int argc, char** argv)
0652 {
0653
0654
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664
0665
0666
0667
0668
0669
0670
0671
0672
0673
0674
0675 test_ctor();
0676
0677 return 0 ;
0678 }
0679
0680