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 testing = mach.testing;
|
||||||
const math = mach.math;
|
const math = mach.math;
|
||||||
const vec = @import("vec.zig");
|
const vec = @import("vec.zig");
|
||||||
|
const quat = @import("quat.zig");
|
||||||
|
|
||||||
pub fn Mat2x2(
|
pub fn Mat2x2(
|
||||||
comptime Scalar: type,
|
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.
|
/// Constructs a 2D projection matrix, aka. an orthographic projection matrix.
|
||||||
///
|
///
|
||||||
/// First, a cuboid is defined with the parameters:
|
/// 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(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)));
|
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