Extract the mesh loader
This commit is contained in:
parent
2ec43c822d
commit
af5322a47e
96
src/main.rs
96
src/main.rs
|
|
@ -1,3 +1,5 @@
|
||||||
|
mod mesh_loader;
|
||||||
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::{env, io};
|
use std::{env, io};
|
||||||
use std::f32::consts::PI;
|
use std::f32::consts::PI;
|
||||||
|
|
@ -6,96 +8,7 @@ use std::io::Write;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use glm;
|
use glm;
|
||||||
use glm::{dot, ivec2, IVec2, ivec3, to_ivec3, vec2, Vec2, Vec3};
|
use glm::{dot, ivec2, IVec2, ivec3, to_ivec3, vec2, Vec2, Vec3};
|
||||||
|
use crate::mesh_loader::load_mesh;
|
||||||
#[derive(Copy, Clone, Debug)]
|
|
||||||
struct ObjVertex {
|
|
||||||
vertex: usize,
|
|
||||||
normal: usize,
|
|
||||||
tex_coord: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
|
||||||
struct ObjFace {
|
|
||||||
vertices: [ObjVertex; 3],
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct ObjMesh {
|
|
||||||
vertices: Vec<Vec3>,
|
|
||||||
normals: Vec<Vec3>,
|
|
||||||
tex_coords: Vec<Vec2>,
|
|
||||||
faces: Vec<ObjFace>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ObjMesh {
|
|
||||||
fn parse_v2(tokens: &[&str]) -> Vec2 {
|
|
||||||
assert_eq!(tokens.len(), 2);
|
|
||||||
let tokens: Vec<_> = tokens.iter().map(|&t| t.parse().unwrap()).collect();
|
|
||||||
vec2(tokens[0], tokens[1])
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_v3(tokens: &[&str]) -> Vec3 {
|
|
||||||
assert_eq!(tokens.len(), 3);
|
|
||||||
let tokens: Vec<_> = tokens.iter().map(|&t| t.parse().unwrap()).collect();
|
|
||||||
glm::vec3(tokens[0], tokens[1], tokens[2])
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_fv(desc: &&str) -> ObjVertex {
|
|
||||||
let tokens: Vec<_> = desc.split('/').map(|s| s.parse::<usize>().unwrap() - 1).collect();
|
|
||||||
assert_eq!(tokens.len(), 3);
|
|
||||||
ObjVertex { vertex: tokens[0], tex_coord: tokens[1], normal: tokens[2] }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_f(tokens: &[&str]) -> ObjFace {
|
|
||||||
let vertices: Vec<_> = tokens.iter().map(ObjMesh::parse_fv).collect();
|
|
||||||
ObjFace { vertices: vertices.as_slice().try_into().unwrap() }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read(f: &mut impl BufRead) -> io::Result<ObjMesh> {
|
|
||||||
let mut result = ObjMesh {
|
|
||||||
vertices: Vec::new(),
|
|
||||||
normals: Vec::new(),
|
|
||||||
tex_coords: Vec::new(),
|
|
||||||
faces: Vec::new(),
|
|
||||||
};
|
|
||||||
loop {
|
|
||||||
let mut line = String::new();
|
|
||||||
if f.read_line(&mut line)? == 0 {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
let tokens: Vec<&str> = line
|
|
||||||
.trim()
|
|
||||||
.split('#')
|
|
||||||
.next()
|
|
||||||
.unwrap()
|
|
||||||
.split(' ')
|
|
||||||
.collect();
|
|
||||||
match tokens[0] {
|
|
||||||
"v" => result.vertices.push(Self::parse_v3(&tokens[1..])),
|
|
||||||
"vn" => result.normals.push(Self::parse_v3(&tokens[1..])),
|
|
||||||
"vt" => result.tex_coords.push(Self::parse_v2(&tokens[1..])),
|
|
||||||
"f" => result.faces.push(Self::parse_f(&tokens[1..])),
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn flatten(&self) -> Vec<Face> {
|
|
||||||
self.faces.iter().map(|face| {
|
|
||||||
Face {
|
|
||||||
vertices: face.vertices.map(|iv| self.vertices[iv.vertex]),
|
|
||||||
normal: self.normals[face.vertices[0].normal],
|
|
||||||
}
|
|
||||||
}).collect()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
|
||||||
struct Face {
|
|
||||||
vertices: [Vec3; 3],
|
|
||||||
normal: Vec3,
|
|
||||||
}
|
|
||||||
|
|
||||||
const W: i32 = 800;
|
const W: i32 = 800;
|
||||||
const H: i32 = 600;
|
const H: i32 = 600;
|
||||||
|
|
@ -171,8 +84,7 @@ fn main() -> io::Result<()> {
|
||||||
let mesh = {
|
let mesh = {
|
||||||
let f = File::open(&args[1])?;
|
let f = File::open(&args[1])?;
|
||||||
let mut f = BufReader::new(f);
|
let mut f = BufReader::new(f);
|
||||||
ObjMesh::read(&mut f)?
|
load_mesh(&mut f)?
|
||||||
.flatten()
|
|
||||||
};
|
};
|
||||||
let mut img = Image {
|
let mut img = Image {
|
||||||
w: W,
|
w: W,
|
||||||
|
|
|
||||||
96
src/mesh_loader.rs
Normal file
96
src/mesh_loader.rs
Normal file
|
|
@ -0,0 +1,96 @@
|
||||||
|
use std::io;
|
||||||
|
use glm::{vec2, vec3, Vec2, Vec3};
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
struct ObjVertex {
|
||||||
|
vertex: usize,
|
||||||
|
normal: usize,
|
||||||
|
tex_coord: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
struct ObjFace {
|
||||||
|
vertices: [ObjVertex; 3],
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct ObjMesh {
|
||||||
|
vertices: Vec<Vec3>,
|
||||||
|
normals: Vec<Vec3>,
|
||||||
|
tex_coords: Vec<Vec2>,
|
||||||
|
faces: Vec<ObjFace>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ObjMesh {
|
||||||
|
fn parse_v2(tokens: &[&str]) -> Vec2 {
|
||||||
|
assert_eq!(tokens.len(), 2);
|
||||||
|
let tokens: Vec<_> = tokens.iter().map(|&t| t.parse().unwrap()).collect();
|
||||||
|
vec2(tokens[0], tokens[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_v3(tokens: &[&str]) -> Vec3 {
|
||||||
|
assert_eq!(tokens.len(), 3);
|
||||||
|
let tokens: Vec<_> = tokens.iter().map(|&t| t.parse().unwrap()).collect();
|
||||||
|
vec3(tokens[0], tokens[1], tokens[2])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_fv(desc: &&str) -> ObjVertex {
|
||||||
|
let tokens: Vec<_> = desc.split('/').map(|s| s.parse::<usize>().unwrap() - 1).collect();
|
||||||
|
assert_eq!(tokens.len(), 3);
|
||||||
|
ObjVertex { vertex: tokens[0], tex_coord: tokens[1], normal: tokens[2] }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_f(tokens: &[&str]) -> ObjFace {
|
||||||
|
let vertices: Vec<_> = tokens.iter().map(ObjMesh::parse_fv).collect();
|
||||||
|
ObjFace { vertices: vertices.as_slice().try_into().unwrap() }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read(f: &mut impl io::BufRead) -> io::Result<ObjMesh> {
|
||||||
|
let mut result = ObjMesh {
|
||||||
|
vertices: Vec::new(),
|
||||||
|
normals: Vec::new(),
|
||||||
|
tex_coords: Vec::new(),
|
||||||
|
faces: Vec::new(),
|
||||||
|
};
|
||||||
|
loop {
|
||||||
|
let mut line = String::new();
|
||||||
|
if f.read_line(&mut line)? == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let tokens: Vec<&str> = line
|
||||||
|
.trim()
|
||||||
|
.split('#')
|
||||||
|
.next()
|
||||||
|
.unwrap()
|
||||||
|
.split(' ')
|
||||||
|
.collect();
|
||||||
|
match tokens[0] {
|
||||||
|
"v" => result.vertices.push(Self::parse_v3(&tokens[1..])),
|
||||||
|
"vn" => result.normals.push(Self::parse_v3(&tokens[1..])),
|
||||||
|
"vt" => result.tex_coords.push(Self::parse_v2(&tokens[1..])),
|
||||||
|
"f" => result.faces.push(Self::parse_f(&tokens[1..])),
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flatten(&self) -> Vec<Face> {
|
||||||
|
self.faces.iter().map(|face| {
|
||||||
|
Face {
|
||||||
|
vertices: face.vertices.map(|iv| self.vertices[iv.vertex]),
|
||||||
|
normal: self.normals[face.vertices[0].normal],
|
||||||
|
}
|
||||||
|
}).collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
pub struct Face {
|
||||||
|
pub vertices: [Vec3; 3],
|
||||||
|
pub normal: Vec3,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load_mesh(f: &mut impl io::BufRead) -> io::Result<Vec<Face>> {
|
||||||
|
Ok(ObjMesh::read(f)?.flatten())
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user