Port to GLAM

This commit is contained in:
numzero 2024-07-02 12:00:51 +03:00
parent 09299b05a4
commit 97c089a7bc
3 changed files with 25 additions and 28 deletions

View File

@ -10,5 +10,5 @@ opt-level = 3
[dependencies] [dependencies]
rand = "0.8.5" rand = "0.8.5"
glm = "0.2.3" glam = "0.27.0"
show-image = "0.14.0" show-image = "0.14.0"

View File

@ -5,7 +5,7 @@ use std::{env};
use std::error::Error; use std::error::Error;
use std::f32::consts::PI; use std::f32::consts::PI;
use std::io::{BufReader}; use std::io::{BufReader};
use glm::*; use glam::*;
use show_image::{ImageInfo, ImageView, WindowOptions}; use show_image::{ImageInfo, ImageView, WindowOptions};
use crate::mesh_loader::{Face, load_mesh}; use crate::mesh_loader::{Face, load_mesh};
@ -40,17 +40,17 @@ impl Image {
fn ypr_to_mat(ypr: Vec3) -> Mat3 { fn ypr_to_mat(ypr: Vec3) -> Mat3 {
let Vec3 { x: yaw, y: pitch, z: roll } = ypr; let Vec3 { x: yaw, y: pitch, z: roll } = ypr;
let m_roll = mat3( let m_roll = mat3(
roll.cos(), roll.sin(), 0.0, vec3(roll.cos(), roll.sin(), 0.0),
-roll.sin(), roll.cos(), 0.0, vec3(-roll.sin(), roll.cos(), 0.0),
0.0, 0.0, 1.0); vec3(0.0, 0.0, 1.0));
let m_yaw = mat3( let m_yaw = mat3(
yaw.cos(), 0.0, yaw.sin(), vec3(yaw.cos(), 0.0, yaw.sin()),
0.0, 1.0, 0.0, vec3(0.0, 1.0, 0.0),
-yaw.sin(), 0.0, yaw.cos()); vec3(-yaw.sin(), 0.0, yaw.cos()));
let m_pitch = mat3( let m_pitch = mat3(
1.0, 0.0, 0.0, vec3(1.0, 0.0, 0.0),
0.0, pitch.cos(), -pitch.sin(), vec3(0.0, pitch.cos(), -pitch.sin()),
0.0, pitch.sin(), pitch.cos()); vec3(0.0, pitch.sin(), pitch.cos()));
m_roll * m_pitch * m_yaw m_roll * m_pitch * m_yaw
} }
@ -67,8 +67,8 @@ fn trace_to_mesh(mesh: &Mesh, base: Vec3, ray: Vec3) -> Option<TraceResult> {
for f in mesh { for f in mesh {
let fs = (0..3).map(|k| edge_dist(f.vertices[k], f.vertices[(k + 1) % 3], base, ray)); let fs = (0..3).map(|k| edge_dist(f.vertices[k], f.vertices[(k + 1) % 3], base, ray));
if fs.into_iter().all(|f| f >= 0.0) { if fs.into_iter().all(|f| f >= 0.0) {
let m = Mat3 { c0: f.vertices[1] - f.vertices[0], c1: f.vertices[2] - f.vertices[0], c2: -ray }; let m = mat3(f.vertices[1] - f.vertices[0], f.vertices[2] - f.vertices[0], -ray);
if let Some(m) = m.inverse() { let m = m.inverse();
let rel = m * (base - f.vertices[0]); let rel = m * (base - f.vertices[0]);
if rel.z > dist { if rel.z > dist {
continue; continue;
@ -78,9 +78,6 @@ fn trace_to_mesh(mesh: &Mesh, base: Vec3, ray: Vec3) -> Option<TraceResult> {
distance: rel.z, distance: rel.z,
normal: f.normal, normal: f.normal,
}); });
} else {
continue;
}
} }
} }
ret ret
@ -104,13 +101,13 @@ fn render(mesh: &Mesh, camera: impl Fn(Vec2) -> (Vec3, Vec3)) -> Image {
let img_coords = vec2(x as f32, y as f32); let img_coords = vec2(x as f32, y as f32);
let off = (img_coords - img_size * 0.5) / img_size.y; let off = (img_coords - img_size * 0.5) / img_size.y;
let (base, ray) = camera(off); let (base, ray) = camera(off);
let color = if let Some(r) = trace_to_mesh(mesh, base, normalize(ray)) { let color = if let Some(r) = trace_to_mesh(mesh, base, ray.normalize()) {
// to_vec3(0.45) * dot(r.normal, normalize(vec3(-1.0, 1.0, -1.0))) + 0.50 // to_vec3(0.45) * dot(r.normal, normalize(vec3(-1.0, 1.0, -1.0))) + 0.50
r.normal * 0.45 + 0.50 r.normal * 0.45 + 0.50
} else { } else {
bkg bkg
}; };
let color = clamp_s(to_ivec3(color * 255.0), 0, 255); let color = (color * 255.0).as_ivec3().clamp(IVec3::splat(0), IVec3::splat(255));
img.put_pixel(x, y, Color(color.x as u8, color.y as u8, color.z as u8)); img.put_pixel(x, y, Color(color.x as u8, color.y as u8, color.z as u8));
} }
} }
@ -129,7 +126,7 @@ fn main() -> Result<(), Box<dyn Error>> {
loop { loop {
for phi in 0..360 { for phi in 0..360 {
let m_view = ypr_to_mat(vec3((135.0 + phi as f32) * PI / 180.0, -30.0 * PI / 180.0, 0.0f32)); let m_view = ypr_to_mat(vec3((135.0 + phi as f32) * PI / 180.0, -30.0 * PI / 180.0, 0.0f32));
let m_camera = transpose(&m_view); let m_camera = m_view.transpose();
let img = render(mesh.as_slice(), |off| { let img = render(mesh.as_slice(), |off| {
// perspective projection // perspective projection
let base = vec3(0.0, 0.0, -40.0); let base = vec3(0.0, 0.0, -40.0);
@ -150,5 +147,5 @@ fn main() -> Result<(), Box<dyn Error>> {
fn edge_dist(a: Vec3, b: Vec3, base: Vec3, dir: Vec3) -> f32 { fn edge_dist(a: Vec3, b: Vec3, base: Vec3, dir: Vec3) -> f32 {
// Note: given that the input is not arbitrary but comes from a cartesian product of certain (a, b) pairs and certain (base, dir) pairs, this can be optimized from Cnm to an+bm+cnm with c<C. // Note: given that the input is not arbitrary but comes from a cartesian product of certain (a, b) pairs and certain (base, dir) pairs, this can be optimized from Cnm to an+bm+cnm with c<C.
Mat3 { c0: b - a, c1: base - a, c2: -dir }.determinant() mat3(b - a, base - a, -dir).determinant()
} }

View File

@ -1,5 +1,5 @@
use std::io; use std::io;
use glm::{vec2, vec3, Vec2, Vec3}; use glam::{vec2, vec3, Vec2, Vec3};
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
struct ObjVertex { struct ObjVertex {