|
|
|
use bytemuck::{Pod, Zeroable};
|
|
|
|
use nalgebra::Vector4;
|
|
|
|
use rapier3d::parry::math::Point;
|
|
|
|
|
|
|
|
#[repr(C)]
|
|
|
|
#[derive(Clone, Copy, Debug)]
|
|
|
|
pub struct Vertex {
|
|
|
|
pos: [f32; 4],
|
|
|
|
normal: [f32; 4],
|
|
|
|
uv: [f32; 2],
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Vertex {
|
|
|
|
pub fn position(&self) -> Point<f32> {
|
|
|
|
Point::<f32>::new(self.pos[0], self.pos[1], self.pos[2])
|
|
|
|
}
|
|
|
|
pub fn from(pos: [f32; 3], nor: [f32; 3], uv: [f32; 2]) -> Vertex {
|
|
|
|
Vertex {
|
|
|
|
pos: [pos[0], pos[1], pos[2], 1.0],
|
|
|
|
normal: [nor[0], nor[1], nor[2], 0.0],
|
|
|
|
uv: [uv[0], uv[1]],
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe impl Pod for Vertex {}
|
|
|
|
unsafe impl Zeroable for Vertex {}
|
|
|
|
|
|
|
|
#[derive(Clone, Debug)]
|
|
|
|
pub struct RawMesh {
|
|
|
|
pub vertices: Vec<Vertex>,
|
|
|
|
pub indices: Vec<[u32; 3]>,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn load_obj(obj_path: &str) -> RawMesh {
|
|
|
|
|
|
|
|
let (models, materials) = tobj::load_obj(obj_path, true).expect("Failed to load file");
|
|
|
|
|
|
|
|
println!("# of models: {}", models.len());
|
|
|
|
println!("# of materials: {}", materials.len());
|
|
|
|
|
|
|
|
println!("{:?}", materials);
|
|
|
|
|
|
|
|
let mut index_data: Vec<[u32; 3]> = Vec::new();
|
|
|
|
let mut vertex_data = Vec::new();
|
|
|
|
|
|
|
|
for model in models {
|
|
|
|
let mesh = &model.mesh;
|
|
|
|
|
|
|
|
// Cycle through the faces and chunk out the indices
|
|
|
|
let mut next_face = 0;
|
|
|
|
for f in 0..mesh.num_face_indices.len() {
|
|
|
|
// calculate the next chunk
|
|
|
|
let end = next_face + mesh.num_face_indices[f] as usize;
|
|
|
|
let face_indices: Vec<_> = mesh.indices[next_face..end].iter().collect();
|
|
|
|
|
|
|
|
assert!(face_indices.len() == 3, "we only handle triangulated faces");
|
|
|
|
index_data.push([*face_indices[0], *face_indices[1], *face_indices[2]]);
|
|
|
|
|
|
|
|
next_face = end;
|
|
|
|
}
|
|
|
|
|
|
|
|
assert!(mesh.positions.len() % 3 == 0);
|
|
|
|
assert!(mesh.texcoords.len() % 2 == 0);
|
|
|
|
|
|
|
|
for v in 0..mesh.positions.len() / 3 {
|
|
|
|
let texcoords = if mesh.texcoords.len() == 0 {
|
|
|
|
[0.0, 0.0]
|
|
|
|
} else {
|
|
|
|
[mesh.texcoords[2 * v], mesh.texcoords[2 * v + 1]]
|
|
|
|
};
|
|
|
|
|
|
|
|
vertex_data.push(Vertex::from(
|
|
|
|
[
|
|
|
|
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],
|
|
|
|
],
|
|
|
|
texcoords,
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
RawMesh {
|
|
|
|
vertices: vertex_data.to_vec(),
|
|
|
|
indices: index_data.to_vec(),
|
|
|
|
}
|
|
|
|
}
|