@@ -4246,9 +4246,9 @@ fn fftUnswizzle(input: []const F32x4, output: []F32x4) void {
42464246 const n = index / 2 ;
42474247 var addr =
42484248 (((@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 ) |
42524252 ((index & 1 ) * rev7 * 4 );
42534253 f32_output [addr ] = input [index ][0 ];
42544254 addr += rev7 ;
@@ -4530,6 +4530,147 @@ pub fn approxEqAbs(v0: anytype, v1: anytype, eps: f32) bool {
45304530 return true ;
45314531}
45324532
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+
45334674// ------------------------------------------------------------------------------
45344675// This software is available under 2 licenses -- choose whichever you prefer.
45354676// ------------------------------------------------------------------------------
0 commit comments