Refactor math for no good reason; I just really like math
This commit is contained in:
@@ -17,6 +17,8 @@ pub const Matrix4x4 = extern struct {
|
||||
// zig fmt: on
|
||||
);
|
||||
|
||||
// --- INIT ---
|
||||
|
||||
pub inline fn init(
|
||||
// zig fmt: off
|
||||
ix: f32, iy: f32, iz: f32, iw: f32,
|
||||
@@ -26,147 +28,173 @@ pub const Matrix4x4 = extern struct {
|
||||
// zig fmt: on
|
||||
) Matrix4x4 {
|
||||
return .{
|
||||
.i = .{ .vector = .{ ix, iy, iz, iw } },
|
||||
.j = .{ .vector = .{ jx, jy, jz, jw } },
|
||||
.k = .{ .vector = .{ kx, ky, kz, kw } },
|
||||
.t = .{ .vector = .{ tx, ty, tz, tw } },
|
||||
.i = .init(ix, iy, iz, iw),
|
||||
.j = .init(jx, jy, jz, jw),
|
||||
.k = .init(kx, ky, kz, kw),
|
||||
.t = .init(tx, ty, tz, tw),
|
||||
};
|
||||
}
|
||||
|
||||
pub inline fn initVector(i: Vector4, j: Vector4, k: Vector4, t: Vector4) Matrix4x4 {
|
||||
pub inline fn initArray(array: [16]f32) Matrix4x4 {
|
||||
return .{
|
||||
.i = .initArray(array[0..4].*),
|
||||
.j = .initArray(array[4..8].*),
|
||||
.k = .initArray(array[8..12].*),
|
||||
.t = .initArray(array[12..16].*),
|
||||
};
|
||||
}
|
||||
|
||||
pub inline fn initVector4(i: Vector4, j: Vector4, k: Vector4, t: Vector4) Matrix4x4 {
|
||||
return .{ .i = i, .j = j, .k = k, .t = t };
|
||||
}
|
||||
|
||||
pub inline fn initTranslation(translation: Vector3) Matrix4x4 {
|
||||
return .{
|
||||
.i = .{ .vector = .{ 1, 0, 0, 0 } },
|
||||
.j = .{ .vector = .{ 0, 1, 0, 0 } },
|
||||
.k = .{ .vector = .{ 0, 0, 1, 0 } },
|
||||
.t = .{ .vector = translation.vector ++ .{1} },
|
||||
};
|
||||
return .initVector4(
|
||||
.unit_x,
|
||||
.unit_y,
|
||||
.unit_z,
|
||||
translation.asVector4(1),
|
||||
);
|
||||
}
|
||||
|
||||
pub inline fn initRotation(rotation: Quaternion) Matrix4x4 {
|
||||
const xx = rotation.getX() * rotation.getX();
|
||||
const xy = rotation.getX() * rotation.getY();
|
||||
const xz = rotation.getX() * rotation.getZ();
|
||||
const xw = rotation.getX() * rotation.getW();
|
||||
const yy = rotation.getY() * rotation.getY();
|
||||
const yz = rotation.getY() * rotation.getZ();
|
||||
const yw = rotation.getY() * rotation.getW();
|
||||
const zz = rotation.getZ() * rotation.getZ();
|
||||
const zw = rotation.getZ() * rotation.getW();
|
||||
const xx = rotation.vector.getX() * rotation.vector.getX();
|
||||
const xy = rotation.vector.getX() * rotation.vector.getY();
|
||||
const xz = rotation.vector.getX() * rotation.vector.getZ();
|
||||
const xw = rotation.vector.getX() * rotation.vector.getW();
|
||||
const yy = rotation.vector.getY() * rotation.vector.getY();
|
||||
const yz = rotation.vector.getY() * rotation.vector.getZ();
|
||||
const yw = rotation.vector.getY() * rotation.vector.getW();
|
||||
const zz = rotation.vector.getZ() * rotation.vector.getZ();
|
||||
const zw = rotation.vector.getZ() * rotation.vector.getW();
|
||||
|
||||
return .{
|
||||
.i = .{ .vector = .{ 1 - 2 * (yy + zz), 2 * (xy + zw), 2 * (xz - yw), 0 } },
|
||||
.j = .{ .vector = .{ 2 * (xy - zw), 1 - 2 * (xx + zz), 2 * (yz + xw), 0 } },
|
||||
.k = .{ .vector = .{ 2 * (xz + yw), 2 * (yz - xw), 1 - 2 * (xx + yy), 0 } },
|
||||
.t = .{ .vector = .{ 0, 0, 0, 1 } },
|
||||
};
|
||||
return .init(
|
||||
// zig fmt: off
|
||||
1 - 2 * (yy + zz), 2 * (xy + zw), 2 * (xz - yw), 0,
|
||||
2 * (xy - zw), 1 - 2 * (xx + zz), 2 * (yz + xw), 0,
|
||||
2 * (xz + yw), 2 * (yz - xw), 1 - 2 * (xx + yy), 0,
|
||||
0, 0, 0, 1,
|
||||
// zig fmt: on
|
||||
);
|
||||
}
|
||||
|
||||
pub inline fn initScale(scale: Vector3) Matrix4x4 {
|
||||
return .{
|
||||
.i = .{ .vector = .{ scale.getX(), 0, 0, 0 } },
|
||||
.j = .{ .vector = .{ 0, scale.getY(), 0, 0 } },
|
||||
.k = .{ .vector = .{ 0, 0, scale.getZ(), 0 } },
|
||||
.t = .{ .vector = .{ 0, 0, 0, 1 } },
|
||||
};
|
||||
return .init(
|
||||
// zig fmt: off
|
||||
scale.getX(), 0, 0, 0,
|
||||
0, scale.getY(), 0, 0,
|
||||
0, 0, scale.getZ(), 0,
|
||||
0, 0, 0, 1,
|
||||
// zig fmt: on
|
||||
);
|
||||
}
|
||||
|
||||
pub inline fn initTranslationRotationScale(translation: Vector3, rotation: Quaternion, scale: Vector3) Matrix4x4 {
|
||||
const xx = rotation.getX() * rotation.getX();
|
||||
const xy = rotation.getX() * rotation.getY();
|
||||
const xz = rotation.getX() * rotation.getZ();
|
||||
const xw = rotation.getX() * rotation.getW();
|
||||
const yy = rotation.getY() * rotation.getY();
|
||||
const yz = rotation.getY() * rotation.getZ();
|
||||
const yw = rotation.getY() * rotation.getW();
|
||||
const zz = rotation.getZ() * rotation.getZ();
|
||||
const zw = rotation.getZ() * rotation.getW();
|
||||
pub inline fn initTranslationRotationScale(
|
||||
translation: Vector3,
|
||||
rotation: Quaternion,
|
||||
scale: Vector3,
|
||||
) Matrix4x4 {
|
||||
const xx = rotation.vector.getX() * rotation.vector.getX();
|
||||
const xy = rotation.vector.getX() * rotation.vector.getY();
|
||||
const xz = rotation.vector.getX() * rotation.vector.getZ();
|
||||
const xw = rotation.vector.getX() * rotation.vector.getW();
|
||||
const yy = rotation.vector.getY() * rotation.vector.getY();
|
||||
const yz = rotation.vector.getY() * rotation.vector.getZ();
|
||||
const yw = rotation.vector.getY() * rotation.vector.getW();
|
||||
const zz = rotation.vector.getZ() * rotation.vector.getZ();
|
||||
const zw = rotation.vector.getZ() * rotation.vector.getW();
|
||||
|
||||
const scale_x: Vector4.Vector = @splat(scale.getX());
|
||||
const scale_y: Vector4.Vector = @splat(scale.getY());
|
||||
const scale_z: Vector4.Vector = @splat(scale.getZ());
|
||||
const rotation_i = Vector4.init((1 - 2 * (yy + zz)), 2 * (xy + zw), 2 * (xz - yw), 0);
|
||||
const rotation_j = Vector4.init(2 * (xy - zw), (1 - 2 * (xx + zz)), 2 * (yz + xw), 0);
|
||||
const rotation_k = Vector4.init(2 * (xz + yw), 2 * (yz - xw), (1 - 2 * (xx + yy)), 0);
|
||||
|
||||
const rotation_i: Vector4.Vector = .{ (1 - 2 * (yy + zz)), 2 * (xy + zw), 2 * (xz - yw), 0 };
|
||||
const rotation_j: Vector4.Vector = .{ 2 * (xy - zw), (1 - 2 * (xx + zz)), 2 * (yz + xw), 0 };
|
||||
const rotation_k: Vector4.Vector = .{ 2 * (xz + yw), 2 * (yz - xw), (1 - 2 * (xx + yy)), 0 };
|
||||
|
||||
return .{
|
||||
.i = .{ .vector = scale_x * rotation_i },
|
||||
.j = .{ .vector = scale_y * rotation_j },
|
||||
.k = .{ .vector = scale_z * rotation_k },
|
||||
.t = .{ .vector = translation.vector ++ .{1} },
|
||||
};
|
||||
return .initVector4(
|
||||
Vector4.mulScalar(rotation_i, scale.getX()),
|
||||
Vector4.mulScalar(rotation_j, scale.getY()),
|
||||
Vector4.mulScalar(rotation_k, scale.getZ()),
|
||||
translation.asVector4(1),
|
||||
);
|
||||
}
|
||||
|
||||
// --- CONVERSION ---
|
||||
|
||||
pub inline fn asArray(self: Matrix4x4) [16]f32 {
|
||||
return self.i.asArray() ++ self.j.asArray() ++ self.k.asArray() ++ self.t.asArray();
|
||||
}
|
||||
|
||||
pub inline fn asVector4(self: Matrix4x4) [4]Vector4 {
|
||||
return .{ self.i, self.j, self.k, self.t };
|
||||
}
|
||||
|
||||
// --- COMPONENT-WISE ---
|
||||
|
||||
pub inline fn add(self: Matrix4x4, other: Matrix4x4) Matrix4x4 {
|
||||
return .{
|
||||
.i = .{ .vector = self.i.vector + other.i.vector },
|
||||
.j = .{ .vector = self.j.vector + other.j.vector },
|
||||
.k = .{ .vector = self.k.vector + other.k.vector },
|
||||
.t = .{ .vector = self.t.vector + other.t.vector },
|
||||
};
|
||||
return .initVector4(
|
||||
Vector4.add(self.i, other.i),
|
||||
Vector4.add(self.j, other.j),
|
||||
Vector4.add(self.k, other.k),
|
||||
Vector4.add(self.t, other.t),
|
||||
);
|
||||
}
|
||||
|
||||
pub inline fn sub(self: Matrix4x4, other: Matrix4x4) Matrix4x4 {
|
||||
return .{
|
||||
.i = .{ .vector = self.i.vector - other.i.vector },
|
||||
.j = .{ .vector = self.j.vector - other.j.vector },
|
||||
.k = .{ .vector = self.k.vector - other.k.vector },
|
||||
.t = .{ .vector = self.t.vector - other.t.vector },
|
||||
};
|
||||
}
|
||||
|
||||
pub inline fn mulScalar(self: Matrix4x4, scalar: f32) Matrix4x4 {
|
||||
const scalar_vector: Vector4.Vector = @splat(scalar);
|
||||
return .{
|
||||
.i = .{ .vector = self.i.vector * scalar_vector },
|
||||
.j = .{ .vector = self.j.vector * scalar_vector },
|
||||
.k = .{ .vector = self.k.vector * scalar_vector },
|
||||
.t = .{ .vector = self.t.vector * scalar_vector },
|
||||
};
|
||||
}
|
||||
|
||||
pub inline fn divScalar(self: Matrix4x4, scalar: f32) Matrix4x4 {
|
||||
const inv_scalar_vector: Vector4.Vector = @splat(1 / scalar);
|
||||
return .{
|
||||
.i = .{ .vector = self.i * inv_scalar_vector },
|
||||
.j = .{ .vector = self.j * inv_scalar_vector },
|
||||
.k = .{ .vector = self.k * inv_scalar_vector },
|
||||
.t = .{ .vector = self.t * inv_scalar_vector },
|
||||
};
|
||||
return .initVector4(
|
||||
Vector4.sub(self.i, other.i),
|
||||
Vector4.sub(self.j, other.j),
|
||||
Vector4.sub(self.k, other.k),
|
||||
Vector4.sub(self.t, other.t),
|
||||
);
|
||||
}
|
||||
|
||||
pub inline fn negate(self: Matrix4x4) Matrix4x4 {
|
||||
return .{
|
||||
.i = .{ .vector = -self.i.vector },
|
||||
.j = .{ .vector = -self.j.vector },
|
||||
.k = .{ .vector = -self.k.vector },
|
||||
.t = .{ .vector = -self.t.vector },
|
||||
};
|
||||
return .initVector4(
|
||||
Vector4.negate(self.i),
|
||||
Vector4.negate(self.j),
|
||||
Vector4.negate(self.k),
|
||||
Vector4.negate(self.t),
|
||||
);
|
||||
}
|
||||
|
||||
pub inline fn mulScalar(self: Matrix4x4, scalar: f32) Matrix4x4 {
|
||||
return .initVector4(
|
||||
Vector4.mulScalar(self.i, scalar),
|
||||
Vector4.mulScalar(self.j, scalar),
|
||||
Vector4.mulScalar(self.k, scalar),
|
||||
Vector4.mulScalar(self.t, scalar),
|
||||
);
|
||||
}
|
||||
|
||||
pub inline fn divScalar(self: Matrix4x4, scalar: f32) Matrix4x4 {
|
||||
const inv_scalar = 1 / scalar;
|
||||
return .initVector4(
|
||||
Vector4.mulScalar(self.i, inv_scalar),
|
||||
Vector4.mulScalar(self.j, inv_scalar),
|
||||
Vector4.mulScalar(self.k, inv_scalar),
|
||||
Vector4.mulScalar(self.t, inv_scalar),
|
||||
);
|
||||
}
|
||||
|
||||
// --- OTHER ---
|
||||
|
||||
pub inline fn mulMatrix(self: Matrix4x4, other: Matrix4x4) Matrix4x4 {
|
||||
return .{
|
||||
.i = self.i.mulScalar(other.i.getX())
|
||||
return .initVector4(
|
||||
self.i.mulScalar(other.i.getX())
|
||||
.add(self.j.mulScalar(other.i.getY()))
|
||||
.add(self.k.mulScalar(other.i.getZ()))
|
||||
.add(self.t.mulScalar(other.i.getW())),
|
||||
.j = self.i.mulScalar(other.j.getX())
|
||||
self.i.mulScalar(other.j.getX())
|
||||
.add(self.j.mulScalar(other.j.getY()))
|
||||
.add(self.k.mulScalar(other.j.getZ()))
|
||||
.add(self.t.mulScalar(other.j.getW())),
|
||||
.k = self.i.mulScalar(other.k.getX())
|
||||
self.i.mulScalar(other.k.getX())
|
||||
.add(self.j.mulScalar(other.k.getY()))
|
||||
.add(self.k.mulScalar(other.k.getZ()))
|
||||
.add(self.t.mulScalar(other.k.getW())),
|
||||
.t = self.i.mulScalar(other.t.getX())
|
||||
self.i.mulScalar(other.t.getX())
|
||||
.add(self.j.mulScalar(other.t.getY()))
|
||||
.add(self.k.mulScalar(other.t.getZ()))
|
||||
.add(self.t.mulScalar(other.t.getW())),
|
||||
};
|
||||
);
|
||||
}
|
||||
|
||||
pub inline fn inverseAffine(self: Matrix4x4) Matrix4x4 {
|
||||
@@ -203,12 +231,12 @@ pub const Matrix4x4 = extern struct {
|
||||
.add(self.k.asVector3().mulScalar(self.t.getZ()))
|
||||
.negate();
|
||||
|
||||
return .{
|
||||
.i = .{ .vector = i ++ .{0} },
|
||||
.j = .{ .vector = j ++ .{0} },
|
||||
.k = .{ .vector = k ++ .{0} },
|
||||
.t = .{ .vector = t ++ .{1} },
|
||||
};
|
||||
return .initVector4(
|
||||
i.asVector4(0),
|
||||
j.asVector4(0),
|
||||
k.asVector4(0),
|
||||
t.asVector4(1),
|
||||
);
|
||||
}
|
||||
|
||||
pub inline fn inverseTransposeAffine(self: Matrix4x4) Matrix4x4 {
|
||||
@@ -245,15 +273,11 @@ pub const Matrix4x4 = extern struct {
|
||||
.add(self.k.asVector3().mulScalar(self.t.getZ()))
|
||||
.negate();
|
||||
|
||||
return .{
|
||||
.i = .{ .vector = i ++ .{0} },
|
||||
.j = .{ .vector = j ++ .{0} },
|
||||
.k = .{ .vector = k ++ .{0} },
|
||||
.t = .{ .vector = t ++ .{1} },
|
||||
};
|
||||
}
|
||||
|
||||
pub inline fn asArray(self: Matrix4x4) [16]f32 {
|
||||
return @bitCast(self);
|
||||
return .initVector4(
|
||||
i.asVector4(0),
|
||||
j.asVector4(0),
|
||||
k.asVector4(0),
|
||||
t.asVector4(1),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user