Add matrix rotation by quaternion
This commit is contained in:
parent
6fd6a8fa67
commit
9749cd9a65
1 changed files with 31 additions and 0 deletions
|
|
@ -4,6 +4,7 @@ const mach = @import("../main.zig");
|
|||
const testing = mach.testing;
|
||||
const math = mach.math;
|
||||
const vec = @import("vec.zig");
|
||||
const quat = @import("quat.zig");
|
||||
|
||||
pub fn Mat2x2(
|
||||
comptime Scalar: type,
|
||||
|
|
@ -439,6 +440,22 @@ pub fn Mat4x4(
|
|||
);
|
||||
}
|
||||
|
||||
//https://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToMatrix/jay.htm
|
||||
//Requires a normalized quaternion
|
||||
pub inline fn rotateByQuaternion(quaternion: quat.Quat(T)) Matrix {
|
||||
const qx = quaternion.v.x();
|
||||
const qy = quaternion.v.y();
|
||||
const qz = quaternion.v.z();
|
||||
const qw = quaternion.v.w();
|
||||
|
||||
return Matrix.init(
|
||||
&RowVec.init(1 - 2 * qy * qy - 2 * qz * qz, 2 * qx * qy - 2 * qz * qw, 2 * qx * qz + 2 * qy * qw, 0),
|
||||
&RowVec.init(2 * qx * qy + 2 * qz * qw, 1 - 2 * qx * qx - 2 * qz * qz, 2 * qy * qz - 2 * qx * qw, 0),
|
||||
&RowVec.init(2 * qx * qz - 2 * qy * qw, 2 * qy * qz + 2 * qx * qw, 1 - 2 * qx * qx - 2 * qy * qy, 0),
|
||||
&RowVec.init(0, 0, 0, 1),
|
||||
);
|
||||
}
|
||||
|
||||
/// Constructs a 2D projection matrix, aka. an orthographic projection matrix.
|
||||
///
|
||||
/// First, a cuboid is defined with the parameters:
|
||||
|
|
@ -1196,3 +1213,17 @@ test "projection2D_model_to_clip_space" {
|
|||
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)));
|
||||
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)));
|
||||
}
|
||||
|
||||
test "quaternion_rotation" {
|
||||
const expected = math.Mat4x4.init(
|
||||
&math.vec4(0.7716905, 0.5519065, 0.3160585, 0),
|
||||
&math.vec4(-0.0782971, -0.4107276, 0.9083900, 0),
|
||||
&math.vec4(0.6311602, -0.7257425, -0.2737419, 0),
|
||||
&math.vec4(0, 0, 0, 1),
|
||||
);
|
||||
|
||||
const q = math.Quat.fromAxisAngle(math.vec3(0.9182788, 0.1770672, 0.3541344), 4.2384558);
|
||||
const result = math.Mat4x4.rotateByQuaternion(q.normalize());
|
||||
|
||||
try testing.expect(bool, true).eql(expected.eqlApprox(&result, 0.0000002));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue