|
|
|
use bytemuck::{Pod, Zeroable};
|
|
|
|
|
|
|
|
#[repr(C)]
|
|
|
|
#[derive(Clone, Copy, Debug)]
|
|
|
|
pub struct Vertex {
|
|
|
|
_pos: [f32; 4],
|
|
|
|
_normal: [f32; 4],
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe impl Pod for Vertex {}
|
|
|
|
|
|
|
|
unsafe impl Zeroable for Vertex {}
|
|
|
|
|
|
|
|
pub fn vertex(pos: [f32; 3], nor: [f32; 3]) -> Vertex {
|
|
|
|
Vertex {
|
|
|
|
_pos: [pos[0], pos[1], pos[2], 1.0],
|
|
|
|
_normal: [nor[0], nor[1], nor[2], 0.0],
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn import_mesh(mesh_path: &str) -> (Vec<Vertex>, Vec<u32>) {
|
|
|
|
|
|
|
|
let (models, materials) = tobj::load_obj(mesh_path, false).expect("Failed to load file");
|
|
|
|
|
|
|
|
println!("# of models: {}", models.len());
|
|
|
|
println!("# of materials: {}", materials.len());
|
|
|
|
|
|
|
|
let mut index_data : Vec<u32> = Vec::new();
|
|
|
|
let mut vertex_data = Vec::new();
|
|
|
|
|
|
|
|
for model in models {
|
|
|
|
let mesh = &model.mesh;
|
|
|
|
let mut next_face = 0;
|
|
|
|
for f in 0..mesh.num_face_indices.len() {
|
|
|
|
let end = next_face + mesh.num_face_indices[f] as usize;
|
|
|
|
let face_indices: Vec<_> = mesh.indices[next_face..end].iter().collect();
|
|
|
|
|
|
|
|
for i in face_indices {
|
|
|
|
index_data.push(*i);
|
|
|
|
}
|
|
|
|
next_face = end;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Normals and texture coordinates are also loaded, but not printed in this example
|
|
|
|
assert!(mesh.positions.len() % 3 == 0);
|
|
|
|
|
|
|
|
for v in 0..mesh.positions.len() / 3 {
|
|
|
|
vertex_data.push(
|
|
|
|
vertex([
|
|
|
|
mesh.positions[3 * v],
|
|
|
|
mesh.positions[3 * v + 1],
|
|
|
|
mesh.positions[3 * v + 2]
|
|
|
|
],
|
|
|
|
[
|
|
|
|
mesh.normals[3 * v],
|
|
|
|
mesh.normals[3 * v + 1],
|
|
|
|
mesh.normals[3 * v + 2]
|
|
|
|
],
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
(vertex_data.to_vec(), index_data.to_vec())
|
|
|
|
|
|
|
|
}
|