128 lines
3.2 KiB
Rust
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 }
|
|
}
|
|
}
|