better to use a struct for the raw mesh data

master
mitchellhansen 4 years ago
parent e5815ce0d6
commit 85376e5b17

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

@ -330,25 +330,18 @@ pub fn load_colliding_mesh_entity(world: &mut World, renderer: &mut render::stat
.build(); .build();
//let pair = import_mesh("./resources/terrain.obj"); //let pair = import_mesh("./resources/terrain.obj");
let pair = load_obj(mesh_path); let raw_mesh = load_obj(mesh_path);
let floor_collider = ColliderBuilder::trimesh( let floor_collider = ColliderBuilder::trimesh(
pair.0 raw_mesh.vertices
.iter() .iter()
.map(|v| { .map(|v| v.position())
let position = v.position();
Point::<f32>::new(position.x, position.y, position.z)
})
.collect(), .collect(),
pair.1 raw_mesh.indices
.chunks(3) ).build();
.map(|v| [v[0], v[1], v[2]])
.collect(),
)
.build();
let plane_mesh = renderer.load_mesh_to_buffer( let plane_mesh = renderer.load_mesh_to_buffer(
"./resources/terrain.obj", mesh_path,
Some(wgpu::Color { Some(wgpu::Color {
r: 1.0, r: 1.0,
g: 0.7, g: 0.7,
@ -389,6 +382,7 @@ pub fn entity_loading(world: &mut World, renderer: &mut render::state::RenderSta
let ball_mesh = 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));
load_colliding_mesh_entity(world, renderer, "./resources/test-textured.obj");
let camera_ent: Entity = world.push(( let camera_ent: Entity = world.push((
Camera { Camera {
@ -459,21 +453,17 @@ pub fn entity_loading(world: &mut World, renderer: &mut render::state::RenderSta
.build(); .build();
let pair = load_obj("./resources/ball.obj"); let raw_mesh = load_obj("./resources/ball.obj");
let ball_collider = ColliderBuilder::trimesh( let ball_collider = ColliderBuilder::trimesh(
pair.0 raw_mesh.vertices
.iter() .iter()
.map(|v| { .map(|v| {
let position = v.position(); let position = v.position();
Point::<f32>::new(position.x, position.y, position.z) Point::<f32>::new(position.x, position.y, position.z)
}) })
.collect(), .collect(),
pair.1 raw_mesh.indices,
//.iter()
.chunks(3)
.map(|v| [v[0], v[1], v[2]])
.collect(),
) )
.build(); .build();

@ -26,7 +26,7 @@ use winit_24::window::Window;
use crate::camera::{Camera, CameraController}; use crate::camera::{Camera, CameraController};
use crate::components::{Mesh, Position, RangeCopy}; use crate::components::{Mesh, Position, RangeCopy};
use crate::current_ui; 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::imgui_supp::imgui_support::{ImguiContext, ImguiPlatform};
use crate::light::{DirectionalLight, LightRaw}; use crate::light::{DirectionalLight, LightRaw};
use crate::render::{EntityUniforms, ShadowUniforms, ForwardUniforms}; use crate::render::{EntityUniforms, ShadowUniforms, ForwardUniforms};
@ -112,21 +112,30 @@ impl RenderState {
/// TODO I really should remove this / consolidate it /// TODO I really should remove this / consolidate it
fn create_buffer( fn create_buffer(
device: &wgpu::Device, device: &wgpu::Device,
indices: Vec<u32>, raw_mesh: RawMesh,
vertices: Vec<Vertex>,
) -> (Arc<Buffer>, Arc<Buffer>) { ) -> (Arc<Buffer>, Arc<Buffer>) {
let vertex_buf = Arc::new( let vertex_buf = Arc::new(
device.create_buffer_init(&wgpu::util::BufferInitDescriptor { device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some("vertex-buffer"), label: Some("vertex-buffer"),
contents: bytemuck::cast_slice(&vertices), contents: bytemuck::cast_slice(&raw_mesh.vertices),
usage: wgpu::BufferUsage::VERTEX, usage: wgpu::BufferUsage::VERTEX,
}), }),
); );
//println!("{:x?}", raw_mesh.indices);
// let mut hack = Vec::<u32>::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( let index_buf = Arc::new(
device.create_buffer_init(&wgpu::util::BufferInitDescriptor { device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some("index-buffer"), label: Some("index-buffer"),
contents: bytemuck::cast_slice(&indices), contents: bytemuck::cast_slice(&raw_mesh.indices),
usage: wgpu::BufferUsage::INDEX, usage: wgpu::BufferUsage::INDEX,
}), }),
); );
@ -134,11 +143,16 @@ impl RenderState {
(vertex_buf, index_buf) (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<wgpu::Color>) -> Mesh { pub fn load_mesh_to_buffer(&self, filepath: &str, color: Option<wgpu::Color>) -> Mesh {
let (vertices, indices) = load_obj(filepath); let raw_mesh = load_obj(filepath);
let index_count = indices.len(); 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::<EntityUniforms>() as wgpu::BufferAddress; let uniform_size = mem::size_of::<EntityUniforms>() as wgpu::BufferAddress;

Loading…
Cancel
Save