math: improve debug build performance
Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
This commit is contained in:
parent
b96e8ac995
commit
fe517f3efb
2 changed files with 137 additions and 128 deletions
183
src/math/mat.zig
183
src/math/mat.zig
|
|
@ -49,15 +49,15 @@ pub fn Mat(
|
|||
/// Identity matrix
|
||||
pub const ident = switch (Matrix) {
|
||||
inline math.Mat3x3, math.Mat3x3h, math.Mat3x3d => Matrix.init(
|
||||
RowVec.init(1, 0, 0),
|
||||
RowVec.init(0, 1, 0),
|
||||
RowVec.init(0, 0, 1),
|
||||
&RowVec.init(1, 0, 0),
|
||||
&RowVec.init(0, 1, 0),
|
||||
&RowVec.init(0, 0, 1),
|
||||
),
|
||||
inline math.Mat4x4, math.Mat4x4h, math.Mat4x4d => Matrix.init(
|
||||
Vec.init(1, 0, 0, 0),
|
||||
Vec.init(0, 1, 0, 0),
|
||||
Vec.init(0, 0, 1, 0),
|
||||
Vec.init(0, 0, 0, 1),
|
||||
&Vec.init(1, 0, 0, 0),
|
||||
&Vec.init(0, 1, 0, 0),
|
||||
&Vec.init(0, 0, 1, 0),
|
||||
&Vec.init(0, 0, 0, 1),
|
||||
),
|
||||
else => @compileError("Expected Mat3x3, Mat4x4 found '" ++ @typeName(Matrix) ++ "'"),
|
||||
};
|
||||
|
|
@ -84,7 +84,7 @@ pub fn Mat(
|
|||
/// ```
|
||||
///
|
||||
/// Note that Mach matrices use [column-major storage and column-vectors](https://machengine.org/engine/math/matrix-storage/).
|
||||
pub inline fn init(r0: RowVec, r1: RowVec, r2: RowVec) Matrix {
|
||||
pub inline fn init(r0: *const RowVec, r1: *const RowVec, r2: *const RowVec) Matrix {
|
||||
return .{ .v = [_]Vec{
|
||||
Vec.init(r0.x(), r1.x(), r2.x(), 1),
|
||||
Vec.init(r0.y(), r1.y(), r2.y(), 1),
|
||||
|
|
@ -93,17 +93,21 @@ pub fn Mat(
|
|||
}
|
||||
|
||||
/// Returns the row `i` of the matrix.
|
||||
pub inline fn row(m: Matrix, i: usize) RowVec {
|
||||
return RowVec.init(m.v[0].v[i], m.v[1].v[i], m.v[2].v[i]);
|
||||
pub inline fn row(m: *const Matrix, i: usize) RowVec {
|
||||
// Note: we inline RowVec.init manually here as it is faster in debug builds.
|
||||
// return RowVec.init(m.v[0].v[i], m.v[1].v[i], m.v[2].v[i]);
|
||||
return .{ .v = .{ m.v[0].v[i], m.v[1].v[i], m.v[2].v[i] } };
|
||||
}
|
||||
|
||||
/// Returns the column `i` of the matrix.
|
||||
pub inline fn col(m: Matrix, i: usize) RowVec {
|
||||
return RowVec.init(m.v[i].v[0], m.v[i].v[1], m.v[i].v[2]);
|
||||
pub inline fn col(m: *const Matrix, i: usize) RowVec {
|
||||
// Note: we inline RowVec.init manually here as it is faster in debug builds.
|
||||
// return RowVec.init(m.v[i].v[0], m.v[i].v[1], m.v[i].v[2]);
|
||||
return .{ .v = .{ m.v[i].v[0], m.v[i].v[1], m.v[i].v[2] } };
|
||||
}
|
||||
|
||||
/// Transposes the matrix.
|
||||
pub inline fn transpose(m: Matrix) Matrix {
|
||||
pub inline fn transpose(m: *const Matrix) Matrix {
|
||||
return .{ .v = [_]Vec{
|
||||
Vec.init(m.v[0].v[0], m.v[1].v[0], m.v[2].v[0], 1),
|
||||
Vec.init(m.v[0].v[1], m.v[1].v[1], m.v[2].v[1], 1),
|
||||
|
|
@ -115,9 +119,9 @@ pub fn Mat(
|
|||
// TODO: needs tests
|
||||
pub inline fn scale(s: math.Vec2) Matrix {
|
||||
return init(
|
||||
RowVec.init(s.x(), 0, 0),
|
||||
RowVec.init(0, s.y(), 0),
|
||||
RowVec.init(0, 0, 1),
|
||||
&RowVec.init(s.x(), 0, 0),
|
||||
&RowVec.init(0, s.y(), 0),
|
||||
&RowVec.init(0, 0, 1),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -131,9 +135,9 @@ pub fn Mat(
|
|||
// TODO: needs tests
|
||||
pub inline fn translate(t: math.Vec2) Matrix {
|
||||
return init(
|
||||
RowVec.init(1, 0, t.x()),
|
||||
RowVec.init(0, 1, t.y()),
|
||||
RowVec.init(0, 0, 1),
|
||||
&RowVec.init(1, 0, t.x()),
|
||||
&RowVec.init(0, 1, t.y()),
|
||||
&RowVec.init(0, 0, 1),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -164,15 +168,15 @@ pub fn Mat(
|
|||
///
|
||||
/// ```
|
||||
/// const m = Mat4x4.init(
|
||||
/// vec4(1, 0, 0, tx),
|
||||
/// vec4(0, 1, 0, ty),
|
||||
/// vec4(0, 0, 1, tz),
|
||||
/// vec4(0, 0, 0, tw),
|
||||
/// &vec4(1, 0, 0, tx),
|
||||
/// &vec4(0, 1, 0, ty),
|
||||
/// &vec4(0, 0, 1, tz),
|
||||
/// &vec4(0, 0, 0, tw),
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
/// Note that Mach matrices use [column-major storage and column-vectors](https://machengine.org/engine/math/matrix-storage/).
|
||||
pub inline fn init(r0: RowVec, r1: RowVec, r2: RowVec, r3: RowVec) Matrix {
|
||||
pub inline fn init(r0: *const RowVec, r1: *const RowVec, r2: *const RowVec, r3: *const RowVec) Matrix {
|
||||
return .{ .v = [_]Vec{
|
||||
Vec.init(r0.x(), r1.x(), r2.x(), r3.x()),
|
||||
Vec.init(r0.y(), r1.y(), r2.y(), r3.y()),
|
||||
|
|
@ -182,17 +186,17 @@ pub fn Mat(
|
|||
}
|
||||
|
||||
/// Returns the row `i` of the matrix.
|
||||
pub inline fn row(m: Matrix, i: usize) RowVec {
|
||||
return RowVec.init(m.v[0].v[i], m.v[1].v[i], m.v[2].v[i], m.v[3].v[i]);
|
||||
pub inline fn row(m: *const Matrix, i: usize) RowVec {
|
||||
return RowVec{ .v = RowVec.Vector{ m.v[0].v[i], m.v[1].v[i], m.v[2].v[i], m.v[3].v[i] } };
|
||||
}
|
||||
|
||||
/// Returns the column `i` of the matrix.
|
||||
pub inline fn col(m: Matrix, i: usize) RowVec {
|
||||
return RowVec.init(m.v[i].v[0], m.v[i].v[1], m.v[i].v[2], m.v[i].v[3]);
|
||||
pub inline fn col(m: *const Matrix, i: usize) RowVec {
|
||||
return RowVec{ .v = RowVec.Vector{ m.v[i].v[0], m.v[i].v[1], m.v[i].v[2], m.v[i].v[3] } };
|
||||
}
|
||||
|
||||
/// Transposes the matrix.
|
||||
pub inline fn transpose(m: Matrix) Matrix {
|
||||
pub inline fn transpose(m: *const Matrix) Matrix {
|
||||
return .{ .v = [_]Vec{
|
||||
Vec.init(m.v[0].v[0], m.v[1].v[0], m.v[2].v[0], m.v[3].v[0]),
|
||||
Vec.init(m.v[0].v[1], m.v[1].v[1], m.v[2].v[1], m.v[3].v[1]),
|
||||
|
|
@ -205,10 +209,10 @@ pub fn Mat(
|
|||
// TODO: needs tests
|
||||
pub inline fn scale(s: math.Vec3) Matrix {
|
||||
return init(
|
||||
Vec.init(s.x(), 0, 0, 0),
|
||||
Vec.init(0, s.y(), 0, 0),
|
||||
Vec.init(0, 0, s.z(), 0),
|
||||
Vec.init(0, 0, 0, 1),
|
||||
&RowVec.init(s.x(), 0, 0, 0),
|
||||
&RowVec.init(0, s.y(), 0, 0),
|
||||
&RowVec.init(0, 0, s.z(), 0),
|
||||
&RowVec.init(0, 0, 0, 1),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -222,10 +226,10 @@ pub fn Mat(
|
|||
// TODO: needs tests
|
||||
pub inline fn translate(t: math.Vec3) Matrix {
|
||||
return init(
|
||||
RowVec.init(1, 0, 0, t.x()),
|
||||
RowVec.init(0, 1, 0, t.y()),
|
||||
RowVec.init(0, 0, 1, t.z()),
|
||||
RowVec.init(0, 0, 0, 1),
|
||||
&RowVec.init(1, 0, 0, t.x()),
|
||||
&RowVec.init(0, 1, 0, t.y()),
|
||||
&RowVec.init(0, 0, 1, t.z()),
|
||||
&RowVec.init(0, 0, 0, 1),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -237,7 +241,7 @@ pub fn Mat(
|
|||
|
||||
/// Returns the translation component of the matrix.
|
||||
// TODO: needs tests
|
||||
pub inline fn translation(t: Matrix) math.Vec3 {
|
||||
pub inline fn translation(t: *const Matrix) math.Vec3 {
|
||||
return math.Vec3.init(t.v[3].x(), t.v[3].y(), t.v[3].z());
|
||||
}
|
||||
|
||||
|
|
@ -246,10 +250,10 @@ pub fn Mat(
|
|||
const c = std.math.cos(angle_radians);
|
||||
const s = std.math.sin(angle_radians);
|
||||
return Matrix.init(
|
||||
RowVec.init(1, 0, 0, 0),
|
||||
RowVec.init(0, c, -s, 0),
|
||||
RowVec.init(0, s, c, 0),
|
||||
RowVec.init(0, 0, 0, 1),
|
||||
&RowVec.init(1, 0, 0, 0),
|
||||
&RowVec.init(0, c, -s, 0),
|
||||
&RowVec.init(0, s, c, 0),
|
||||
&RowVec.init(0, 0, 0, 1),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -258,10 +262,10 @@ pub fn Mat(
|
|||
const c = std.math.cos(angle_radians);
|
||||
const s = std.math.sin(angle_radians);
|
||||
return Matrix.init(
|
||||
RowVec.init(c, 0, s, 0),
|
||||
RowVec.init(0, 1, 0, 0),
|
||||
RowVec.init(-s, 0, c, 0),
|
||||
RowVec.init(0, 0, 0, 1),
|
||||
&RowVec.init(c, 0, s, 0),
|
||||
&RowVec.init(0, 1, 0, 0),
|
||||
&RowVec.init(-s, 0, c, 0),
|
||||
&RowVec.init(0, 0, 0, 1),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -270,10 +274,10 @@ pub fn Mat(
|
|||
const c = std.math.cos(angle_radians);
|
||||
const s = std.math.sin(angle_radians);
|
||||
return Matrix.init(
|
||||
RowVec.init(c, -s, 0, 0),
|
||||
RowVec.init(s, c, 0, 0),
|
||||
RowVec.init(0, 0, 1, 0),
|
||||
RowVec.init(0, 0, 0, 1),
|
||||
&RowVec.init(c, -s, 0, 0),
|
||||
&RowVec.init(s, c, 0, 0),
|
||||
&RowVec.init(0, 0, 1, 0),
|
||||
&RowVec.init(0, 0, 0, 1),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -303,10 +307,10 @@ pub fn Mat(
|
|||
const ty = (top + bottom) / (bottom - top);
|
||||
const tz = near / (near - far);
|
||||
return init(
|
||||
RowVec.init(xx, 0, 0, tx),
|
||||
RowVec.init(0, yy, 0, ty),
|
||||
RowVec.init(0, 0, zz, tz),
|
||||
RowVec.init(0, 0, 0, 1),
|
||||
&RowVec.init(xx, 0, 0, tx),
|
||||
&RowVec.init(0, yy, 0, ty),
|
||||
&RowVec.init(0, 0, zz, tz),
|
||||
&RowVec.init(0, 0, 0, 1),
|
||||
);
|
||||
}
|
||||
},
|
||||
|
|
@ -315,13 +319,18 @@ pub fn Mat(
|
|||
|
||||
/// Matrix multiplication a*b
|
||||
// TODO: needs tests
|
||||
pub fn mul(a: Matrix, b: Matrix) Matrix {
|
||||
pub inline fn mul(a: *const Matrix, b: *const Matrix) Matrix {
|
||||
@setEvalBranchQuota(10000);
|
||||
var result: Matrix = undefined;
|
||||
inline for (0..Matrix.rows) |row| {
|
||||
inline for (0..Matrix.cols) |col| {
|
||||
var sum: RowVec.T = 0.0;
|
||||
inline for (0..RowVec.n) |i| {
|
||||
sum += a.row(row).mul(b.col(col)).v[i];
|
||||
// Note: we directly access rows/columns below as it is much faster **in
|
||||
// debug builds**, instead of using these helpers:
|
||||
//
|
||||
// sum += a.row(row).mul(&b.col(col)).v[i];
|
||||
sum += a.v[i].v[row] * b.v[col].v[i];
|
||||
}
|
||||
result.v[col].v[row] = sum;
|
||||
}
|
||||
|
|
@ -401,9 +410,9 @@ test "n" {
|
|||
|
||||
test "init" {
|
||||
try testing.expect(math.Mat3x3, math.mat3x3(
|
||||
math.vec3(1, 0, 1337),
|
||||
math.vec3(0, 1, 7331),
|
||||
math.vec3(0, 0, 1),
|
||||
&math.vec3(1, 0, 1337),
|
||||
&math.vec3(0, 1, 7331),
|
||||
&math.vec3(0, 0, 1),
|
||||
)).eql(math.Mat3x3{
|
||||
.v = [_]math.Vec4{
|
||||
math.Vec4.init(1, 0, 0, 1),
|
||||
|
|
@ -436,9 +445,9 @@ test "mat4x4_ident" {
|
|||
|
||||
test "Mat3x3_row" {
|
||||
const m = math.Mat3x3.init(
|
||||
math.vec3(0, 1, 2),
|
||||
math.vec3(3, 4, 5),
|
||||
math.vec3(6, 7, 8),
|
||||
&math.vec3(0, 1, 2),
|
||||
&math.vec3(3, 4, 5),
|
||||
&math.vec3(6, 7, 8),
|
||||
);
|
||||
try testing.expect(math.Vec3, math.vec3(0, 1, 2)).eql(m.row(0));
|
||||
try testing.expect(math.Vec3, math.vec3(3, 4, 5)).eql(m.row(1));
|
||||
|
|
@ -447,9 +456,9 @@ test "Mat3x3_row" {
|
|||
|
||||
test "Mat3x3_col" {
|
||||
const m = math.Mat3x3.init(
|
||||
math.vec3(0, 1, 2),
|
||||
math.vec3(3, 4, 5),
|
||||
math.vec3(6, 7, 8),
|
||||
&math.vec3(0, 1, 2),
|
||||
&math.vec3(3, 4, 5),
|
||||
&math.vec3(6, 7, 8),
|
||||
);
|
||||
try testing.expect(math.Vec3, math.vec3(0, 3, 6)).eql(m.col(0));
|
||||
try testing.expect(math.Vec3, math.vec3(1, 4, 7)).eql(m.col(1));
|
||||
|
|
@ -458,10 +467,10 @@ test "Mat3x3_col" {
|
|||
|
||||
test "Mat4x4_row" {
|
||||
const m = math.Mat4x4.init(
|
||||
math.vec4(0, 1, 2, 3),
|
||||
math.vec4(4, 5, 6, 7),
|
||||
math.vec4(8, 9, 10, 11),
|
||||
math.vec4(12, 13, 14, 15),
|
||||
&math.vec4(0, 1, 2, 3),
|
||||
&math.vec4(4, 5, 6, 7),
|
||||
&math.vec4(8, 9, 10, 11),
|
||||
&math.vec4(12, 13, 14, 15),
|
||||
);
|
||||
try testing.expect(math.Vec4, math.vec4(0, 1, 2, 3)).eql(m.row(0));
|
||||
try testing.expect(math.Vec4, math.vec4(4, 5, 6, 7)).eql(m.row(1));
|
||||
|
|
@ -471,10 +480,10 @@ test "Mat4x4_row" {
|
|||
|
||||
test "Mat4x4_col" {
|
||||
const m = math.Mat4x4.init(
|
||||
math.vec4(0, 1, 2, 3),
|
||||
math.vec4(4, 5, 6, 7),
|
||||
math.vec4(8, 9, 10, 11),
|
||||
math.vec4(12, 13, 14, 15),
|
||||
&math.vec4(0, 1, 2, 3),
|
||||
&math.vec4(4, 5, 6, 7),
|
||||
&math.vec4(8, 9, 10, 11),
|
||||
&math.vec4(12, 13, 14, 15),
|
||||
);
|
||||
try testing.expect(math.Vec4, math.vec4(0, 4, 8, 12)).eql(m.col(0));
|
||||
try testing.expect(math.Vec4, math.vec4(1, 5, 9, 13)).eql(m.col(1));
|
||||
|
|
@ -484,29 +493,29 @@ test "Mat4x4_col" {
|
|||
|
||||
test "Mat3x3_transpose" {
|
||||
const m = math.Mat3x3.init(
|
||||
math.vec3(0, 1, 2),
|
||||
math.vec3(3, 4, 5),
|
||||
math.vec3(6, 7, 8),
|
||||
&math.vec3(0, 1, 2),
|
||||
&math.vec3(3, 4, 5),
|
||||
&math.vec3(6, 7, 8),
|
||||
);
|
||||
try testing.expect(math.Mat3x3, math.Mat3x3.init(
|
||||
math.vec3(0, 3, 6),
|
||||
math.vec3(1, 4, 7),
|
||||
math.vec3(2, 5, 8),
|
||||
&math.vec3(0, 3, 6),
|
||||
&math.vec3(1, 4, 7),
|
||||
&math.vec3(2, 5, 8),
|
||||
)).eql(m.transpose());
|
||||
}
|
||||
|
||||
test "Mat4x4_transpose" {
|
||||
const m = math.Mat4x4.init(
|
||||
math.vec4(0, 1, 2, 3),
|
||||
math.vec4(4, 5, 6, 7),
|
||||
math.vec4(8, 9, 10, 11),
|
||||
math.vec4(12, 13, 14, 15),
|
||||
&math.vec4(0, 1, 2, 3),
|
||||
&math.vec4(4, 5, 6, 7),
|
||||
&math.vec4(8, 9, 10, 11),
|
||||
&math.vec4(12, 13, 14, 15),
|
||||
);
|
||||
try testing.expect(math.Mat4x4, math.Mat4x4.init(
|
||||
math.vec4(0, 4, 8, 12),
|
||||
math.vec4(1, 5, 9, 13),
|
||||
math.vec4(2, 6, 10, 14),
|
||||
math.vec4(3, 7, 11, 15),
|
||||
&math.vec4(0, 4, 8, 12),
|
||||
&math.vec4(1, 5, 9, 13),
|
||||
&math.vec4(2, 6, 10, 14),
|
||||
&math.vec4(3, 7, 11, 15),
|
||||
)).eql(m.transpose());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,10 +24,10 @@ pub fn Vec(comptime n_value: usize, comptime Scalar: type) type {
|
|||
pub inline fn init(xs: Scalar, ys: Scalar) VecN {
|
||||
return .{ .v = .{ xs, ys } };
|
||||
}
|
||||
pub inline fn x(v: VecN) Scalar {
|
||||
pub inline fn x(v: *const VecN) Scalar {
|
||||
return v.v[0];
|
||||
}
|
||||
pub inline fn y(v: VecN) Scalar {
|
||||
pub inline fn y(v: *const VecN) Scalar {
|
||||
return v.v[1];
|
||||
}
|
||||
},
|
||||
|
|
@ -35,27 +35,27 @@ pub fn Vec(comptime n_value: usize, comptime Scalar: type) type {
|
|||
pub inline fn init(xs: Scalar, ys: Scalar, zs: Scalar) VecN {
|
||||
return .{ .v = .{ xs, ys, zs } };
|
||||
}
|
||||
pub inline fn x(v: VecN) Scalar {
|
||||
pub inline fn x(v: *const VecN) Scalar {
|
||||
return v.v[0];
|
||||
}
|
||||
pub inline fn y(v: VecN) Scalar {
|
||||
pub inline fn y(v: *const VecN) Scalar {
|
||||
return v.v[1];
|
||||
}
|
||||
pub inline fn z(v: VecN) Scalar {
|
||||
pub inline fn z(v: *const VecN) Scalar {
|
||||
return v.v[2];
|
||||
}
|
||||
|
||||
// TODO(math): come up with a better strategy for swizzling?
|
||||
pub inline fn yzw(v: VecN) VecN {
|
||||
pub inline fn yzw(v: *const VecN) VecN {
|
||||
return VecN.init(v.y(), v.z(), v.w());
|
||||
}
|
||||
pub inline fn zxy(v: VecN) VecN {
|
||||
pub inline fn zxy(v: *const VecN) VecN {
|
||||
return VecN.init(v.z(), v.x(), v.y());
|
||||
}
|
||||
|
||||
/// Calculates the cross product between vector a and b. This can be done only in 3D
|
||||
/// and required inputs are Vec3.
|
||||
pub inline fn cross(a: VecN, b: VecN) VecN {
|
||||
pub inline fn cross(a: *const VecN, b: *const VecN) VecN {
|
||||
// https://gamemath.com/book/vectors.html#cross_product
|
||||
const s1 = a.yzx().mul(b.zxy());
|
||||
const s2 = a.zxy().mul(b.yzx());
|
||||
|
|
@ -66,16 +66,16 @@ pub fn Vec(comptime n_value: usize, comptime Scalar: type) type {
|
|||
pub inline fn init(xs: Scalar, ys: Scalar, zs: Scalar, ws: Scalar) VecN {
|
||||
return .{ .v = .{ xs, ys, zs, ws } };
|
||||
}
|
||||
pub inline fn x(v: VecN) Scalar {
|
||||
pub inline fn x(v: *const VecN) Scalar {
|
||||
return v.v[0];
|
||||
}
|
||||
pub inline fn y(v: VecN) Scalar {
|
||||
pub inline fn y(v: *const VecN) Scalar {
|
||||
return v.v[1];
|
||||
}
|
||||
pub inline fn z(v: VecN) Scalar {
|
||||
pub inline fn z(v: *const VecN) Scalar {
|
||||
return v.v[2];
|
||||
}
|
||||
pub inline fn w(v: VecN) Scalar {
|
||||
pub inline fn w(v: *const VecN) Scalar {
|
||||
return v.v[3];
|
||||
}
|
||||
},
|
||||
|
|
@ -83,66 +83,66 @@ pub fn Vec(comptime n_value: usize, comptime Scalar: type) type {
|
|||
};
|
||||
|
||||
/// Element-wise addition
|
||||
pub inline fn add(a: VecN, b: VecN) VecN {
|
||||
pub inline fn add(a: *const VecN, b: *const VecN) VecN {
|
||||
return .{ .v = a.v + b.v };
|
||||
}
|
||||
|
||||
/// Element-wise subtraction
|
||||
pub inline fn sub(a: VecN, b: VecN) VecN {
|
||||
pub inline fn sub(a: *const VecN, b: *const VecN) VecN {
|
||||
return .{ .v = a.v - b.v };
|
||||
}
|
||||
|
||||
/// Element-wise division
|
||||
pub inline fn div(a: VecN, b: VecN) VecN {
|
||||
pub inline fn div(a: *const VecN, b: *const VecN) VecN {
|
||||
return .{ .v = a.v / b.v };
|
||||
}
|
||||
|
||||
/// Element-wise multiplication.
|
||||
///
|
||||
/// See also .cross()
|
||||
pub inline fn mul(a: VecN, b: VecN) VecN {
|
||||
pub inline fn mul(a: *const VecN, b: *const VecN) VecN {
|
||||
return .{ .v = a.v * b.v };
|
||||
}
|
||||
|
||||
/// Scalar addition
|
||||
pub inline fn addScalar(a: VecN, s: Scalar) VecN {
|
||||
pub inline fn addScalar(a: *const VecN, s: Scalar) VecN {
|
||||
return .{ .v = a.v + VecN.splat(s).v };
|
||||
}
|
||||
|
||||
/// Scalar subtraction
|
||||
pub inline fn subScalar(a: VecN, s: Scalar) VecN {
|
||||
pub inline fn subScalar(a: *const VecN, s: Scalar) VecN {
|
||||
return .{ .v = a.v - VecN.splat(s).v };
|
||||
}
|
||||
|
||||
/// Scalar division
|
||||
pub inline fn divScalar(a: VecN, s: Scalar) VecN {
|
||||
pub inline fn divScalar(a: *const VecN, s: Scalar) VecN {
|
||||
return .{ .v = a.v / VecN.splat(s).v };
|
||||
}
|
||||
|
||||
/// Scalar multiplication.
|
||||
///
|
||||
/// See .dot() for the dot product
|
||||
pub inline fn mulScalar(a: VecN, s: Scalar) VecN {
|
||||
pub inline fn mulScalar(a: *const VecN, s: Scalar) VecN {
|
||||
return .{ .v = a.v * VecN.splat(s).v };
|
||||
}
|
||||
|
||||
/// Element-wise a < b
|
||||
pub inline fn less(a: VecN, b: Scalar) bool {
|
||||
pub inline fn less(a: *const VecN, b: Scalar) bool {
|
||||
return a.v < b.v;
|
||||
}
|
||||
|
||||
/// Element-wise a <= b
|
||||
pub inline fn lessEq(a: VecN, b: Scalar) bool {
|
||||
pub inline fn lessEq(a: *const VecN, b: Scalar) bool {
|
||||
return a.v <= b.v;
|
||||
}
|
||||
|
||||
/// Element-wise a > b
|
||||
pub inline fn greater(a: VecN, b: Scalar) bool {
|
||||
pub inline fn greater(a: *const VecN, b: Scalar) bool {
|
||||
return a.v > b.v;
|
||||
}
|
||||
|
||||
/// Element-wise a >= b
|
||||
pub inline fn greaterEq(a: VecN, b: Scalar) bool {
|
||||
pub inline fn greaterEq(a: *const VecN, b: Scalar) bool {
|
||||
return a.v >= b.v;
|
||||
}
|
||||
|
||||
|
|
@ -157,7 +157,7 @@ pub fn Vec(comptime n_value: usize, comptime Scalar: type) type {
|
|||
}
|
||||
|
||||
/// Computes the squared length of the vector. Faster than `len()`
|
||||
pub inline fn len2(v: VecN) Scalar {
|
||||
pub inline fn len2(v: *const VecN) Scalar {
|
||||
return switch (VecN.n) {
|
||||
inline 2 => (v.x() * v.x()) + (v.y() * v.y()),
|
||||
inline 3 => (v.x() * v.x()) + (v.y() * v.y()) + (v.z() * v.z()),
|
||||
|
|
@ -167,7 +167,7 @@ pub fn Vec(comptime n_value: usize, comptime Scalar: type) type {
|
|||
}
|
||||
|
||||
/// Computes the length of the vector.
|
||||
pub inline fn len(v: VecN) Scalar {
|
||||
pub inline fn len(v: *const VecN) Scalar {
|
||||
return math.sqrt(len2(v));
|
||||
}
|
||||
|
||||
|
|
@ -179,8 +179,8 @@ pub fn Vec(comptime n_value: usize, comptime Scalar: type) type {
|
|||
/// ```
|
||||
/// math.vec3(1.0, 2.0, 3.0).normalize(v, 0.00000001);
|
||||
/// ```
|
||||
pub inline fn normalize(v: VecN, d0: Scalar) VecN {
|
||||
return v.div(VecN.splat(v.len() + d0));
|
||||
pub inline fn normalize(v: *const VecN, d0: Scalar) VecN {
|
||||
return v.div(&VecN.splat(v.len() + d0));
|
||||
}
|
||||
|
||||
/// Returns the normalized direction vector from points a and b.
|
||||
|
|
@ -191,17 +191,17 @@ pub fn Vec(comptime n_value: usize, comptime Scalar: type) type {
|
|||
/// ```
|
||||
/// var v = a_point.dir(b_point, 0.0000001);
|
||||
/// ```
|
||||
pub inline fn dir(a: VecN, b: VecN, d0: Scalar) VecN {
|
||||
pub inline fn dir(a: *const VecN, b: *const VecN, d0: Scalar) VecN {
|
||||
return b.sub(a).normalize(d0);
|
||||
}
|
||||
|
||||
/// Calculates the squared distance between points a and b. Faster than `dist()`.
|
||||
pub inline fn dist2(a: VecN, b: VecN) Scalar {
|
||||
pub inline fn dist2(a: *const VecN, b: *const VecN) Scalar {
|
||||
return b.sub(a).len2();
|
||||
}
|
||||
|
||||
/// Calculates the distance between points a and b.
|
||||
pub inline fn dist(a: VecN, b: VecN) Scalar {
|
||||
pub inline fn dist(a: *const VecN, b: *const VecN) Scalar {
|
||||
return math.sqrt(a.dist2(b));
|
||||
}
|
||||
|
||||
|
|
@ -211,12 +211,12 @@ pub fn Vec(comptime n_value: usize, comptime Scalar: type) type {
|
|||
/// a.lerp(b, 0.0) == a
|
||||
/// a.lerp(b, 1.0) == b
|
||||
/// ```
|
||||
pub inline fn lerp(a: VecN, b: VecN, amount: Scalar) VecN {
|
||||
pub inline fn lerp(a: *const VecN, b: *const VecN, amount: Scalar) VecN {
|
||||
return a.mulScalar(1.0 - amount).add(b.mulScalar(amount));
|
||||
}
|
||||
|
||||
/// Calculates the dot product between vector a and b and returns scalar.
|
||||
pub inline fn dot(a: VecN, b: VecN) Scalar {
|
||||
pub inline fn dot(a: *const VecN, b: *const VecN) Scalar {
|
||||
return .{ .v = @reduce(.Add, a.v * b.v) };
|
||||
}
|
||||
};
|
||||
|
|
@ -304,14 +304,14 @@ test "normalize_no_nan" {
|
|||
|
||||
// TODO(math): add basic tests for these:
|
||||
//
|
||||
// pub inline fn add(a: VecN, b: VecN) VecN {
|
||||
// pub inline fn sub(a: VecN, b: VecN) VecN {
|
||||
// pub inline fn div(a: VecN, b: VecN) VecN {
|
||||
// pub inline fn mul(a: VecN, b: VecN) VecN {
|
||||
// pub inline fn addScalar(a: VecN, s: Scalar) VecN {
|
||||
// pub inline fn subScalar(a: VecN, s: Scalar) VecN {
|
||||
// pub inline fn divScalar(a: VecN, s: Scalar) VecN {
|
||||
// pub inline fn mulScalar(a: VecN, s: Scalar) VecN {
|
||||
// pub inline fn add(a: *const VecN, b: *const VecN) VecN {
|
||||
// pub inline fn sub(a: *const VecN, b: *const VecN) VecN {
|
||||
// pub inline fn div(a: *const VecN, b: *const VecN) VecN {
|
||||
// pub inline fn mul(a: *const VecN, b: *const VecN) VecN {
|
||||
// pub inline fn addScalar(a: *const VecN, s: Scalar) VecN {
|
||||
// pub inline fn subScalar(a: *const VecN, s: Scalar) VecN {
|
||||
// pub inline fn divScalar(a: *const VecN, s: Scalar) VecN {
|
||||
// pub inline fn mulScalar(a: *const VecN, s: Scalar) VecN {
|
||||
|
||||
// TODO(math): the tests below violate our styleguide (https://machengine.org/about/style/) we
|
||||
// should write new tests loosely based on them:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue