128 lines
3.2 KiB
Rust

use crate::math::{ Vec3 };
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct Mat4 {
pub data: [f32; 16],
}
impl Mat4 {
pub fn identity() -> Self {
Self {
data: [
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0,
],
}
}
pub fn translation(x: f32, y: f32, z: f32) -> Self {
Self {
data: [
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
x, y, z, 1.0,
],
}
}
pub fn scale(x: f32, y: f32, z: f32) -> Self {
Self {
data: [
x, 0.0, 0.0, 0.0,
0.0, y, 0.0, 0.0,
0.0, 0.0, z, 0.0,
0.0, 0.0, 0.0, 1.0,
],
}
}
pub fn rotation_x(angle: f32) -> Self {
let c = angle.cos();
let s = angle.sin();
Self {
data: [
1.0, 0.0, 0.0, 0.0,
0.0, c, s, 0.0,
0.0, -s, c, 0.0,
0.0, 0.0, 0.0, 1.0,
],
}
}
pub fn rotation_y(angle: f32) -> Self {
let c = angle.cos();
let s = angle.sin();
Self {
data: [
c, 0.0, -s, 0.0,
0.0, 1.0, 0.0, 0.0,
s, 0.0, c, 0.0,
0.0, 0.0, 0.0, 1.0,
],
}
}
pub fn rotation_z(angle: f32) -> Self {
let c = angle.cos();
let s = angle.sin();
Self {
data: [
c, s, 0.0, 0.0,
-s, c, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0,
],
}
}
pub fn perspective(fov: f32, aspect: f32, near: f32, far: f32) -> Self {
let f = 1.0 / (fov / 2.0).tan();
let nf = 1.0 / (near - far);
Self {
data: [
f / aspect, 0.0, 0.0, 0.0,
0.0, f, 0.0, 0.0,
0.0, 0.0, (far + near) * nf, -1.0,
0.0, 0.0, 2.0 * far * near * nf, 0.0,
],
}
}
pub fn look_at(eye: Vec3, target: Vec3, up: Vec3) -> Self {
let f = (target - eye).normalize();
let r = f.cross(&up).normalize();
let u = r.cross(&f);
Self {
data: [
r.x, u.x, -f.x, 0.0,
r.y, u.y, -f.y, 0.0,
r.z, u.z, -f.z, 0.0,
-r.dot(&eye), -u.dot(&eye), f.dot(&eye), 1.0,
],
}
}
pub fn as_ptr(&self) -> *const f32 {
self.data.as_ptr()
}
}
impl std::ops::Mul for Mat4 {
type Output = Self;
fn mul(self, rhs: Self) -> Self {
let mut result = [0.0f32; 16];
for row in 0..4 {
for col in 0..4 {
for k in 0..4 {
result[col * 4 + row] += self.data[k * 4 + row] * rhs.data[col * 4 + k];
}
}
}
Self { data: result }
}
}