Skip to content

Commit

Permalink
Merge pull request #46 from fabioarnold/main
Browse files Browse the repository at this point in the history
Speed up `Mat4.recompose`
  • Loading branch information
kooparse authored Mar 6, 2024
2 parents 0f1a246 + 7b04d9d commit 1ab7f25
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 5 deletions.
21 changes: 16 additions & 5 deletions src/mat4.zig
Original file line number Diff line number Diff line change
Expand Up @@ -401,16 +401,27 @@ pub fn Mat4x4(comptime T: type) type {
/// The final order is T * R * S.
/// Note: `rotation` could be `Vec3` (Euler angles) or a `quat`.
pub fn recompose(translation: Vector3, rotation: anytype, scalar: Vector3) Self {
const t = Self.fromTranslate(translation);
const s = Self.fromScale(scalar);

const r = switch (@TypeOf(rotation)) {
var r = switch (@TypeOf(rotation)) {
Quaternion(T) => Quaternion(T).toMat4(rotation),
Vector3 => Self.fromEulerAngles(rotation),
else => @compileError("Recompose not implemented for " ++ @typeName(@TypeOf(rotation))),
};

return t.mul(r.mul(s));
r.data[0][0] *= scalar.x();
r.data[0][1] *= scalar.x();
r.data[0][2] *= scalar.x();
r.data[1][0] *= scalar.y();
r.data[1][1] *= scalar.y();
r.data[1][2] *= scalar.y();
r.data[2][0] *= scalar.z();
r.data[2][1] *= scalar.z();
r.data[2][2] *= scalar.z();

r.data[3][0] = translation.x();
r.data[3][1] = translation.y();
r.data[3][2] = translation.z();

return r;
}

/// Return `translation`, `rotation` and `scale` components from given matrix.
Expand Down
32 changes: 32 additions & 0 deletions src/quaternion.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const std = @import("std");
const root = @import("main.zig");
const meta = std.meta;
const generic_vector = @import("generic_vector.zig");
const mat3 = @import("mat3.zig");
const mat4 = @import("mat4.zig");
const math = std.math;
const eps_value = math.floatEps(f32);
Expand All @@ -15,6 +16,7 @@ const GenericVector = generic_vector.GenericVector;

const Vec3 = generic_vector.Vec3;
const Vec4 = generic_vector.Vec4;
const Mat3x3 = mat3.Mat3x3;
const Mat4x4 = mat4.Mat4x4;

pub const Quat = Quaternion(f32);
Expand Down Expand Up @@ -142,6 +144,36 @@ pub fn Quaternion(comptime T: type) type {
return (left.x * right.x) + (left.y * right.y) + (left.z * right.z) + (left.w * right.w);
}

/// Convert given quaternion to rotation 3x3 matrix.
fn toMat3(self: Self) Mat3x3(T) {
var result: Mat3x3(T) = undefined;

const normalized = self.norm();
const xx = normalized.x * normalized.x;
const yy = normalized.y * normalized.y;
const zz = normalized.z * normalized.z;
const xy = normalized.x * normalized.y;
const xz = normalized.x * normalized.z;
const yz = normalized.y * normalized.z;
const wx = normalized.w * normalized.x;
const wy = normalized.w * normalized.y;
const wz = normalized.w * normalized.z;

result.data[0][0] = 1 - 2 * (yy + zz);
result.data[0][1] = 2 * (xy + wz);
result.data[0][2] = 2 * (xz - wy);

result.data[1][0] = 2 * (xy - wz);
result.data[1][1] = 1 - 2 * (xx + zz);
result.data[1][2] = 2 * (yz + wx);

result.data[2][0] = 2 * (xz + wy);
result.data[2][1] = 2 * (yz - wx);
result.data[2][2] = 1 - 2 * (xx + yy);

return result;
}

/// Convert given quaternion to rotation 4x4 matrix.
/// Mostly taken from https://github.com/HandmadeMath/Handmade-Math.
pub fn toMat4(self: Self) Mat4x4(T) {
Expand Down

0 comments on commit 1ab7f25

Please sign in to comment.