gltf
This commit is contained in:
@@ -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.");
|
||||
}
|
||||
|
||||
|
||||
100
src/mesh.rs
100
src/mesh.rs
@@ -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)
|
||||
}
|
||||
Reference in New Issue
Block a user