diff --git a/Cargo.toml b/Cargo.toml index 0a318f2..5af9d22 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ tracing = { version = "0.1", default-features = false, features = ["std"] } typed-arena = "2.0.1" serde = { version = "1", features = ["derive"], optional = true } log = "0.4" +simple_logger = "1.11.0" png = "0.16" #winit = { version = "0.24.0"} rand = { version = "0.7.2", features = ["wasm-bindgen"] } diff --git a/src/geometry.rs b/src/geometry.rs index e53dbaf..5dcc80e 100644 --- a/src/geometry.rs +++ b/src/geometry.rs @@ -1,6 +1,8 @@ use bytemuck::{Pod, Zeroable}; use nalgebra::Vector4; use rapier3d::parry::math::Point; +use tobj::{LoadError, Model, Material}; + #[repr(C)] #[derive(Clone, Copy, Debug)] @@ -32,14 +34,23 @@ pub struct RawMesh { 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"); +/// We use meshes in a few different places. To keep things simple, we return +/// the most basic, direct-to-memory version. If something fancy needs to be done +/// with it, the fancy stays there +pub fn load_obj(obj_path: &str) -> Result { + + log::info!("Loading object {}", obj_path); - println!("# of models: {}", models.len()); - println!("# of materials: {}", materials.len()); + // Is there no better way to translate error messages? + let (models, materials) = match tobj::load_obj(obj_path, true) { + Ok((a, b)) => {Ok((a, b))} + Err(load_error) => {Err(load_error.to_string())} + }.unwrap(); - println!("{:?}", materials); + // 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(); @@ -54,14 +65,22 @@ pub fn load_obj(obj_path: &str) -> RawMesh { 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"); + if face_indices.len() != 3 { + return Err("we only handle triangulated faces".to_string()); + } 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); + if mesh.positions.len() % 3 != 0 { + return Err(format!("position array not % 3 : {}", mesh.positions.len())) + } + if mesh.texcoords.len() % 2 != 0 { + return Err(format!("position array not % 3 : {}", mesh.positions.len())) + } + if mesh.texcoords.is_empty() { + log::info!("Mesh texture coordinates empty") + } for v in 0..mesh.positions.len() / 3 { let texcoords = if mesh.texcoords.len() == 0 { @@ -85,8 +104,8 @@ pub fn load_obj(obj_path: &str) -> RawMesh { )); } } - RawMesh { + Ok(RawMesh { vertices: vertex_data.to_vec(), indices: index_data.to_vec(), - } + }) } diff --git a/src/main.rs b/src/main.rs index a49b3d7..be9ef16 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ extern crate lazy_static; extern crate tobj; extern crate winit_24; +use simple_logger::SimpleLogger; use std::f32::consts::PI; use std::sync::{Arc, Mutex}; #[cfg(not(target_arch = "wasm32"))] @@ -97,6 +98,10 @@ pub unsafe fn current_ui<'a>() -> Option<&'a imgui::Ui<'a>> { } fn main() { + + let logger = SimpleLogger::new().with_level(log::LevelFilter::Info).init().unwrap(); + + let mut world = World::default(); let mut imgui_prepare_schedule = Schedule::builder() @@ -330,7 +335,7 @@ pub fn load_colliding_mesh_entity(world: &mut World, renderer: &mut render::stat .build(); //let pair = import_mesh("./resources/terrain.obj"); - let raw_mesh = load_obj(mesh_path); + let raw_mesh = load_obj(mesh_path).unwrap(); let floor_collider = ColliderBuilder::trimesh( raw_mesh.vertices @@ -348,7 +353,7 @@ pub fn load_colliding_mesh_entity(world: &mut World, renderer: &mut render::stat b: 0.3, a: 1.0, }), - ); + ).unwrap(); let plane_entity: Entity = world.push(( Position { @@ -376,11 +381,11 @@ pub fn load_colliding_mesh_entity(world: &mut World, renderer: &mut render::stat pub fn entity_loading(world: &mut World, renderer: &mut render::state::RenderState) { let monkey_mesh = - renderer.load_mesh_to_buffer("./resources/monkey.obj", Some(wgpu::Color::GREEN)); + renderer.load_mesh_to_buffer("./resources/monkey.obj", Some(wgpu::Color::GREEN)).unwrap(); let light_mesh = - renderer.load_mesh_to_buffer("./resources/light.obj", Some(wgpu::Color::BLACK)); + renderer.load_mesh_to_buffer("./resources/light.obj", Some(wgpu::Color::BLACK)).unwrap(); let ball_mesh = - renderer.load_mesh_to_buffer("./resources/ball.obj", Some(wgpu::Color::BLUE)); + renderer.load_mesh_to_buffer("./resources/ball.obj", Some(wgpu::Color::BLUE)).unwrap(); load_colliding_mesh_entity(world, renderer, "./resources/test-textured.obj"); @@ -453,7 +458,7 @@ pub fn entity_loading(world: &mut World, renderer: &mut render::state::RenderSta .build(); - let raw_mesh = load_obj("./resources/ball.obj"); + let raw_mesh = load_obj("./resources/ball.obj").unwrap(); let ball_collider = ColliderBuilder::trimesh( raw_mesh.vertices diff --git a/src/physics/system.rs b/src/physics/system.rs index 8767fff..699b900 100644 --- a/src/physics/system.rs +++ b/src/physics/system.rs @@ -116,10 +116,5 @@ pub fn update_models( position.rot.x = rotation.x.into(); position.rot.y = rotation.y.into(); position.rot.z = rotation.z.into(); - - // mx.x = pos.rotation.i; - // mx.y = pos.rotation.j; - // mx.z = pos.rotation.k; - // mx.w = pos.rotation.w; } } diff --git a/src/render/state.rs b/src/render/state.rs index 7f1ccc0..eedd769 100644 --- a/src/render/state.rs +++ b/src/render/state.rs @@ -148,8 +148,9 @@ impl RenderState { } - pub fn load_mesh_to_buffer(&self, filepath: &str, color: Option) -> Mesh { - let raw_mesh = load_obj(filepath); + pub fn load_mesh_to_buffer(&self, filepath: &str, color: Option) -> Result { + + let raw_mesh = load_obj(filepath)?; let index_count = raw_mesh.indices.len() * 3; // TODO bad bad bad bad! let (vertex_buf, index_buf) = RenderState::create_buffer(&self.device, raw_mesh); @@ -176,7 +177,7 @@ impl RenderState { }], })); - Mesh { + Ok(Mesh { index_buffer: index_buf, index_count: index_count, // TODO: This is hardcoded by tobj, maybe think about doing something a little more clever? @@ -185,7 +186,7 @@ impl RenderState { uniform_buffer: uniform_buf, bind_group: bind_group, color: color.unwrap_or(wgpu::Color::RED), - } + }) } /// When creating a light we have to give it a target view to render to