math: remove usingnamespace in favour of mixins (#1231)

This commit is contained in:
yzrmn 2024-08-08 07:05:35 +02:00 committed by GitHub
parent 42d2a57611
commit af7ac96a0e
Failed to generate hash of commit
5 changed files with 828 additions and 606 deletions

View file

@ -50,34 +50,34 @@ const ray = @import("ray.zig");
pub const collision = @import("collision.zig"); pub const collision = @import("collision.zig");
/// Standard f32 precision types /// Standard f32 precision types
pub const Vec2 = vec.Vec(2, f32); pub const Vec2 = vec.Vec2(f32);
pub const Vec3 = vec.Vec(3, f32); pub const Vec3 = vec.Vec3(f32);
pub const Vec4 = vec.Vec(4, f32); pub const Vec4 = vec.Vec4(f32);
pub const Quat = q.Quat(f32); pub const Quat = q.Quat(f32);
pub const Mat2x2 = mat.Mat(2, 2, Vec2); pub const Mat2x2 = mat.Mat2x2(f32);
pub const Mat3x3 = mat.Mat(3, 3, Vec3); pub const Mat3x3 = mat.Mat3x3(f32);
pub const Mat4x4 = mat.Mat(4, 4, Vec4); pub const Mat4x4 = mat.Mat4x4(f32);
pub const Ray = ray.Ray(Vec3); pub const Ray = ray.Ray3(f32);
/// Half-precision f16 types /// Half-precision f16 types
pub const Vec2h = vec.Vec(2, f16); pub const Vec2h = vec.Vec2(f16);
pub const Vec3h = vec.Vec(3, f16); pub const Vec3h = vec.Vec3(f16);
pub const Vec4h = vec.Vec(4, f16); pub const Vec4h = vec.Vec4(f16);
pub const Quath = q.Quat(f16); pub const Quath = q.Quat(f16);
pub const Mat2x2h = mat.Mat(2, 2, Vec2h); pub const Mat2x2h = mat.Mat2x2(f16);
pub const Mat3x3h = mat.Mat(3, 3, Vec3h); pub const Mat3x3h = mat.Mat3x3(f16);
pub const Mat4x4h = mat.Mat(4, 4, Vec4h); pub const Mat4x4h = mat.Mat4x4(f16);
pub const Rayh = ray.Ray(Vec3h); pub const Rayh = ray.Ray3(f16);
/// Double-precision f64 types /// Double-precision f64 types
pub const Vec2d = vec.Vec(2, f64); pub const Vec2d = vec.Vec2(f64);
pub const Vec3d = vec.Vec(3, f64); pub const Vec3d = vec.Vec3(f64);
pub const Vec4d = vec.Vec(4, f64); pub const Vec4d = vec.Vec4(f64);
pub const Quatd = q.Quat(f64); pub const Quatd = q.Quat(f64);
pub const Mat2x2d = mat.Mat(2, 2, Vec2d); pub const Mat2x2d = mat.Mat2x2(f64);
pub const Mat3x3d = mat.Mat(3, 3, Vec3d); pub const Mat3x3d = mat.Mat3x3(f64);
pub const Mat4x4d = mat.Mat(4, 4, Vec4d); pub const Mat4x4d = mat.Mat4x4(f64);
pub const Rayd = ray.Ray(Vec3d); pub const Rayd = ray.Ray3(f64);
/// Standard f32 precision initializers /// Standard f32 precision initializers
pub const vec2 = Vec2.init; pub const vec2 = Vec2.init;

View file

@ -3,10 +3,8 @@ const testing = mach.testing;
const math = mach.math; const math = mach.math;
const vec = @import("vec.zig"); const vec = @import("vec.zig");
pub fn Mat( pub fn Mat2x2(
comptime n_cols: usize, comptime Scalar: type,
comptime n_rows: usize,
comptime Vector: type,
) type { ) type {
return extern struct { return extern struct {
/// The column vectors of the matrix. /// The column vectors of the matrix.
@ -28,47 +26,33 @@ pub fn Mat(
v: [cols]Vec, v: [cols]Vec,
/// The number of columns, e.g. Mat3x4.cols == 3 /// The number of columns, e.g. Mat3x4.cols == 3
pub const cols = n_cols; pub const cols = 2;
/// The number of rows, e.g. Mat3x4.rows == 4 /// The number of rows, e.g. Mat3x4.rows == 4
pub const rows = n_rows; pub const rows = 2;
/// The scalar type of this matrix, e.g. Mat3x3.T == f32 /// The scalar type of this matrix, e.g. Mat3x3.T == f32
pub const T = Vector.T; pub const T = Scalar;
/// The underlying Vec type, e.g. Mat3x3.Vec == Vec3 /// The underlying Vec type, e.g. Mat3x3.Vec == Vec3
pub const Vec = Vector; pub const Vec = vec.Vec2(Scalar);
/// The Vec type corresponding to the number of rows, e.g. Mat3x3.RowVec == Vec3 /// The Vec type corresponding to the number of rows, e.g. Mat3x3.RowVec == Vec3
pub const RowVec = vec.Vec(rows, T); pub const RowVec = Vec;
/// The Vec type corresponding to the numebr of cols, e.g. Mat3x4.ColVec = Vec4 /// The Vec type corresponding to the numebr of cols, e.g. Mat3x4.ColVec = Vec4
pub const ColVec = vec.Vec(cols, T); pub const ColVec = Vec;
const Matrix = @This(); const Matrix = @This();
const Shared = MatShared(RowVec, ColVec, Matrix);
/// Identity matrix /// Identity matrix
pub const ident = switch (Matrix) { pub const ident = Matrix.init(
inline math.Mat2x2, math.Mat2x2h, math.Mat2x2d => Matrix.init(
&RowVec.init(1, 0), &RowVec.init(1, 0),
&RowVec.init(0, 1), &RowVec.init(0, 1),
), );
inline math.Mat3x3, math.Mat3x3h, math.Mat3x3d => Matrix.init(
&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),
),
else => @compileError("Expected Mat3x3, Mat4x4 found '" ++ @typeName(Matrix) ++ "'"),
};
pub usingnamespace switch (Matrix) {
inline math.Mat2x2, math.Mat2x2h, math.Mat2x2d => struct {
/// Constructs a 2x2 matrix with the given rows. For example to write a translation /// Constructs a 2x2 matrix with the given rows. For example to write a translation
/// matrix like in the left part of this equation: /// matrix like in the left part of this equation:
/// ///
@ -131,8 +115,63 @@ pub fn Mat(
&RowVec.init(0, 1), &RowVec.init(0, 1),
); );
} }
},
inline math.Mat3x3, math.Mat3x3h, math.Mat3x3d => struct { pub const mul = Shared.mul;
pub const mulVec = Shared.mulVec;
};
}
pub fn Mat3x3(
comptime Scalar: type,
) type {
return extern struct {
/// The column vectors of the matrix.
///
/// Mach matrices use [column-major storage and column-vectors](https://machengine.org/engine/math/matrix-storage/).
/// The translation vector is stored in contiguous memory elements 12, 13, 14:
///
/// ```
/// [4]Vec4{
/// vec4( 1, 0, 0, 0),
/// vec4( 0, 1, 0, 0),
/// vec4( 0, 0, 1, 0),
/// vec4(tx, ty, tz, tw),
/// }
/// ```
///
/// Use the init() constructor to write code which visually matches the same layout as you'd
/// see used in scientific / maths communities.
v: [cols]Vec,
/// The number of columns, e.g. Mat3x4.cols == 3
pub const cols = 3;
/// The number of rows, e.g. Mat3x4.rows == 4
pub const rows = 3;
/// The scalar type of this matrix, e.g. Mat3x3.T == f32
pub const T = Scalar;
/// The underlying Vec type, e.g. Mat3x3.Vec == Vec3
pub const Vec = vec.Vec3(Scalar);
/// The Vec type corresponding to the number of rows, e.g. Mat3x3.RowVec == Vec3
pub const RowVec = Vec;
/// The Vec type corresponding to the numebr of cols, e.g. Mat3x4.ColVec = Vec4
pub const ColVec = Vec;
const Matrix = @This();
const Shared = MatShared(RowVec, ColVec, Matrix);
/// Identity matrix
pub const ident = Matrix.init(
&RowVec.init(1, 0, 0),
&RowVec.init(0, 1, 0),
&RowVec.init(0, 0, 1),
);
/// Constructs a 3x3 matrix with the given rows. For example to write a translation /// Constructs a 3x3 matrix with the given rows. For example to write a translation
/// matrix like in the left part of this equation: /// matrix like in the left part of this equation:
/// ///
@ -216,8 +255,64 @@ pub fn Mat(
pub inline fn translation(t: Matrix) math.Vec2 { pub inline fn translation(t: Matrix) math.Vec2 {
return math.Vec2.init(t.v[2].x(), t.v[2].y()); return math.Vec2.init(t.v[2].x(), t.v[2].y());
} }
},
inline math.Mat4x4, math.Mat4x4h, math.Mat4x4d => struct { pub const mul = Shared.mul;
pub const mulVec = Shared.mulVec;
};
}
pub fn Mat4x4(
comptime Scalar: type,
) type {
return extern struct {
/// The column vectors of the matrix.
///
/// Mach matrices use [column-major storage and column-vectors](https://machengine.org/engine/math/matrix-storage/).
/// The translation vector is stored in contiguous memory elements 12, 13, 14:
///
/// ```
/// [4]Vec4{
/// vec4( 1, 0, 0, 0),
/// vec4( 0, 1, 0, 0),
/// vec4( 0, 0, 1, 0),
/// vec4(tx, ty, tz, tw),
/// }
/// ```
///
/// Use the init() constructor to write code which visually matches the same layout as you'd
/// see used in scientific / maths communities.
v: [cols]Vec,
/// The number of columns, e.g. Mat3x4.cols == 3
pub const cols = 4;
/// The number of rows, e.g. Mat3x4.rows == 4
pub const rows = 4;
/// The scalar type of this matrix, e.g. Mat3x3.T == f32
pub const T = Scalar;
/// The underlying Vec type, e.g. Mat3x3.Vec == Vec3
pub const Vec = vec.Vec4(Scalar);
/// The Vec type corresponding to the number of rows, e.g. Mat3x3.RowVec == Vec3
pub const RowVec = Vec;
/// The Vec type corresponding to the numebr of cols, e.g. Mat3x4.ColVec = Vec4
pub const ColVec = Vec;
const Matrix = @This();
const Shared = MatShared(RowVec, ColVec, Matrix);
/// Identity matrix
pub const ident = 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),
);
/// Constructs a 4x4 matrix with the given rows. For example to write a translation /// Constructs a 4x4 matrix with the given rows. For example to write a translation
/// matrix like in the left part of this equation: /// matrix like in the left part of this equation:
/// ///
@ -385,10 +480,14 @@ pub fn Mat(
))); )));
return p; return p;
} }
},
else => @compileError("Expected Mat3x3, Mat4x4 found '" ++ @typeName(Matrix) ++ "'"),
};
pub const mul = Shared.mul;
pub const mulVec = Shared.mulVec;
};
}
pub fn MatShared(comptime RowVec: type, comptime ColVec: type, comptime Matrix: type) type {
return struct {
/// Matrix multiplication a*b /// Matrix multiplication a*b
pub inline fn mul(a: *const Matrix, b: *const Matrix) Matrix { pub inline fn mul(a: *const Matrix, b: *const Matrix) Matrix {
@setEvalBranchQuota(10000); @setEvalBranchQuota(10000);
@ -417,7 +516,7 @@ pub fn Mat(
result[i] += matrix.v[row].v[i] * vector.v[row]; result[i] += matrix.v[row].v[i] * vector.v[row];
} }
} }
return vec.Vec(ColVec.n, ColVec.T){ .v = result }; return ColVec{ .v = result };
} }
// TODO: the below code was correct in our old implementation, it just needs to be updated // TODO: the below code was correct in our old implementation, it just needs to be updated

View file

@ -6,16 +6,16 @@ const mat = @import("mat.zig");
pub fn Quat(comptime Scalar: type) type { pub fn Quat(comptime Scalar: type) type {
return extern struct { return extern struct {
v: vec.Vec(4, Scalar), v: vec.Vec4(Scalar),
/// The scalar type of this matrix, e.g. Mat3x3.T == f32 /// The scalar type of this matrix, e.g. Mat3x3.T == f32
pub const T = Vec.T; pub const T = Vec.T;
/// The underlying Vec type, e.g. math.Vec4, math.Vec4h, math.Vec4d /// The underlying Vec type, e.g. math.Vec4, math.Vec4h, math.Vec4d
pub const Vec = vec.Vec(4, Scalar); pub const Vec = vec.Vec4(Scalar);
/// The Vec type used to represent axes, e.g. math.Vec3 /// The Vec type used to represent axes, e.g. math.Vec3
pub const Axis = vec.Vec(3, Scalar); pub const Axis = vec.Vec3(Scalar);
/// Creates a quaternion from the given x, y, z, and w values /// Creates a quaternion from the given x, y, z, and w values
pub inline fn init(x: T, y: T, z: T, w: T) Quat(T) { pub inline fn init(x: T, y: T, z: T, w: T) Quat(T) {

View file

@ -4,7 +4,9 @@ const math = mach.math;
const vec = @import("vec.zig"); const vec = @import("vec.zig");
// A Ray in three-dimensional space // A Ray in three-dimensional space
pub fn Ray(comptime Vec3P: type) type { pub fn Ray3(comptime Scalar: type) type {
const Vec3P = vec.Vec3(Scalar);
// Floating point precision, will be either f16, f32, or f64 // Floating point precision, will be either f16, f32, or f64
const P: type = Vec3P.T; const P: type = Vec3P.T;
@ -34,8 +36,6 @@ pub fn Ray(comptime Vec3P: type) type {
/// and w represents hit distance t /// and w represents hit distance t
pub const Hit = Vec4P; pub const Hit = Vec4P;
pub usingnamespace switch (Vec3P) {
math.Vec3, math.Vec3h, math.Vec3d => struct {
// Determine the 3D vector dimension with the largest scalar // Determine the 3D vector dimension with the largest scalar
// value // value
fn maxDim(v: [3]P) u8 { fn maxDim(v: [3]P) u8 {
@ -63,7 +63,7 @@ pub fn Ray(comptime Vec3P: type) type {
/// On hit, will return a RayHit which contains distance t /// On hit, will return a RayHit which contains distance t
/// and barycentric coordinates. /// and barycentric coordinates.
pub inline fn triangleIntersect( pub inline fn triangleIntersect(
ray: *const Ray(Vec3P), ray: *const Ray3(P),
va: *const Vec3P, va: *const Vec3P,
vb: *const Vec3P, vb: *const Vec3P,
vc: *const Vec3P, vc: *const Vec3P,
@ -183,10 +183,6 @@ pub fn Ray(comptime Vec3P: type) type {
return hit; return hit;
} }
},
else => @compileError("Expected Vec3, Vec3h, or Vec3d, found '" ++
@typeName(Vec3P) ++ "'"),
};
}; };
} }

View file

@ -8,23 +8,23 @@ const quat = @import("quat.zig");
pub const VecComponent = enum { x, y, z, w }; pub const VecComponent = enum { x, y, z, w };
pub fn Vec(comptime n_value: usize, comptime Scalar: type) type { pub fn Vec2(comptime Scalar: type) type {
return extern struct { return extern struct {
v: Vector, v: Vector,
/// The vector dimension size, e.g. Vec3.n == 3 /// The vector dimension size, e.g. Vec3.n == 3
pub const n = n_value; pub const n = 2;
/// The scalar type of this vector, e.g. Vec3.T == f32 /// The scalar type of this vector, e.g. Vec3.T == f32
pub const T = Scalar; pub const T = Scalar;
// The underlying @Vector type // The underlying @Vector type
pub const Vector = @Vector(n_value, Scalar); pub const Vector = @Vector(n, Scalar);
const VecN = @This(); const VecN = @This();
pub usingnamespace switch (VecN.n) { const Shared = VecShared(Scalar, VecN);
inline 2 => struct {
pub inline fn init(xs: Scalar, ys: Scalar) VecN { pub inline fn init(xs: Scalar, ys: Scalar) VecN {
return .{ .v = .{ xs, ys } }; return .{ .v = .{ xs, ys } };
} }
@ -37,8 +37,56 @@ pub fn Vec(comptime n_value: usize, comptime Scalar: type) type {
pub inline fn y(v: *const VecN) Scalar { pub inline fn y(v: *const VecN) Scalar {
return v.v[1]; return v.v[1];
} }
},
inline 3 => struct { pub const add = Shared.add;
pub const sub = Shared.sub;
pub const div = Shared.div;
pub const mul = Shared.mul;
pub const addScalar = Shared.addScalar;
pub const subScalar = Shared.subScalar;
pub const divScalar = Shared.divScalar;
pub const mulScalar = Shared.mulScalar;
pub const less = Shared.less;
pub const lessEq = Shared.lessEq;
pub const greater = Shared.greater;
pub const greaterEq = Shared.greaterEq;
pub const splat = Shared.splat;
pub const len2 = Shared.len2;
pub const len = Shared.len;
pub const normalize = Shared.normalize;
pub const dir = Shared.dir;
pub const dist2 = Shared.dist2;
pub const dist = Shared.dist;
pub const lerp = Shared.lerp;
pub const dot = Shared.dot;
pub const max = Shared.max;
pub const min = Shared.min;
pub const inverse = Shared.inverse;
pub const negate = Shared.negate;
pub const maxScalar = Shared.maxScalar;
pub const minScalar = Shared.minScalar;
pub const eqlApprox = Shared.eqlApprox;
pub const eql = Shared.eql;
};
}
pub fn Vec3(comptime Scalar: type) type {
return extern struct {
v: Vector,
/// The vector dimension size, e.g. Vec3.n == 3
pub const n = 3;
/// The scalar type of this vector, e.g. Vec3.T == f32
pub const T = Scalar;
// The underlying @Vector type
pub const Vector = @Vector(n, Scalar);
const VecN = @This();
const Shared = VecShared(Scalar, VecN);
pub inline fn init(xs: Scalar, ys: Scalar, zs: Scalar) VecN { pub inline fn init(xs: Scalar, ys: Scalar, zs: Scalar) VecN {
return .{ .v = .{ xs, ys, zs } }; return .{ .v = .{ xs, ys, zs } };
} }
@ -80,7 +128,7 @@ pub fn Vec(comptime n_value: usize, comptime Scalar: type) type {
} }
/// Vector * Matrix multiplication /// Vector * Matrix multiplication
pub inline fn mulMat(vector: *const VecN, matrix: *const mat.Mat(3, 3, Vec(3, T))) VecN { pub inline fn mulMat(vector: *const VecN, matrix: *const mat.Mat3x3(T)) VecN {
var result = [_]VecN.T{0} ** 3; var result = [_]VecN.T{0} ** 3;
inline for (0..3) |i| { inline for (0..3) |i| {
inline for (0..3) |j| { inline for (0..3) |j| {
@ -112,8 +160,56 @@ pub fn Vec(comptime n_value: usize, comptime Scalar: type) type {
vz + uv_z * w2 + (qz * uv_y - qy * uv_x) * 2, vz + uv_z * w2 + (qz * uv_y - qy * uv_x) * 2,
); );
} }
},
inline 4 => struct { pub const add = Shared.add;
pub const sub = Shared.sub;
pub const div = Shared.div;
pub const mul = Shared.mul;
pub const addScalar = Shared.addScalar;
pub const subScalar = Shared.subScalar;
pub const divScalar = Shared.divScalar;
pub const mulScalar = Shared.mulScalar;
pub const less = Shared.less;
pub const lessEq = Shared.lessEq;
pub const greater = Shared.greater;
pub const greaterEq = Shared.greaterEq;
pub const splat = Shared.splat;
pub const len2 = Shared.len2;
pub const len = Shared.len;
pub const normalize = Shared.normalize;
pub const dir = Shared.dir;
pub const dist2 = Shared.dist2;
pub const dist = Shared.dist;
pub const lerp = Shared.lerp;
pub const dot = Shared.dot;
pub const max = Shared.max;
pub const min = Shared.min;
pub const inverse = Shared.inverse;
pub const negate = Shared.negate;
pub const maxScalar = Shared.maxScalar;
pub const minScalar = Shared.minScalar;
pub const eqlApprox = Shared.eqlApprox;
pub const eql = Shared.eql;
};
}
pub fn Vec4(comptime Scalar: type) type {
return extern struct {
v: Vector,
/// The vector dimension size, e.g. Vec3.n == 3
pub const n = 4;
/// The scalar type of this vector, e.g. Vec3.T == f32
pub const T = Scalar;
// The underlying @Vector type
pub const Vector = @Vector(n, Scalar);
const VecN = @This();
const Shared = VecShared(Scalar, VecN);
pub inline fn init(xs: Scalar, ys: Scalar, zs: Scalar, ws: Scalar) VecN { pub inline fn init(xs: Scalar, ys: Scalar, zs: Scalar, ws: Scalar) VecN {
return .{ .v = .{ xs, ys, zs, ws } }; return .{ .v = .{ xs, ys, zs, ws } };
} }
@ -134,7 +230,7 @@ pub fn Vec(comptime n_value: usize, comptime Scalar: type) type {
} }
/// Vector * Matrix multiplication /// Vector * Matrix multiplication
pub inline fn mulMat(vector: *const VecN, matrix: *const mat.Mat(4, 4, Vec(4, T))) VecN { pub inline fn mulMat(vector: *const VecN, matrix: *const mat.Mat4x4(T)) VecN {
var result = [_]VecN.T{0} ** 4; var result = [_]VecN.T{0} ** 4;
inline for (0..4) |i| { inline for (0..4) |i| {
inline for (0..4) |j| { inline for (0..4) |j| {
@ -143,10 +239,41 @@ pub fn Vec(comptime n_value: usize, comptime Scalar: type) type {
} }
return .{ .v = result }; return .{ .v = result };
} }
},
else => @compileError("Expected Vec2, Vec3, Vec4, found '" ++ @typeName(VecN) ++ "'"),
};
pub const add = Shared.add;
pub const sub = Shared.sub;
pub const div = Shared.div;
pub const mul = Shared.mul;
pub const addScalar = Shared.addScalar;
pub const subScalar = Shared.subScalar;
pub const divScalar = Shared.divScalar;
pub const mulScalar = Shared.mulScalar;
pub const less = Shared.less;
pub const lessEq = Shared.lessEq;
pub const greater = Shared.greater;
pub const greaterEq = Shared.greaterEq;
pub const splat = Shared.splat;
pub const len2 = Shared.len2;
pub const len = Shared.len;
pub const normalize = Shared.normalize;
pub const dir = Shared.dir;
pub const dist2 = Shared.dist2;
pub const dist = Shared.dist;
pub const lerp = Shared.lerp;
pub const dot = Shared.dot;
pub const max = Shared.max;
pub const min = Shared.min;
pub const inverse = Shared.inverse;
pub const negate = Shared.negate;
pub const maxScalar = Shared.maxScalar;
pub const minScalar = Shared.minScalar;
pub const eqlApprox = Shared.eqlApprox;
pub const eql = Shared.eql;
};
}
pub fn VecShared(comptime Scalar: type, comptime VecN: type) type {
return struct {
/// Element-wise addition /// Element-wise addition
pub inline fn add(a: *const VecN, b: *const VecN) VecN { pub inline fn add(a: *const VecN, b: *const VecN) VecN {
return .{ .v = a.v + b.v }; return .{ .v = a.v + b.v };
@ -377,10 +504,10 @@ pub fn Vec(comptime n_value: usize, comptime Scalar: type) type {
/// Checks for approximate (absolute tolerance) equality between two vectors /// Checks for approximate (absolute tolerance) equality between two vectors
/// of the same type and dimensions /// of the same type and dimensions
pub inline fn eqlApprox(a: *const VecN, b: *const VecN, tolerance: T) bool { pub inline fn eqlApprox(a: *const VecN, b: *const VecN, tolerance: Scalar) bool {
var i: usize = 0; var i: usize = 0;
while (i < VecN.n) : (i += 1) { while (i < VecN.n) : (i += 1) {
if (!math.eql(T, a.v[i], b.v[i], tolerance)) { if (!math.eql(Scalar, a.v[i], b.v[i], tolerance)) {
return false; return false;
} }
} }
@ -390,7 +517,7 @@ pub fn Vec(comptime n_value: usize, comptime Scalar: type) type {
/// Checks for approximate (absolute epsilon tolerance) equality /// Checks for approximate (absolute epsilon tolerance) equality
/// between two vectors of the same type and dimensions /// between two vectors of the same type and dimensions
pub inline fn eql(a: *const VecN, b: *const VecN) bool { pub inline fn eql(a: *const VecN, b: *const VecN) bool {
return a.eqlApprox(b, math.eps(T)); return a.eqlApprox(b, math.eps(Scalar));
} }
}; };
} }