From 85376e5b17c91d2fffdc00dad83a18de228e495a Mon Sep 17 00:00:00 2001 From: mitchellhansen Date: Fri, 19 Feb 2021 21:18:47 -0800 Subject: [PATCH] better to use a struct for the raw mesh data --- src/geometry.rs | 30 +++++++++++++++++++----------- src/main.rs | 30 ++++++++++-------------------- src/render/state.rs | 30 ++++++++++++++++++++++-------- 3 files changed, 51 insertions(+), 39 deletions(-) diff --git a/src/geometry.rs b/src/geometry.rs index 0a6e6ca..e53dbaf 100644 --- a/src/geometry.rs +++ b/src/geometry.rs @@ -1,5 +1,6 @@ use bytemuck::{Pod, Zeroable}; use nalgebra::Vector4; +use rapier3d::parry::math::Point; #[repr(C)] #[derive(Clone, Copy, Debug)] @@ -10,14 +11,14 @@ pub struct Vertex { } impl Vertex { - pub fn position(&self) -> Vector4 { - Vector4::new(self.pos[0], self.pos[1], self.pos[2], self.pos[3]) + pub fn position(&self) -> Point { + Point::::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: [0.0, 0.0], + uv: [uv[0], uv[1]], } } } @@ -27,31 +28,35 @@ unsafe impl Zeroable for Vertex {} #[derive(Clone, Debug)] pub struct RawMesh { - vertices: Vec, - normals: Vec<[u32; 3]>, + pub vertices: Vec, + pub indices: Vec<[u32; 3]>, } -pub fn load_obj(obj_path: &str, mtl_path: Option<&str>) -> (Vec, Vec) { +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 = Vec::new(); + 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(); - for i in face_indices { - index_data.push(*i); - } + 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; } @@ -80,5 +85,8 @@ pub fn load_obj(obj_path: &str, mtl_path: Option<&str>) -> (Vec, Vec::new(position.x, position.y, position.z) - }) + .map(|v| v.position()) .collect(), - pair.1 - .chunks(3) - .map(|v| [v[0], v[1], v[2]]) - .collect(), - ) - .build(); + raw_mesh.indices + ).build(); let plane_mesh = renderer.load_mesh_to_buffer( - "./resources/terrain.obj", + mesh_path, Some(wgpu::Color { r: 1.0, g: 0.7, @@ -389,6 +382,7 @@ pub fn entity_loading(world: &mut World, renderer: &mut render::state::RenderSta let ball_mesh = renderer.load_mesh_to_buffer("./resources/ball.obj", Some(wgpu::Color::BLUE)); + load_colliding_mesh_entity(world, renderer, "./resources/test-textured.obj"); let camera_ent: Entity = world.push(( Camera { @@ -459,21 +453,17 @@ pub fn entity_loading(world: &mut World, renderer: &mut render::state::RenderSta .build(); - let pair = load_obj("./resources/ball.obj"); + let raw_mesh = load_obj("./resources/ball.obj"); let ball_collider = ColliderBuilder::trimesh( - pair.0 + raw_mesh.vertices .iter() .map(|v| { let position = v.position(); Point::::new(position.x, position.y, position.z) }) .collect(), - pair.1 - //.iter() - .chunks(3) - .map(|v| [v[0], v[1], v[2]]) - .collect(), + raw_mesh.indices, ) .build(); diff --git a/src/render/state.rs b/src/render/state.rs index 5f7de43..7f1ccc0 100644 --- a/src/render/state.rs +++ b/src/render/state.rs @@ -26,7 +26,7 @@ use winit_24::window::Window; use crate::camera::{Camera, CameraController}; use crate::components::{Mesh, Position, RangeCopy}; use crate::current_ui; -use crate::geometry::{load_obj, Vertex}; +use crate::geometry::{load_obj, Vertex, RawMesh}; use crate::imgui_supp::imgui_support::{ImguiContext, ImguiPlatform}; use crate::light::{DirectionalLight, LightRaw}; use crate::render::{EntityUniforms, ShadowUniforms, ForwardUniforms}; @@ -112,21 +112,30 @@ impl RenderState { /// TODO I really should remove this / consolidate it fn create_buffer( device: &wgpu::Device, - indices: Vec, - vertices: Vec, + raw_mesh: RawMesh, ) -> (Arc, Arc) { let vertex_buf = Arc::new( device.create_buffer_init(&wgpu::util::BufferInitDescriptor { label: Some("vertex-buffer"), - contents: bytemuck::cast_slice(&vertices), + contents: bytemuck::cast_slice(&raw_mesh.vertices), usage: wgpu::BufferUsage::VERTEX, }), ); + //println!("{:x?}", raw_mesh.indices); + + + // let mut hack = Vec::::new(); + // for ind_chunk in raw_mesh.indices { + // hack.push(ind_chunk[0]); + // hack.push(ind_chunk[1]); + // hack.push(ind_chunk[2]); + // } + let index_buf = Arc::new( device.create_buffer_init(&wgpu::util::BufferInitDescriptor { label: Some("index-buffer"), - contents: bytemuck::cast_slice(&indices), + contents: bytemuck::cast_slice(&raw_mesh.indices), usage: wgpu::BufferUsage::INDEX, }), ); @@ -134,11 +143,16 @@ impl RenderState { (vertex_buf, index_buf) } + /// Take a meshes + pub fn upload_mesh_to_buffer(mesh: RawMesh) { + + } + pub fn load_mesh_to_buffer(&self, filepath: &str, color: Option) -> Mesh { - let (vertices, indices) = load_obj(filepath); - let index_count = indices.len(); + 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, indices, vertices); + let (vertex_buf, index_buf) = RenderState::create_buffer(&self.device, raw_mesh); let uniform_size = mem::size_of::() as wgpu::BufferAddress;