@@ -4246,9 +4246,9 @@ fn fftUnswizzle(input: []const F32x4, output: []F32x4) void {
4246
4246
const n = index / 2 ;
4247
4247
var addr =
4248
4248
(((@as (usize , @intCast (static .swizzle_table [n & 0xff ])) << 24 ) |
4249
- (@as (usize , @intCast (static .swizzle_table [(n >> 8 ) & 0xff ])) << 16 ) |
4250
- (@as (usize , @intCast (static .swizzle_table [(n >> 16 ) & 0xff ])) << 8 ) |
4251
- (@as (usize , @intCast (static .swizzle_table [(n >> 24 ) & 0xff ])))) >> rev32 ) |
4249
+ (@as (usize , @intCast (static .swizzle_table [(n >> 8 ) & 0xff ])) << 16 ) |
4250
+ (@as (usize , @intCast (static .swizzle_table [(n >> 16 ) & 0xff ])) << 8 ) |
4251
+ (@as (usize , @intCast (static .swizzle_table [(n >> 24 ) & 0xff ])))) >> rev32 ) |
4252
4252
((index & 1 ) * rev7 * 4 );
4253
4253
f32_output [addr ] = input [index ][0 ];
4254
4254
addr += rev7 ;
@@ -4530,6 +4530,147 @@ pub fn approxEqAbs(v0: anytype, v1: anytype, eps: f32) bool {
4530
4530
return true ;
4531
4531
}
4532
4532
4533
+ /// ==============================================================================
4534
+ ///
4535
+ /// Collection of useful functions building on top of, and extending, core zmath.
4536
+ /// https://github.com/michal-z/zig-gamedev/tree/main/libs/zmath
4537
+ ///
4538
+ /// ------------------------------------------------------------------------------
4539
+ /// 1. Matrix functions
4540
+ /// ------------------------------------------------------------------------------
4541
+ ///
4542
+ /// As an example, in a left handed Y-up system:
4543
+ /// getAxisX is equivalent to the right vector
4544
+ /// getAxisY is equivalent to the up vector
4545
+ /// getAxisZ is equivalent to the forward vector
4546
+ ///
4547
+ /// getTranslationVec(m: Mat) Vec
4548
+ /// getAxisX(m: Mat) Vec
4549
+ /// getAxisY(m: Mat) Vec
4550
+ /// getAxisZ(m: Mat) Vec
4551
+ ///
4552
+ /// ==============================================================================
4553
+ pub const util = struct {
4554
+ pub fn getTranslationVec (m : Mat ) Vec {
4555
+ var _translation = m [3 ];
4556
+ _translation [3 ] = 0 ;
4557
+ return _translation ;
4558
+ }
4559
+
4560
+ pub fn set_TranslationVec (m : * Mat , _translation : Vec ) void {
4561
+ const w = m [3 ][3 ];
4562
+ m [3 ] = _translation ;
4563
+ m [3 ][3 ] = w ;
4564
+ }
4565
+
4566
+ pub fn getScaleVec (m : Mat ) Vec {
4567
+ const scale_x = length3 (f32x4 (m [0 ][0 ], m [1 ][0 ], m [2 ][0 ], 0 ))[0 ];
4568
+ const scale_y = length3 (f32x4 (m [0 ][1 ], m [1 ][1 ], m [2 ][1 ], 0 ))[0 ];
4569
+ const scale_z = length3 (f32x4 (m [0 ][2 ], m [1 ][2 ], m [2 ][2 ], 0 ))[0 ];
4570
+ return f32x4 (scale_x , scale_y , scale_z , 0 );
4571
+ }
4572
+
4573
+ pub fn getRotationQuat (_m : Mat ) Quat {
4574
+ // Ortho normalize given matrix.
4575
+ const c1 = normalize3 (f32x4 (_m [0 ][0 ], _m [1 ][0 ], _m [2 ][0 ], 0 ));
4576
+ const c2 = normalize3 (f32x4 (_m [0 ][1 ], _m [1 ][1 ], _m [2 ][1 ], 0 ));
4577
+ const c3 = normalize3 (f32x4 (_m [0 ][2 ], _m [1 ][2 ], _m [2 ][2 ], 0 ));
4578
+ var m = _m ;
4579
+ m [0 ][0 ] = c1 [0 ];
4580
+ m [1 ][0 ] = c1 [1 ];
4581
+ m [2 ][0 ] = c1 [2 ];
4582
+ m [0 ][1 ] = c2 [0 ];
4583
+ m [1 ][1 ] = c2 [1 ];
4584
+ m [2 ][1 ] = c2 [2 ];
4585
+ m [0 ][2 ] = c3 [0 ];
4586
+ m [1 ][2 ] = c3 [1 ];
4587
+ m [2 ][2 ] = c3 [2 ];
4588
+
4589
+ // Extract rotation
4590
+ return quatFromMat (m );
4591
+ }
4592
+
4593
+ pub fn getAxisX (m : Mat ) Vec {
4594
+ return normalize3 (f32x4 (m [0 ][0 ], m [0 ][1 ], m [0 ][2 ], 0.0 ));
4595
+ }
4596
+
4597
+ pub fn getAxisY (m : Mat ) Vec {
4598
+ return normalize3 (f32x4 (m [1 ][0 ], m [1 ][1 ], m [1 ][2 ], 0.0 ));
4599
+ }
4600
+
4601
+ pub fn getAxisZ (m : Mat ) Vec {
4602
+ return normalize3 (f32x4 (m [2 ][0 ], m [2 ][1 ], m [2 ][2 ], 0.0 ));
4603
+ }
4604
+
4605
+ test "zmath.util.mat.translation" {
4606
+ // zig fmt: off
4607
+ const mat_data = [18 ]f32 {
4608
+ 1.0 ,
4609
+ 2.0 , 3.0 , 4.0 , 5.0 ,
4610
+ 6.0 , 7.0 , 8.0 , 9.0 ,
4611
+ 10.0 ,11.0 , 12.0 ,13.0 ,
4612
+ 14.0 , 15.0 , 16.0 , 17.0 ,
4613
+ 18.0 ,
4614
+ };
4615
+ // zig fmt: on
4616
+ const mat = loadMat (mat_data [1.. ]);
4617
+ try expectVecApproxEqAbs (getTranslationVec (mat ), f32x4 (14.0 , 15.0 , 16.0 , 0.0 ), 0.0001 );
4618
+ }
4619
+
4620
+ test "zmath.util.mat.scale" {
4621
+ const mat = mul (scaling (3 , 4 , 5 ), translation (6 , 7 , 8 ));
4622
+ const scale = getScaleVec (mat );
4623
+ try expectVecApproxEqAbs (scale , f32x4 (3.0 , 4.0 , 5.0 , 0.0 ), 0.0001 );
4624
+ }
4625
+
4626
+ test "zmath.util.mat.rotation" {
4627
+ const rotate_origin = matFromRollPitchYaw (0.1 , 1.2 , 2.3 );
4628
+ const mat = mul (mul (rotate_origin , scaling (3 , 4 , 5 )), translation (6 , 7 , 8 ));
4629
+ const rotate_get = getRotationQuat (mat );
4630
+ const v0 = mul (f32x4s (1 ), rotate_origin );
4631
+ const v1 = mul (f32x4s (1 ), quatToMat (rotate_get ));
4632
+ try expectVecApproxEqAbs (v0 , v1 , 0.0001 );
4633
+ }
4634
+
4635
+ test "zmath.util.mat.z_vec" {
4636
+ const degToRad = std .math .degreesToRadians ;
4637
+ var z_vec = getAxisZ (identity ());
4638
+ try expectVecApproxEqAbs (z_vec , f32x4 (0.0 , 0.0 , 1.0 , 0 ), 0.0001 );
4639
+ const rot_yaw = rotationY (degToRad (90 ));
4640
+ identity = mul (identity (), rot_yaw );
4641
+ z_vec = getAxisZ (identity ());
4642
+ try expectVecApproxEqAbs (z_vec , f32x4 (1.0 , 0.0 , 0.0 , 0 ), 0.0001 );
4643
+ }
4644
+
4645
+ test "zmath.util.mat.y_vec" {
4646
+ const degToRad = std .math .degreesToRadians ;
4647
+ var y_vec = getAxisY (identity ());
4648
+ try expectVecApproxEqAbs (y_vec , f32x4 (0.0 , 1.0 , 0.0 , 0 ), 0.01 );
4649
+ const rot_yaw = rotationY (degToRad (90 ));
4650
+ identity = mul (identity (), rot_yaw );
4651
+ y_vec = getAxisY (identity ());
4652
+ try expectVecApproxEqAbs (y_vec , f32x4 (0.0 , 1.0 , 0.0 , 0 ), 0.01 );
4653
+ const rot_pitch = rotationX (degToRad (90 ));
4654
+ identity = mul (identity (), rot_pitch );
4655
+ y_vec = getAxisY (identity ());
4656
+ try expectVecApproxEqAbs (y_vec , f32x4 (0.0 , 0.0 , 1.0 , 0 ), 0.01 );
4657
+ }
4658
+
4659
+ test "zmath.util.mat.right" {
4660
+ const degToRad = std .math .degreesToRadians ;
4661
+ var right = getAxisX (identity ());
4662
+ try expectVecApproxEqAbs (right , f32x4 (1.0 , 0.0 , 0.0 , 0 ), 0.01 );
4663
+ const rot_yaw = rotationY (degToRad (90 ));
4664
+ identity = mul (identity , rot_yaw );
4665
+ right = getAxisX (identity ());
4666
+ try expectVecApproxEqAbs (right , f32x4 (0.0 , 0.0 , -1.0 , 0 ), 0.01 );
4667
+ const rot_pitch = rotationX (degToRad (90 ));
4668
+ identity = mul (identity (), rot_pitch );
4669
+ right = getAxisX (identity ());
4670
+ try expectVecApproxEqAbs (right , f32x4 (0.0 , 1.0 , 0.0 , 0 ), 0.01 );
4671
+ }
4672
+ }; // util
4673
+
4533
4674
// ------------------------------------------------------------------------------
4534
4675
// This software is available under 2 licenses -- choose whichever you prefer.
4535
4676
// ------------------------------------------------------------------------------
0 commit comments