|
| 1 | +const std = @import("std"); |
| 2 | + |
1 | 3 | const mach = @import("../main.zig"); |
2 | 4 | const testing = mach.testing; |
3 | 5 | const math = mach.math; |
4 | 6 | const vec = @import("vec.zig"); |
| 7 | +const quat = @import("quat.zig"); |
5 | 8 |
|
6 | 9 | pub fn Mat2x2( |
7 | 10 | comptime Scalar: type, |
@@ -118,6 +121,7 @@ pub fn Mat2x2( |
118 | 121 |
|
119 | 122 | pub const mul = Shared.mul; |
120 | 123 | pub const mulVec = Shared.mulVec; |
| 124 | + pub const format = Shared.format; |
121 | 125 | }; |
122 | 126 | } |
123 | 127 |
|
@@ -258,6 +262,7 @@ pub fn Mat3x3( |
258 | 262 |
|
259 | 263 | pub const mul = Shared.mul; |
260 | 264 | pub const mulVec = Shared.mulVec; |
| 265 | + pub const format = Shared.format; |
261 | 266 | }; |
262 | 267 | } |
263 | 268 |
|
@@ -435,6 +440,22 @@ pub fn Mat4x4( |
435 | 440 | ); |
436 | 441 | } |
437 | 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 | + |
438 | 459 | /// Constructs a 2D projection matrix, aka. an orthographic projection matrix. |
439 | 460 | /// |
440 | 461 | /// First, a cuboid is defined with the parameters: |
@@ -485,6 +506,7 @@ pub fn Mat4x4( |
485 | 506 | pub const mulVec = Shared.mulVec; |
486 | 507 | pub const eql = Shared.eql; |
487 | 508 | pub const eqlApprox = Shared.eqlApprox; |
| 509 | + pub const format = Shared.format; |
488 | 510 | }; |
489 | 511 | } |
490 | 512 |
|
@@ -542,6 +564,24 @@ pub fn MatShared(comptime RowVec: type, comptime ColVec: type, comptime Matrix: |
542 | 564 | } |
543 | 565 | return true; |
544 | 566 | } |
| 567 | + |
| 568 | + /// Custom format function for all matrix types. |
| 569 | + pub inline fn format( |
| 570 | + self: Matrix, |
| 571 | + comptime fmt: []const u8, |
| 572 | + options: std.fmt.FormatOptions, |
| 573 | + writer: anytype, |
| 574 | + ) @TypeOf(writer).Error!void { |
| 575 | + const rows = @TypeOf(self).rows; |
| 576 | + try writer.print("{{", .{}); |
| 577 | + inline for (0..rows) |r| { |
| 578 | + try std.fmt.formatType(self.row(r), fmt, options, writer, 1); |
| 579 | + if (r < rows - 1) { |
| 580 | + try writer.print(", ", .{}); |
| 581 | + } |
| 582 | + } |
| 583 | + try writer.print("}}", .{}); |
| 584 | + } |
545 | 585 | }; |
546 | 586 | } |
547 | 587 |
|
@@ -1173,3 +1213,17 @@ test "projection2D_model_to_clip_space" { |
1173 | 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))); |
1174 | 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))); |
1175 | 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