From e01947068718cad15ac3f5fa0dce97059d9157aa Mon Sep 17 00:00:00 2001 From: Szymon Nowakowski Date: Sun, 4 Jan 2026 22:43:44 +0100 Subject: [PATCH] Reorganize and fix --- packages/vecmath/src/matrices/Matrix3x2.zig | 51 ++----- packages/vecmath/src/matrices/Matrix3x2x8.zig | 34 ----- packages/vecmath/src/matrices/Matrix4x4.zig | 125 +++--------------- packages/vecmath/src/matrices/Matrix4x4x8.zig | 105 +++++++-------- packages/vecmath/src/rotors/Complex.zig | 2 +- packages/vecmath/src/rotors/Complex_x8.zig | 2 +- packages/vecmath/src/rotors/Quaternion.zig | 12 +- packages/vecmath/src/rotors/Quaternion_x8.zig | 2 +- packages/vecmath/src/trig.zig | 16 +-- packages/vecmath/src/vectors/Vector2.zig | 35 +++++ packages/vecmath/src/vectors/Vector2x8.zig | 28 ++++ packages/vecmath/src/vectors/Vector3.zig | 46 +++++++ packages/vecmath/src/vectors/Vector3x8.zig | 32 +++++ packages/vecmath/src/vectors/Vector4.zig | 18 +++ packages/vecmath/src/vectors/Vector4x8.zig | 18 +++ 15 files changed, 270 insertions(+), 256 deletions(-) diff --git a/packages/vecmath/src/matrices/Matrix3x2.zig b/packages/vecmath/src/matrices/Matrix3x2.zig index 7cd6048..1b7fb13 100644 --- a/packages/vecmath/src/matrices/Matrix3x2.zig +++ b/packages/vecmath/src/matrices/Matrix3x2.zig @@ -176,40 +176,6 @@ pub const Matrix3x2 = extern struct { }; } - // --- TRANSFORM ----------------------------------------------------------- - - // TODO Move to vm.Vector2 - pub inline fn transformPoint(self: Matrix3x2, p: vm.Vector2) vm.Vector2 { - return .{ - .x = p.x * self.ix + p.y * self.jx + self.tx, - .y = p.x * self.iy + p.y * self.jy + self.ty, - }; - } - - // TODO Move to vm.Vector2x8 - pub inline fn transformPoint_x8(self: Matrix3x2, p: vm.Vector2x8) vm.Vector2x8 { - return .{ - .x = p.x * vm.ps(self.ix) + p.y * vm.ps(self.jx) + vm.ps(self.tx), - .y = p.x * vm.ps(self.iy) + p.y * vm.ps(self.jy) + vm.ps(self.ty), - }; - } - - // TODO Move to vm.Vector2 - pub inline fn transformVector(self: Matrix3x2, v: vm.Vector2) vm.Vector2 { - return .{ - .x = v.x * self.ix + v.y * self.jx, - .y = v.x * self.iy + v.y * self.jy, - }; - } - - // TODO Move to vm.Vector2x8 - pub inline fn transformVector_x8(self: Matrix3x2, v: vm.Vector2x8) vm.Vector2x8 { - return .{ - .x = v.x * vm.ps(self.ix) + v.y * vm.ps(self.jx), - .y = v.x * vm.ps(self.iy) + v.y * vm.ps(self.jy), - }; - } - // --- COMPOSE ------------------------------------------------------------- pub inline fn mulMatrix(self: Matrix3x2, other: Matrix3x2) Matrix3x2 { @@ -223,15 +189,14 @@ pub const Matrix3x2 = extern struct { }; } - pub inline fn mulMatrix_x8(self: Matrix3x2, other: vm.Matrix3x2x8) vm.Matrix3x2 { - return .{ - .ix = other.ix * vm.ps(self.ix) + other.iy * vm.ps(self.jx), - .iy = other.ix * vm.ps(self.iy) + other.iy * vm.ps(self.jy), - .jx = other.jx * vm.ps(self.ix) + other.jy * vm.ps(self.jx), - .jy = other.jx * vm.ps(self.iy) + other.jy * vm.ps(self.jy), - .tx = other.tx * vm.ps(self.ix) + other.ty * vm.ps(self.jx) + vm.ps(self.tx), - .ty = other.tx * vm.ps(self.iy) + other.ty * vm.ps(self.jy) + vm.ps(self.ty), - }; + test mulMatrix { + try std.testing.expectEqual( + init(121, 438, 131, 474, 162, 581), + mulMatrix( + init(2, 7, 3, 11, 5, 13), + init(17, 29, 19, 31, 23, 37), + ), + ); } // INVERSION DERIVATION diff --git a/packages/vecmath/src/matrices/Matrix3x2x8.zig b/packages/vecmath/src/matrices/Matrix3x2x8.zig index 4bd189d..e20a600 100644 --- a/packages/vecmath/src/matrices/Matrix3x2x8.zig +++ b/packages/vecmath/src/matrices/Matrix3x2x8.zig @@ -340,40 +340,6 @@ pub const Matrix3x2x8 = struct { }; } - // --- TRANSFORM ----------------------------------------------------------- - - // TODO Move to vm.Vector2x8 - pub inline fn transformPoint(self: Matrix3x2x8, p: vm.Vector2x8) vm.Vector2x8 { - return .{ - .x = p.x * self.ix + p.y * self.jx + self.tx, - .y = p.x * self.iy + p.y * self.jy + self.ty, - }; - } - - // TODO Move to vm.Vector2x8 - pub inline fn transformPointSingle(self: Matrix3x2x8, p: vm.Vector2) vm.Vector2x8 { - return .{ - .x = vm.ps(p.x) * self.ix + vm.ps(p.y) * self.jx + self.tx, - .y = vm.ps(p.x) * self.iy + vm.ps(p.y) * self.jy + self.ty, - }; - } - - // TODO Move to vm.Vector2x8 - pub inline fn transformVector(self: Matrix3x2x8, v: vm.Vector2x8) vm.Vector2x8 { - return .{ - .x = v.x * self.ix + v.y * self.jx, - .y = v.x * self.iy + v.y * self.jy, - }; - } - - // TODO Move to vm.Vector2x8 - pub inline fn transformVectorSingle(self: Matrix3x2x8, v: vm.Vector2) vm.Vector2x8 { - return .{ - .x = vm.ps(v.x) * self.ix + vm.ps(v.y) * self.jx, - .y = vm.ps(v.x) * self.iy + vm.ps(v.y) * self.jy, - }; - } - // --- COMPOSE ------------------------------------------------------------- pub inline fn mulMatrix(self: Matrix3x2x8, other: Matrix3x2x8) Matrix3x2x8 { diff --git a/packages/vecmath/src/matrices/Matrix4x4.zig b/packages/vecmath/src/matrices/Matrix4x4.zig index 615ad81..0b45200 100644 --- a/packages/vecmath/src/matrices/Matrix4x4.zig +++ b/packages/vecmath/src/matrices/Matrix4x4.zig @@ -83,6 +83,20 @@ pub const Matrix4x4 = extern struct { }; } + test initRotation { + const q = vm.Quaternion.initRotation(.XY, 0.5); + const m = initRotation(q); + + try std.testing.expectEqual(init( + // zig fmt: off + -1, 0, 0, 0, + 0, -1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1, + // zig fmt: on + ), m); + } + pub inline fn initScale(s: vm.Vector3) Matrix4x4 { return .{ // zig fmt: off @@ -261,64 +275,6 @@ pub const Matrix4x4 = extern struct { }; } - // --- TRANSFORM ----------------------------------------------------------- - - // TODO Move to vm.Vector3 - pub inline fn transformPoint(self: Matrix4x4, p: vm.Vector3) vm.Vector3 { - return .{ - .x = p.x * self.ix + p.y * self.jx + p.z * self.kx + self.tx, - .y = p.x * self.iy + p.y * self.jy + p.z * self.ky + self.ty, - .z = p.x * self.iz + p.y * self.jz + p.z * self.kz + self.tz, - }; - } - - // TODO Move to vm.Vector3x8 - pub inline fn transformPoint_x8(self: Matrix4x4, p: vm.Vector3x8) vm.Vector3x8 { - return .{ - .x = p.x * vm.ps(self.ix) + p.y * vm.ps(self.jx) + p.z * vm.ps(self.kx) + vm.ps(self.tx), - .y = p.x * vm.ps(self.iy) + p.y * vm.ps(self.jy) + p.z * vm.ps(self.ky) + vm.ps(self.ty), - .z = p.x * vm.ps(self.iz) + p.y * vm.ps(self.jz) + p.z * vm.ps(self.kz) + vm.ps(self.tz), - }; - } - - // TODO Move to vm.Vector3 - pub inline fn transformVector(self: Matrix4x4, v: vm.Vector3) vm.Vector3 { - return .{ - .x = v.x * self.ix + v.y * self.jx + v.z * self.kx, - .y = v.x * self.iy + v.y * self.jy + v.z * self.ky, - .z = v.x * self.iz + v.y * self.jz + v.z * self.kz, - }; - } - - // TODO Move to vm.Vector3x8 - pub inline fn transformVector_x8(self: Matrix4x4, v: vm.Vector3x8) vm.Vector3x8 { - return .{ - .x = v.x * vm.ps(self.ix) + v.y * vm.ps(self.jx) + v.z * vm.ps(self.kx), - .y = v.x * vm.ps(self.iy) + v.y * vm.ps(self.jy) + v.z * vm.ps(self.ky), - .z = v.x * vm.ps(self.iz) + v.y * vm.ps(self.jz) + v.z * vm.ps(self.kz), - }; - } - - // TODO Move to vm.Vector4 - pub inline fn transformHomogeneous(self: Matrix4x4, h: vm.Vector4) vm.Vector4 { - return .{ - .x = h.x * self.ix + h.y * self.jx + h.z * self.kx + h.w * self.tx, - .y = h.x * self.iy + h.y * self.jy + h.z * self.ky + h.w * self.ty, - .z = h.x * self.iz + h.y * self.jz + h.z * self.kz + h.w * self.tz, - .w = h.x * self.iw + h.y * self.jw + h.z * self.kw + h.w * self.tw, - }; - } - - // TODO Move to vm.Vector4x8 - pub inline fn transformHomogeneous_x8(self: Matrix4x4, h: vm.Vector4x8) vm.Vector4x8 { - return .{ - .x = h.x * vm.ps(self.ix) + h.y * vm.ps(self.jx) + h.z * vm.ps(self.kx) + h.w * vm.ps(self.tx), - .y = h.x * vm.ps(self.iy) + h.y * vm.ps(self.jy) + h.z * vm.ps(self.ky) + h.w * vm.ps(self.ty), - .z = h.x * vm.ps(self.iz) + h.y * vm.ps(self.jz) + h.z * vm.ps(self.kz) + h.w * vm.ps(self.tz), - .w = h.x * vm.ps(self.iw) + h.y * vm.ps(self.jw) + h.z * vm.ps(self.kw) + h.w * vm.ps(self.tw), - }; - } - // --- COMPOSE ------------------------------------------------------------- /// The caller asserts that W rows of all matrices are equal to [0 0 0 1]. @@ -338,38 +294,13 @@ pub const Matrix4x4 = extern struct { .ky = other.kx * self.iy + other.ky * self.jy + other.kz * self.ky, .kz = other.kx * self.iz + other.ky * self.jz + other.kz * self.kz, .kw = 0, - .tx = other.tx * self.tx + other.ty * self.jx + other.tz * self.kx + self.tx, - .ty = other.tx * self.ty + other.ty * self.jy + other.tz * self.ky + self.ty, - .tz = other.tx * self.tz + other.ty * self.jz + other.tz * self.kz + self.tz, + .tx = other.tx * self.ix + other.ty * self.jx + other.tz * self.kx + self.tx, + .ty = other.tx * self.iy + other.ty * self.jy + other.tz * self.ky + self.ty, + .tz = other.tx * self.iz + other.ty * self.jz + other.tz * self.kz + self.tz, .tw = 1, }; } - // TODO Move to vm.Matrix4x4x8 - /// The caller asserts that W rows of all matrices are equal to [0 0 0 1]. - pub fn mulMatrixAffine_x8(self: Matrix4x4, other: vm.Matrix4x4x8) vm.Matrix4x4x8 { - std.debug.assert(self.iw == 0 and self.jw == 0 and self.kw == 0 and self.tw == 1); - std.debug.assert(@reduce(.And, (other.iw == vm.ps(0)) & (other.jw == vm.ps(0)) & (other.kw == vm.ps(0)) & (other.tw == vm.ps(1)))); - return .{ - .ix = other.ix * vm.ps(self.ix) + other.iy * vm.ps(self.jx) + other.iz * vm.ps(self.kx), - .iy = other.ix * vm.ps(self.iy) + other.iy * vm.ps(self.jy) + other.iz * vm.ps(self.ky), - .iz = other.ix * vm.ps(self.iz) + other.iy * vm.ps(self.jz) + other.iz * vm.ps(self.kz), - .iw = vm.ps(0), - .jx = other.jx * vm.ps(self.ix) + other.jy * vm.ps(self.jx) + other.jz * vm.ps(self.kx), - .jy = other.jx * vm.ps(self.iy) + other.jy * vm.ps(self.jy) + other.jz * vm.ps(self.ky), - .jz = other.jx * vm.ps(self.iz) + other.jy * vm.ps(self.jz) + other.jz * vm.ps(self.kz), - .jw = vm.ps(0), - .kx = other.kx * vm.ps(self.ix) + other.ky * vm.ps(self.jx) + other.kz * vm.ps(self.kx), - .ky = other.kx * vm.ps(self.iy) + other.ky * vm.ps(self.jy) + other.kz * vm.ps(self.ky), - .kz = other.kx * vm.ps(self.iz) + other.ky * vm.ps(self.jz) + other.kz * vm.ps(self.kz), - .kw = vm.ps(0), - .tx = other.tx * vm.ps(self.tx) + other.ty * vm.ps(self.jx) + other.tz * vm.ps(self.kx) + vm.ps(self.tx), - .ty = other.tx * vm.ps(self.ty) + other.ty * vm.ps(self.jy) + other.tz * vm.ps(self.ky) + vm.ps(self.ty), - .tz = other.tx * vm.ps(self.tz) + other.ty * vm.ps(self.jz) + other.tz * vm.ps(self.kz) + vm.ps(self.tz), - .tw = vm.ps(1), - }; - } - pub fn mulMatrixFull(self: Matrix4x4, other: Matrix4x4) Matrix4x4 { return .{ .ix = other.ix * self.ix + other.iy * self.jx + other.iz * self.kx + other.iw * self.tx, @@ -391,28 +322,6 @@ pub const Matrix4x4 = extern struct { }; } - // TODO Move to vm.Matrix4x4x8 - pub fn mulMatrixFull_x8(self: Matrix4x4, other: vm.Matrix4x4x8) vm.Matrix4x4x8 { - return .{ - .ix = other.ix * vm.ps(self.ix) + other.iy * vm.ps(self.jx) + other.iz * vm.ps(self.kx) + other.iw * vm.ps(self.tx), - .iy = other.ix * vm.ps(self.iy) + other.iy * vm.ps(self.jy) + other.iz * vm.ps(self.ky) + other.iw * vm.ps(self.ty), - .iz = other.ix * vm.ps(self.iz) + other.iy * vm.ps(self.jz) + other.iz * vm.ps(self.kz) + other.iw * vm.ps(self.tz), - .iw = other.ix * vm.ps(self.iw) + other.iy * vm.ps(self.jw) + other.iz * vm.ps(self.kw) + other.iw * vm.ps(self.tw), - .jx = other.jx * vm.ps(self.ix) + other.jy * vm.ps(self.jx) + other.jz * vm.ps(self.kx) + other.jw * vm.ps(self.tx), - .jy = other.jx * vm.ps(self.iy) + other.jy * vm.ps(self.jy) + other.jz * vm.ps(self.ky) + other.jw * vm.ps(self.ty), - .jz = other.jx * vm.ps(self.iz) + other.jy * vm.ps(self.jz) + other.jz * vm.ps(self.kz) + other.jw * vm.ps(self.tz), - .jw = other.jx * vm.ps(self.iw) + other.jy * vm.ps(self.jw) + other.jz * vm.ps(self.kw) + other.jw * vm.ps(self.tw), - .kx = other.kx * vm.ps(self.ix) + other.ky * vm.ps(self.jx) + other.kz * vm.ps(self.kx) + other.kw * vm.ps(self.tx), - .ky = other.kx * vm.ps(self.iy) + other.ky * vm.ps(self.jy) + other.kz * vm.ps(self.ky) + other.kw * vm.ps(self.ty), - .kz = other.kx * vm.ps(self.iz) + other.ky * vm.ps(self.jz) + other.kz * vm.ps(self.kz) + other.kw * vm.ps(self.tz), - .kw = other.kx * vm.ps(self.iw) + other.ky * vm.ps(self.jw) + other.kz * vm.ps(self.kw) + other.kw * vm.ps(self.tw), - .tx = other.tx * vm.ps(self.ix) + other.ty * vm.ps(self.jx) + other.tz * vm.ps(self.kx) + other.tw * vm.ps(self.tx), - .ty = other.tx * vm.ps(self.iy) + other.ty * vm.ps(self.jy) + other.tz * vm.ps(self.ky) + other.tw * vm.ps(self.ty), - .tz = other.tx * vm.ps(self.iz) + other.ty * vm.ps(self.jz) + other.tz * vm.ps(self.kz) + other.tw * vm.ps(self.tz), - .tw = other.tx * vm.ps(self.iw) + other.ty * vm.ps(self.jw) + other.tz * vm.ps(self.kw) + other.tw * vm.ps(self.tw), - }; - } - // INVERSION DERIVATION (affine and orthonormal case) // // We assume the matrix looks like so: diff --git a/packages/vecmath/src/matrices/Matrix4x4x8.zig b/packages/vecmath/src/matrices/Matrix4x4x8.zig index 95c74f7..fee4834 100644 --- a/packages/vecmath/src/matrices/Matrix4x4x8.zig +++ b/packages/vecmath/src/matrices/Matrix4x4x8.zig @@ -505,64 +505,6 @@ pub const Matrix4x4x8 = extern struct { }; } - // --- TRANSFORM ----------------------------------------------------------- - - // TODO Move to vm.Vector3x8 - pub inline fn transformPoint(self: Matrix4x4x8, p: vm.Vector3x8) vm.Vector3x8 { - return .{ - .x = p.x * self.ix + p.y * self.jx + p.z * self.kx + self.tx, - .y = p.x * self.iy + p.y * self.jy + p.z * self.ky + self.ty, - .z = p.x * self.iz + p.y * self.jz + p.z * self.kz + self.tz, - }; - } - - // TODO Move to vm.Vector3x8 - pub inline fn transformPointSingle(self: Matrix4x4x8, p: vm.Vector3) vm.Vector3x8 { - return .{ - .x = vm.ps(p.x) * self.ix + vm.ps(p.y) * self.jx + vm.ps(p.z) * self.kx + self.tx, - .y = vm.ps(p.x) * self.iy + vm.ps(p.y) * self.jy + vm.ps(p.z) * self.ky + self.ty, - .z = vm.ps(p.x) * self.iz + vm.ps(p.y) * self.jz + vm.ps(p.z) * self.kz + self.tz, - }; - } - - // TODO Move to vm.Vector3x8 - pub inline fn transformVector(self: Matrix4x4x8, v: vm.Vector3x8) vm.Vector3x8 { - return .{ - .x = v.x * self.ix + v.y * self.jx + v.z * self.kx, - .y = v.x * self.iy + v.y * self.jy + v.z * self.ky, - .z = v.x * self.iz + v.y * self.jz + v.z * self.kz, - }; - } - - // TODO Move to vm.Vector3x8 - pub inline fn transformVectorSingle(self: Matrix4x4x8, v: vm.Vector3) vm.Vector3x8 { - return .{ - .x = vm.ps(v.x) * self.ix + vm.ps(v.y) * self.jx + vm.ps(v.z) * self.kx, - .y = vm.ps(v.x) * self.iy + vm.ps(v.y) * self.jy + vm.ps(v.z) * self.ky, - .z = vm.ps(v.x) * self.iz + vm.ps(v.y) * self.jz + vm.ps(v.z) * self.kz, - }; - } - - // TODO Move to vm.Vector4x8 - pub inline fn transformHomogeneous(self: Matrix4x4x8, h: vm.Vector4x8) vm.Vector4x8 { - return .{ - .x = h.x * self.ix + h.y * self.jx + h.z * self.kx + h.w * self.tx, - .y = h.x * self.iy + h.y * self.jy + h.z * self.ky + h.w * self.ty, - .z = h.x * self.iz + h.y * self.jz + h.z * self.kz + h.w * self.tz, - .w = h.x * self.iw + h.y * self.jw + h.z * self.kw + h.w * self.tw, - }; - } - - // TODO Move to vm.Vector4x8 - pub inline fn transformHomogeneousSingle(self: Matrix4x4x8, h: vm.Vector4) vm.Vector4x8 { - return .{ - .x = vm.ps(h.x) * self.ix + vm.ps(h.y) * self.jx + vm.ps(h.z) * self.kx + vm.ps(h.w) * self.tx, - .y = vm.ps(h.x) * self.iy + vm.ps(h.y) * self.jy + vm.ps(h.z) * self.ky + vm.ps(h.w) * self.ty, - .z = vm.ps(h.x) * self.iz + vm.ps(h.y) * self.jz + vm.ps(h.z) * self.kz + vm.ps(h.w) * self.tz, - .w = vm.ps(h.x) * self.iw + vm.ps(h.y) * self.jw + vm.ps(h.z) * self.kw + vm.ps(h.w) * self.tw, - }; - } - // --- COMPOSE ------------------------------------------------------------- /// The caller asserts that W rows of all matrices are equal to [0 0 0 1]. @@ -590,7 +532,7 @@ pub const Matrix4x4x8 = extern struct { } /// The caller asserts that W rows of all matrices are equal to [0 0 0 1]. - pub fn mulMatrixAffineSingle(self: Matrix4x4x8, other: vm.Matrix4x4) vm.Matrix4x4x8 { + pub fn mulMatrixAffineSingle(self: Matrix4x4x8, other: vm.Matrix4x4) Matrix4x4x8 { std.debug.assert(@reduce(.And, (self.iw == vm.ps(0)) & (self.jw == vm.ps(0)) & (self.kw == vm.ps(0)) & (self.tw == vm.ps(1)))); std.debug.assert(other.iw == 0 and other.jw == 0 and other.kw == 0 and other.tw == 1); return .{ @@ -613,6 +555,30 @@ pub const Matrix4x4x8 = extern struct { }; } + /// The caller asserts that W rows of all matrices are equal to [0 0 0 1]. + pub fn premulMatrixAffineSingle(self: Matrix4x4x8, other: vm.Matrix4x4) Matrix4x4x8 { + std.debug.assert(@reduce(.And, (self.iw == vm.ps(0)) & (self.jw == vm.ps(0)) & (self.kw == vm.ps(0)) & (self.tw == vm.ps(1)))); + std.debug.assert(other.iw == 0 and other.jw == 0 and other.kw == 0 and other.tw == 1); + return .{ + .ix = self.ix * vm.ps(other.ix) + self.iy * vm.ps(other.jx) + self.iz * vm.ps(other.kx), + .iy = self.ix * vm.ps(other.iy) + self.iy * vm.ps(other.jy) + self.iz * vm.ps(other.ky), + .iz = self.ix * vm.ps(other.iz) + self.iy * vm.ps(other.jz) + self.iz * vm.ps(other.kz), + .iw = vm.ps(0), + .jx = self.jx * vm.ps(other.ix) + self.jy * vm.ps(other.jx) + self.jz * vm.ps(other.kx), + .jy = self.jx * vm.ps(other.iy) + self.jy * vm.ps(other.jy) + self.jz * vm.ps(other.ky), + .jz = self.jx * vm.ps(other.iz) + self.jy * vm.ps(other.jz) + self.jz * vm.ps(other.kz), + .jw = vm.ps(0), + .kx = self.kx * vm.ps(other.ix) + self.ky * vm.ps(other.jx) + self.kz * vm.ps(other.kx), + .ky = self.kx * vm.ps(other.iy) + self.ky * vm.ps(other.jy) + self.kz * vm.ps(other.ky), + .kz = self.kx * vm.ps(other.iz) + self.ky * vm.ps(other.jz) + self.kz * vm.ps(other.kz), + .kw = vm.ps(0), + .tx = self.tx * vm.ps(other.ix) + self.ty * vm.ps(other.jx) + self.tz * vm.ps(other.kx) + vm.ps(other.tx), + .ty = self.tx * vm.ps(other.iy) + self.ty * vm.ps(other.jy) + self.tz * vm.ps(other.ky) + vm.ps(other.ty), + .tz = self.tx * vm.ps(other.iz) + self.ty * vm.ps(other.jz) + self.tz * vm.ps(other.kz) + vm.ps(other.tz), + .tw = vm.ps(1), + }; + } + pub fn mulMatrixFull(self: Matrix4x4x8, other: Matrix4x4x8) Matrix4x4x8 { return .{ .ix = other.ix * self.ix + other.iy * self.jx + other.iz * self.kx + other.iw * self.tx, @@ -655,6 +621,27 @@ pub const Matrix4x4x8 = extern struct { }; } + pub fn premulMatrixFull(self: Matrix4x4x8, other: vm.Matrix4x4) Matrix4x4x8 { + return .{ + .ix = self.ix * vm.ps(other.ix) + self.iy * vm.ps(other.jx) + self.iz * vm.ps(other.kx) + self.iw * vm.ps(other.tx), + .iy = self.ix * vm.ps(other.iy) + self.iy * vm.ps(other.jy) + self.iz * vm.ps(other.ky) + self.iw * vm.ps(other.ty), + .iz = self.ix * vm.ps(other.iz) + self.iy * vm.ps(other.jz) + self.iz * vm.ps(other.kz) + self.iw * vm.ps(other.tz), + .iw = self.ix * vm.ps(other.iw) + self.iy * vm.ps(other.jw) + self.iz * vm.ps(other.kw) + self.iw * vm.ps(other.tw), + .jx = self.jx * vm.ps(other.ix) + self.jy * vm.ps(other.jx) + self.jz * vm.ps(other.kx) + self.jw * vm.ps(other.tx), + .jy = self.jx * vm.ps(other.iy) + self.jy * vm.ps(other.jy) + self.jz * vm.ps(other.ky) + self.jw * vm.ps(other.ty), + .jz = self.jx * vm.ps(other.iz) + self.jy * vm.ps(other.jz) + self.jz * vm.ps(other.kz) + self.jw * vm.ps(other.tz), + .jw = self.jx * vm.ps(other.iw) + self.jy * vm.ps(other.jw) + self.jz * vm.ps(other.kw) + self.jw * vm.ps(other.tw), + .kx = self.kx * vm.ps(other.ix) + self.ky * vm.ps(other.jx) + self.kz * vm.ps(other.kx) + self.kw * vm.ps(other.tx), + .ky = self.kx * vm.ps(other.iy) + self.ky * vm.ps(other.jy) + self.kz * vm.ps(other.ky) + self.kw * vm.ps(other.ty), + .kz = self.kx * vm.ps(other.iz) + self.ky * vm.ps(other.jz) + self.kz * vm.ps(other.kz) + self.kw * vm.ps(other.tz), + .kw = self.kx * vm.ps(other.iw) + self.ky * vm.ps(other.jw) + self.kz * vm.ps(other.kw) + self.kw * vm.ps(other.tw), + .tx = self.tx * vm.ps(other.ix) + self.ty * vm.ps(other.jx) + self.tz * vm.ps(other.kx) + self.tw * vm.ps(other.tx), + .ty = self.tx * vm.ps(other.iy) + self.ty * vm.ps(other.jy) + self.tz * vm.ps(other.ky) + self.tw * vm.ps(other.ty), + .tz = self.tx * vm.ps(other.iz) + self.ty * vm.ps(other.jz) + self.tz * vm.ps(other.kz) + self.tw * vm.ps(other.tz), + .tw = self.tx * vm.ps(other.iw) + self.ty * vm.ps(other.jw) + self.tz * vm.ps(other.kw) + self.tw * vm.ps(other.tw), + }; + } + pub fn inverseOrthonormal(self: Matrix4x4x8) Matrix4x4x8 { std.debug.assert(@reduce(.And, (self.iw == vm.ps(0)) & (self.jw == vm.ps(0)) & (self.kw == vm.ps(0)) & (self.tw == vm.ps(1)))); const ix = self.ix; diff --git a/packages/vecmath/src/rotors/Complex.zig b/packages/vecmath/src/rotors/Complex.zig index 685e90d..3d053dd 100644 --- a/packages/vecmath/src/rotors/Complex.zig +++ b/packages/vecmath/src/rotors/Complex.zig @@ -91,7 +91,7 @@ pub const Complex = extern struct { } pub inline fn inverseUnit(self: Complex) Complex { - std.debug.assert(@abs(self.mag() - 1.0) <= 0x1p-10); + std.debug.assert(@abs(self.mag() - 1.0) <= 0x1p-5); return .{ .re = self.re, .im = -self.im, diff --git a/packages/vecmath/src/rotors/Complex_x8.zig b/packages/vecmath/src/rotors/Complex_x8.zig index 461e824..dfc64b9 100644 --- a/packages/vecmath/src/rotors/Complex_x8.zig +++ b/packages/vecmath/src/rotors/Complex_x8.zig @@ -155,7 +155,7 @@ pub const Complex_x8 = struct { } pub inline fn inverseUnit(self: Complex_x8) Complex_x8 { - std.debug.assert(@reduce(.And, @abs(self.mag() - vm.ps(1.0)) <= vm.ps(0x1p-10))); + std.debug.assert(@reduce(.And, @abs(self.mag() - vm.ps(1.0)) <= vm.ps(0x1p-5))); return .{ .re = self.re, .im = -self.im, diff --git a/packages/vecmath/src/rotors/Quaternion.zig b/packages/vecmath/src/rotors/Quaternion.zig index d014461..ff74894 100644 --- a/packages/vecmath/src/rotors/Quaternion.zig +++ b/packages/vecmath/src/rotors/Quaternion.zig @@ -130,8 +130,18 @@ pub const Quaternion = extern struct { }; } + test mulQuaternion { + try std.testing.expectEqual( + init(101, 169, 207, -13), + mulQuaternion( + init(2, 3, 5, 7), + init(11, 13, 17, 19), + ), + ); + } + pub inline fn inverseUnit(self: Quaternion) Quaternion { - std.debug.assert(@abs(self.mag() - 1.0) <= 0x1p-10); + std.debug.assert(@abs(self.mag() - 1.0) <= 0x1p-5); return .{ .x = -self.x, .y = -self.y, diff --git a/packages/vecmath/src/rotors/Quaternion_x8.zig b/packages/vecmath/src/rotors/Quaternion_x8.zig index a532bdd..b9d0992 100644 --- a/packages/vecmath/src/rotors/Quaternion_x8.zig +++ b/packages/vecmath/src/rotors/Quaternion_x8.zig @@ -232,7 +232,7 @@ pub const Quaternion_x8 = struct { } pub inline fn inverseUnit(self: Quaternion_x8) Quaternion_x8 { - std.debug.assert(@reduce(.And, @abs(self.mag() - vm.ps(1.0)) <= vm.ps(0x1p-10))); + std.debug.assert(@reduce(.And, @abs(self.mag() - vm.ps(1.0)) <= vm.ps(0x1p-5))); return .{ .x = -self.x, .y = -self.y, diff --git a/packages/vecmath/src/trig.zig b/packages/vecmath/src/trig.zig index 36c1b72..f24bf5a 100644 --- a/packages/vecmath/src/trig.zig +++ b/packages/vecmath/src/trig.zig @@ -27,10 +27,10 @@ pub fn turnsToRadians(ang: anytype) if (@TypeOf(ang) == comptime_int) comptime_f test turnsToRadians { try std.testing.expectEqual(0, turnsToRadians(@as(f32, 0))); - try std.testing.expectApproxEqAbs(0.25 * std.math.tau, turnsToRadians(@as(f32, 0.25)), 0x1p-10); - try std.testing.expectApproxEqAbs(0.5 * std.math.tau, turnsToRadians(@as(f32, 0.5)), 0x1p-10); - try std.testing.expectApproxEqAbs(0.75 * std.math.tau, turnsToRadians(@as(f32, 0.75)), 0x1p-10); - try std.testing.expectApproxEqAbs(std.math.tau, turnsToRadians(@as(f32, 1)), 0x1p-10); + try std.testing.expectApproxEqAbs(0.25 * std.math.tau, turnsToRadians(@as(f32, 0.25)), 0x1p-5); + try std.testing.expectApproxEqAbs(0.5 * std.math.tau, turnsToRadians(@as(f32, 0.5)), 0x1p-5); + try std.testing.expectApproxEqAbs(0.75 * std.math.tau, turnsToRadians(@as(f32, 0.75)), 0x1p-5); + try std.testing.expectApproxEqAbs(std.math.tau, turnsToRadians(@as(f32, 1)), 0x1p-5); } /// Converts an angle in turns to degrees. `@TypeOf(ang)` must be a float or @@ -67,10 +67,10 @@ pub fn radiansToTurns(ang: anytype) if (@TypeOf(ang) == comptime_int) comptime_f test radiansToTurns { try std.testing.expectEqual(0, radiansToTurns(@as(f32, 0))); - try std.testing.expectApproxEqAbs(0.25, radiansToTurns(@as(f32, 0.25 * std.math.tau)), 0x1p-10); - try std.testing.expectApproxEqAbs(0.5, radiansToTurns(@as(f32, 0.5 * std.math.tau)), 0x1p-10); - try std.testing.expectApproxEqAbs(0.75, radiansToTurns(@as(f32, 0.75 * std.math.tau)), 0x1p-10); - try std.testing.expectApproxEqAbs(1, radiansToTurns(@as(f32, std.math.tau)), 0x1p-10); + try std.testing.expectApproxEqAbs(0.25, radiansToTurns(@as(f32, 0.25 * std.math.tau)), 0x1p-5); + try std.testing.expectApproxEqAbs(0.5, radiansToTurns(@as(f32, 0.5 * std.math.tau)), 0x1p-5); + try std.testing.expectApproxEqAbs(0.75, radiansToTurns(@as(f32, 0.75 * std.math.tau)), 0x1p-5); + try std.testing.expectApproxEqAbs(1, radiansToTurns(@as(f32, std.math.tau)), 0x1p-5); } /// Converts an angle in degrees to turns. `@TypeOf(ang)` must be a float or diff --git a/packages/vecmath/src/vectors/Vector2.zig b/packages/vecmath/src/vectors/Vector2.zig index f7fa2e1..8696884 100644 --- a/packages/vecmath/src/vectors/Vector2.zig +++ b/packages/vecmath/src/vectors/Vector2.zig @@ -127,4 +127,39 @@ pub const Vector2 = extern struct { .y = self.x * complex.im + self.y * complex.re, }; } + + pub inline fn rotate_x8(self: Vector2, complex: vm.Complex_x8) vm.Vector2x8 { + return .{ + .x = vm.ps(self.x) * complex.re - vm.ps(self.y) * complex.im, + .y = vm.ps(self.x) * complex.im + vm.ps(self.y) * complex.re, + }; + } + + pub inline fn transformPoint(self: Vector2, m: vm.Matrix3x2) Vector2 { + return .{ + .x = self.x * m.ix + self.y * m.jx + m.tx, + .y = self.x * m.iy + self.y * m.jy + m.ty, + }; + } + + pub inline fn transformPoint_x8(self: Vector2, m: vm.Matrix3x2x8) vm.Vector2x8 { + return .{ + .x = vm.ps(self.x) * m.ix + vm.ps(self.y) * m.jx + m.tx, + .y = vm.ps(self.x) * m.iy + vm.ps(self.y) * m.jy + m.ty, + }; + } + + pub inline fn transformVector(self: Vector2, m: vm.Matrix3x2) Vector2 { + return .{ + .x = self.x * m.ix + self.y * m.jx, + .y = self.x * m.iy + self.y * m.jy, + }; + } + + pub inline fn transformVector_x8(self: Vector2, m: vm.Matrix3x2x8) vm.Vector2x8 { + return .{ + .x = vm.ps(self.x) * m.ix + vm.ps(self.y) * m.jx, + .y = vm.ps(self.x) * m.iy + vm.ps(self.y) * m.jy, + }; + } }; diff --git a/packages/vecmath/src/vectors/Vector2x8.zig b/packages/vecmath/src/vectors/Vector2x8.zig index e0faee6..7a2d837 100644 --- a/packages/vecmath/src/vectors/Vector2x8.zig +++ b/packages/vecmath/src/vectors/Vector2x8.zig @@ -199,4 +199,32 @@ pub const Vector2x8 = struct { .y = self.x * vm.ps(complex.im) + self.y * vm.ps(complex.re), }; } + + pub inline fn transformPoint(self: Vector2x8, m: vm.Matrix3x2x8) Vector2x8 { + return .{ + .x = self.x * m.ix + self.y * m.jx + m.tx, + .y = self.x * m.iy + self.y * m.jy + m.ty, + }; + } + + pub inline fn transformPointSingle(self: Vector2x8, m: vm.Matrix3x2) Vector2x8 { + return .{ + .x = self.x * vm.ps(m.ix) + self.y * vm.ps(m.jx) + vm.ps(m.tx), + .y = self.x * vm.ps(m.iy) + self.y * vm.ps(m.jy) + vm.ps(m.ty), + }; + } + + pub inline fn transformVector(self: Vector2x8, m: vm.Matrix3x2x8) Vector2x8 { + return .{ + .x = self.x * m.ix + self.y * m.jx, + .y = self.x * m.iy + self.y * m.jy, + }; + } + + pub inline fn transformVectorSingle(self: Vector2x8, m: vm.Matrix3x2) Vector2x8 { + return .{ + .x = self.x * vm.ps(m.ix) + self.y * vm.ps(m.jx), + .y = self.x * vm.ps(m.iy) + self.y * vm.ps(m.jy), + }; + } }; diff --git a/packages/vecmath/src/vectors/Vector3.zig b/packages/vecmath/src/vectors/Vector3.zig index 68cf51b..86b7960 100644 --- a/packages/vecmath/src/vectors/Vector3.zig +++ b/packages/vecmath/src/vectors/Vector3.zig @@ -141,4 +141,50 @@ pub const Vector3 = extern struct { ), ); } + + pub inline fn rotate_x8(self: Vector3, quaternion: vm.Quaternion_x8) vm.Vector3x8 { + const w = quaternion.getScalar(); + const xyz = quaternion.getVector(); + const self_x8: vm.Vector3x8 = .splat(self); + + return .add( + self_x8, + .cross( + .add(xyz, xyz), + .add(.cross(xyz, self_x8), self_x8.mulScalar(w)), + ), + ); + } + + pub inline fn transformPoint(self: Vector3, m: vm.Matrix4x4) Vector3 { + return .{ + .x = self.x * m.ix + self.y * m.jx + self.z * m.kx + m.tx, + .y = self.x * m.iy + self.y * m.jy + self.z * m.ky + m.ty, + .z = self.x * m.iz + self.y * m.jz + self.z * m.kz + m.tz, + }; + } + + pub inline fn transformPoint_x8(self: Vector3, m: vm.Matrix4x4x8) vm.Vector3x8 { + return .{ + .x = vm.ps(self.x) * m.ix + vm.ps(self.y) * m.jx + vm.ps(self.z) * m.kx + m.tx, + .y = vm.ps(self.x) * m.iy + vm.ps(self.y) * m.jy + vm.ps(self.z) * m.ky + m.ty, + .z = vm.ps(self.x) * m.iz + vm.ps(self.y) * m.jz + vm.ps(self.z) * m.kz + m.tz, + }; + } + + pub inline fn transformVector(self: Vector3, m: vm.Matrix4x4) Vector3 { + return .{ + .x = self.x * m.ix + self.y * m.jx + self.z * m.kx, + .y = self.x * m.iy + self.y * m.jy + self.z * m.ky, + .z = self.x * m.iz + self.y * m.jz + self.z * m.kz, + }; + } + + pub inline fn transformVector_x8(self: Vector3, m: vm.Matrix4x4x8) vm.Vector3x8 { + return .{ + .x = vm.ps(self.x) * m.ix + vm.ps(self.y) * m.jx + vm.ps(self.z) * m.kx, + .y = vm.ps(self.x) * m.iy + vm.ps(self.y) * m.jy + vm.ps(self.z) * m.ky, + .z = vm.ps(self.x) * m.iz + vm.ps(self.y) * m.jz + vm.ps(self.z) * m.kz, + }; + } }; diff --git a/packages/vecmath/src/vectors/Vector3x8.zig b/packages/vecmath/src/vectors/Vector3x8.zig index f8bbaa9..afac0b7 100644 --- a/packages/vecmath/src/vectors/Vector3x8.zig +++ b/packages/vecmath/src/vectors/Vector3x8.zig @@ -222,4 +222,36 @@ pub const Vector3x8 = struct { ), ); } + + pub inline fn transformPoint(self: vm.Matrix4x4x8, p: Vector3x8) Vector3x8 { + return .{ + .x = p.x * self.ix + p.y * self.jx + p.z * self.kx + self.tx, + .y = p.x * self.iy + p.y * self.jy + p.z * self.ky + self.ty, + .z = p.x * self.iz + p.y * self.jz + p.z * self.kz + self.tz, + }; + } + + pub inline fn transformPointSingle(self: vm.Matrix4x4, p: Vector3x8) Vector3x8 { + return .{ + .x = p.x * vm.ps(self.ix) + p.y * vm.ps(self.jx) + p.z * vm.ps(self.kx) + vm.ps(self.tx), + .y = p.x * vm.ps(self.iy) + p.y * vm.ps(self.jy) + p.z * vm.ps(self.ky) + vm.ps(self.ty), + .z = p.x * vm.ps(self.iz) + p.y * vm.ps(self.jz) + p.z * vm.ps(self.kz) + vm.ps(self.tz), + }; + } + + pub inline fn transformVector(self: vm.Matrix4x4x8, p: Vector3x8) Vector3x8 { + return .{ + .x = p.x * self.ix + p.y * self.jx + p.z * self.kx, + .y = p.x * self.iy + p.y * self.jy + p.z * self.ky, + .z = p.x * self.iz + p.y * self.jz + p.z * self.kz, + }; + } + + pub inline fn transformVectorSingle(self: vm.Matrix4x4, v: Vector3x8) Vector3x8 { + return .{ + .x = v.x * vm.ps(self.ix) + v.y * vm.ps(self.jx) + v.z * vm.ps(self.kx), + .y = v.x * vm.ps(self.iy) + v.y * vm.ps(self.jy) + v.z * vm.ps(self.ky), + .z = v.x * vm.ps(self.iz) + v.y * vm.ps(self.jz) + v.z * vm.ps(self.kz), + }; + } }; diff --git a/packages/vecmath/src/vectors/Vector4.zig b/packages/vecmath/src/vectors/Vector4.zig index 58b5881..9bb8128 100644 --- a/packages/vecmath/src/vectors/Vector4.zig +++ b/packages/vecmath/src/vectors/Vector4.zig @@ -124,4 +124,22 @@ pub const Vector4 = extern struct { .w = @mulAdd(f32, t, b.w, @mulAdd(f32, -t, a.w, a.w)), }; } + + pub inline fn transform(self: Vector4, m: vm.Matrix4x4) Vector4 { + return .{ + .x = self.x * m.ix + self.y * m.jx + self.z * m.kx + self.w * m.tx, + .y = self.x * m.iy + self.y * m.jy + self.z * m.ky + self.w * m.ty, + .z = self.x * m.iz + self.y * m.jz + self.z * m.kz + self.w * m.tz, + .w = self.x * m.iw + self.y * m.jw + self.z * m.kw + self.w * m.tw, + }; + } + + pub inline fn transform_x8(self: Vector4, m: vm.Matrix4x4x8) vm.Vector4x8 { + return .{ + .x = vm.ps(self.x) * m.ix + vm.ps(self.y) * m.jx + vm.ps(self.z) * m.kx + vm.ps(self.w) * m.tx, + .y = vm.ps(self.x) * m.iy + vm.ps(self.y) * m.jy + vm.ps(self.z) * m.ky + vm.ps(self.w) * m.ty, + .z = vm.ps(self.x) * m.iz + vm.ps(self.y) * m.jz + vm.ps(self.z) * m.kz + vm.ps(self.w) * m.tz, + .w = vm.ps(self.x) * m.iw + vm.ps(self.y) * m.jw + vm.ps(self.z) * m.kw + vm.ps(self.w) * m.tw, + }; + } }; diff --git a/packages/vecmath/src/vectors/Vector4x8.zig b/packages/vecmath/src/vectors/Vector4x8.zig index 543988c..d9458ef 100644 --- a/packages/vecmath/src/vectors/Vector4x8.zig +++ b/packages/vecmath/src/vectors/Vector4x8.zig @@ -195,4 +195,22 @@ pub const Vector4x8 = struct { .w = @mulAdd(vm.f32x8, vm.ps(t), b.w, @mulAdd(vm.f32x8, -vm.ps(t), a.w, a.w)), }; } + + pub inline fn transform(self: Vector4x8, m: vm.Matrix4x4x8) Vector4x8 { + return .{ + .x = self.x * m.ix + self.y * m.jx + self.z * m.kx + self.w * m.tx, + .y = self.x * m.iy + self.y * m.jy + self.z * m.ky + self.w * m.ty, + .z = self.x * m.iz + self.y * m.jz + self.z * m.kz + self.w * m.tz, + .w = self.x * m.iw + self.y * m.jw + self.z * m.kw + self.w * m.tw, + }; + } + + pub inline fn transformSingle(self: Vector4x8, m: vm.Matrix4x4) Vector4x8 { + return .{ + .x = self.x * vm.ps(m.ix) + self.y * vm.ps(m.jx) + self.z * vm.ps(m.kx) + self.w * vm.ps(m.tx), + .y = self.x * vm.ps(m.iy) + self.y * vm.ps(m.jy) + self.z * vm.ps(m.ky) + self.w * vm.ps(m.ty), + .z = self.x * vm.ps(m.iz) + self.y * vm.ps(m.jz) + self.z * vm.ps(m.kz) + self.w * vm.ps(m.tz), + .w = self.x * vm.ps(m.iw) + self.y * vm.ps(m.jw) + self.z * vm.ps(m.kw) + self.w * vm.ps(m.tw), + }; + } };