This commit is contained in:
2019-08-01 00:59:42 +02:00
parent 205536ce55
commit cbf26b3045
6 changed files with 170 additions and 162 deletions

View File

@@ -29,7 +29,7 @@ impl Game for TestGame {
impl TestGame {
fn game_start(self: &mut Self, renderer: &mut VulkanRenderer) {
self.cube_mesh = Some(renderer.upload_mesh(mesh::load_mesh("models/cube.dae", self.log_config.mesh_load_info).into_iter().nth(0).unwrap()));
self.cube_mesh = Some(renderer.upload_mesh(mesh::load_mesh("models/box.gltf", self.log_config.mesh_load_info).unwrap().into_iter().nth(0).unwrap()));
println!("Game started.");
}

View File

@@ -1,62 +1,64 @@
use crate::vulkan::Vertex;
use std::path::Path;
use std::time::SystemTime;
pub struct CPUMesh {
pub(crate) vertices: Vec<Vertex>,
pub(crate) indices: Vec<u32>,
}
pub fn load_mesh(mesh_path: &str, print_status: bool) -> Vec<CPUMesh> {
struct TempVertex {
pos: Option<[f32; 3]>,
uv: Option<[f32; 2]>,
normal: Option<[f32; 3]>,
pub fn load_mesh(mesh_path: &str, print_status: bool) -> Result<Vec<CPUMesh>, gltf::Error> {
let mut start_time = None;
let mut total_vertices = 0;
let mut total_indices = 0;
if print_status {
start_time = Some(SystemTime::now());
println!("Loading mesh file {}", mesh_path);
}
let (document, buffers, _textures) = gltf::import(mesh_path)?;
let mut meshes = vec![];
if print_status { println!("Mesh file loaded after {} seconds, processing...", start_time.unwrap().elapsed().unwrap().as_secs()); }
for mesh in document.meshes() {
for primitive in mesh.primitives() {
let reader = primitive.reader(|buffer| Some(&buffers[buffer.index()]));
match (reader.read_indices(), reader.read_positions(), reader.read_tex_coords(0), reader.read_normals()) {
(Some(indices), Some(positions), Some(tex_coords), Some(normals)) => {
let vertices = positions.zip(tex_coords.into_f32()).zip(normals).map(|((p, t), n)| Vertex {
position: p,
uv: t,
normal: n
}).collect();
let cpu_mesh = CPUMesh { vertices, indices: indices.into_u32().collect() };
if print_status {
let vert_count = cpu_mesh.vertices.len();
let index_count = cpu_mesh.indices.len();
println!("Loaded mesh {} after {} seconds: {} Vertices, {} Indices",
mesh.name().unwrap_or(""),
start_time.unwrap().elapsed().unwrap().as_secs(),
vert_count,
index_count);
total_vertices += vert_count;
total_indices += index_count;
}
meshes.push(cpu_mesh);
},
(None, _, _, _) => println!("Indices missing!"),
(_, None, _, _) => println!("Vertex positions missing!"),
(_, _, None, _) => println!("Tex coords missing!"),
(_, _, _, None) => println!("Normals missing!"),
}
}
}
if print_status {
println!("Start loading file {}", mesh_path);
println!("Finished loading file, total vertices: {}, total indices: {}", total_vertices, total_indices);
}
let file = collada::document::ColladaDocument::from_path(Path::new(mesh_path)).unwrap();
file.get_obj_set().unwrap().objects.iter().map(|model| {
if print_status {
println!("Loading mesh {}: {} Vertices", model.name, model.vertices.len());
}
let mut vertices: Vec<TempVertex> = model.vertices.iter().map(|v| {
TempVertex {
pos: Some([v.x as f32, v.y as f32, v.z as f32]),
uv: None,
normal: None
}
}).collect();
let mut indices = Vec::new();
model.geometry.iter().for_each(|geometry| geometry.mesh.iter().for_each(|primitive| {
if let collada::PrimitiveElement::Triangles(tris) = primitive {
tris.vertices.iter().for_each(|tri| {
[tri.0, tri.1, tri.2].iter().for_each(|(vertex_index, texture_position_index, normal_index)| {
indices.push(*vertex_index as u32);
vertices[*vertex_index].uv = texture_position_index.or(None).map(|tpi| {
let tex_vertex = model.tex_vertices[tpi];
[tex_vertex.x as f32, 1.0 - tex_vertex.y as f32]
});
vertices[*vertex_index].normal = normal_index.or(None).map(|ni| {
let normal = model.normals[ni];
[normal.x as f32, normal.y as f32, normal.z as f32]
});
});
});
} else {
panic!("Mesh format Polylist not supported!");
}
}));
let finished_vertices = vertices.iter().map(|v| Vertex {
position: v.pos.unwrap(),
uv: v.uv.unwrap(),
normal: v.normal.unwrap(),
}).collect();
CPUMesh { vertices: finished_vertices, indices }
}).collect()
Ok(meshes)
}