math: Implement Vec swizzle method

This commit is contained in:
Joel D. Schüller 2023-09-23 23:34:15 +02:00 committed by Stephen Gutekanst
parent f6213a4237
commit a3671ab0ef

View file

@ -5,6 +5,7 @@ const testing = mach.testing;
const math = mach.math; const math = mach.math;
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 Vec(comptime n_value: usize, comptime Scalar: type) type {
return extern struct { return extern struct {
v: Vector, v: Vector,
@ -46,20 +47,27 @@ pub fn Vec(comptime n_value: usize, comptime Scalar: type) type {
return v.v[2]; return v.v[2];
} }
// TODO(math): come up with a better strategy for swizzling? pub inline fn swizzle(
pub inline fn yzx(v: *const VecN) VecN { v: *const VecN,
return VecN.init(v.y(), v.z(), v.x()); xc: VecComponent,
} yc: VecComponent,
pub inline fn zxy(v: *const VecN) VecN { zc: VecComponent,
return VecN.init(v.z(), v.x(), v.y()); ) VecN {
return .{ .v = @shuffle(VecN.T, v.v, undefined, [3]T{
@intFromEnum(xc),
@intFromEnum(yc),
@intFromEnum(zc),
}) };
} }
/// Calculates the cross product between vector a and b. This can be done only in 3D /// Calculates the cross product between vector a and b.
/// and required inputs are Vec3. /// This can be done only in 3D and required inputs are Vec3.
pub inline fn cross(a: *const VecN, b: *const VecN) VecN { pub inline fn cross(a: *const VecN, b: *const VecN) VecN {
// https://gamemath.com/book/vectors.html#cross_product // https://gamemath.com/book/vectors.html#cross_product
const s1 = a.yzx().mul(&b.zxy()); const s1 = a.swizzle(.y, .z, .x)
const s2 = a.zxy().mul(&b.yzx()); .mul(&b.swizzle(.z, .x, .y));
const s2 = a.swizzle(.z, .x, .y)
.mul(&b.swizzle(.y, .z, .x));
return s1.sub(&s2); return s1.sub(&s2);
} }
}, },