ona/src/coral/lina.zig

77 lines
1.8 KiB
Zig

const std = @import("std");
pub fn Matrix(comptime n: usize, comptime Element: type) type {
return [n]@Vector(n, Element);
}
pub const ProjectionMatrix = Matrix(4, f32);
pub const Rect = struct {
left: f32,
top: f32,
right: f32,
bottom: f32,
};
pub fn cross(v1: anytype, v2: anytype) @typeInfo(@TypeOf(v1, v2)).Vector.child {
const multipled = v1 * v2;
const vector_info = @typeInfo(@TypeOf(v1)).Vector;
var result = multipled[0];
comptime var index = @as(usize, 1);
inline while (index < vector_info.len) : (index += 1) {
result -= multipled[index];
}
return result;
}
pub fn distance(v1: anytype, v2: anytype) @typeInfo(@TypeOf(v1, v2)).Vector.child {
return length(v1 - v2);
}
pub fn dot(v1: anytype, v2: anytype) @typeInfo(@TypeOf(v1, v2)).Vector.child {
const multipled = v1 * v2;
const vector_info = @typeInfo(@TypeOf(v1)).Vector;
var result = multipled[0];
comptime var index = @as(usize, 1);
inline while (index < vector_info.len) : (index += 1) {
result += multipled[index];
}
return result;
}
pub fn length(v: anytype) @typeInfo(@TypeOf(v)).Vector.child {
return @sqrt(length_squared(v));
}
pub fn length_squared(v: anytype) @typeInfo(@TypeOf(v)).Vector.child {
return dot(v, v);
}
pub fn normal(v: anytype) @TypeOf(v) {
const ls = length_squared(v);
const Vector = @TypeOf(v);
if (ls > std.math.floatEps(@typeInfo(Vector).Vector.child)) {
return v / @as(Vector, @splat(@sqrt(ls)));
}
return v;
}
pub fn orthographic_projection(near: f32, far: f32, viewport: Rect) Matrix(4, f32) {
const width = viewport.right - viewport.left;
const height = viewport.bottom - viewport.top;
return .{
.{2 / width, 0, 0, 0},
.{0, 2 / height, 0, 0},
.{0, 0, 1 / (far - near), 0},
.{-((viewport.left + viewport.right) / width), -((viewport.top + viewport.bottom) / height), near / (near - far), 1},
};
}