@@ -4,6 +4,7 @@ const mach = @import("../main.zig");
4
4
const testing = mach .testing ;
5
5
const math = mach .math ;
6
6
const vec = @import ("vec.zig" );
7
+ const quat = @import ("quat.zig" );
7
8
8
9
pub fn Mat2x2 (
9
10
comptime Scalar : type ,
@@ -439,6 +440,22 @@ pub fn Mat4x4(
439
440
);
440
441
}
441
442
443
+ //https://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToMatrix/jay.htm
444
+ //Requires a normalized quaternion
445
+ pub inline fn rotateByQuaternion (quaternion : quat .Quat (T )) Matrix {
446
+ const qx = quaternion .v .x ();
447
+ const qy = quaternion .v .y ();
448
+ const qz = quaternion .v .z ();
449
+ const qw = quaternion .v .w ();
450
+
451
+ return Matrix .init (
452
+ & RowVec .init (1 - 2 * qy * qy - 2 * qz * qz , 2 * qx * qy - 2 * qz * qw , 2 * qx * qz + 2 * qy * qw , 0 ),
453
+ & RowVec .init (2 * qx * qy + 2 * qz * qw , 1 - 2 * qx * qx - 2 * qz * qz , 2 * qy * qz - 2 * qx * qw , 0 ),
454
+ & RowVec .init (2 * qx * qz - 2 * qy * qw , 2 * qy * qz + 2 * qx * qw , 1 - 2 * qx * qx - 2 * qy * qy , 0 ),
455
+ & RowVec .init (0 , 0 , 0 , 1 ),
456
+ );
457
+ }
458
+
442
459
/// Constructs a 2D projection matrix, aka. an orthographic projection matrix.
443
460
///
444
461
/// First, a cuboid is defined with the parameters:
@@ -1196,3 +1213,17 @@ test "projection2D_model_to_clip_space" {
1196
1213
try testing .expect (math .Vec4 , math .vec4 (1 , 0 , 1 , 1 )).eql (mvp .mul (& math .Mat4x4 .rotateY (math .degreesToRadians (90 ))).mulVec (& math .vec4 (0 , 0 , 50 , 1 )));
1197
1214
try testing .expect (math .Vec4 , math .vec4 (0 , 0 , 0.5 , 1 )).eql (mvp .mul (& math .Mat4x4 .rotateZ (math .degreesToRadians (90 ))).mulVec (& math .vec4 (0 , 0 , 50 , 1 )));
1198
1215
}
1216
+
1217
+ test "quaternion_rotation" {
1218
+ const expected = math .Mat4x4 .init (
1219
+ & math .vec4 (0.7716905 , 0.5519065 , 0.3160585 , 0 ),
1220
+ & math .vec4 (-0.0782971 , -0.4107276 , 0.9083900 , 0 ),
1221
+ & math .vec4 (0.6311602 , -0.7257425 , -0.2737419 , 0 ),
1222
+ & math .vec4 (0 , 0 , 0 , 1 ),
1223
+ );
1224
+
1225
+ const q = math .Quat .fromAxisAngle (math .vec3 (0.9182788 , 0.1770672 , 0.3541344 ), 4.2384558 );
1226
+ const result = math .Mat4x4 .rotateByQuaternion (q .normalize ());
1227
+
1228
+ try testing .expect (bool , true ).eql (expected .eqlApprox (& result , 0.0000002 ));
1229
+ }
0 commit comments