diff --git a/.idea/runConfigurations/debug.xml b/.idea/runConfigurations/debug.xml
index 780dcc7..4f5023b 100644
--- a/.idea/runConfigurations/debug.xml
+++ b/.idea/runConfigurations/debug.xml
@@ -9,7 +9,7 @@
-
+
diff --git a/.idea/runConfigurations/release.xml b/.idea/runConfigurations/release.xml
index b9e0a97..340ff2c 100644
--- a/.idea/runConfigurations/release.xml
+++ b/.idea/runConfigurations/release.xml
@@ -8,6 +8,9 @@
-
+
+
+
+
\ No newline at end of file
diff --git a/shaders/triangle.vert b/shaders/triangle.vert
index 9089c8f..bb6484e 100644
--- a/shaders/triangle.vert
+++ b/shaders/triangle.vert
@@ -11,11 +11,14 @@ layout(binding = 0) uniform ObjectUniformData {
float time;
vec3 light_position;
vec3 camera_position;
+
} ubo;
layout(location = 0) in vec3 position;
layout(location = 1) in vec2 uv;
layout(location = 2) in vec3 normal;
+layout(location = 3) in ivec4 bone_index;
+layout(location = 4) in vec4 bone_weight;
layout(location = 0) out vec2 tex_coords;
layout(location = 1) out vec3 normal_wld;
diff --git a/src/mesh.rs b/src/mesh.rs
index 304ade1..0ec5ed8 100644
--- a/src/mesh.rs
+++ b/src/mesh.rs
@@ -1,7 +1,30 @@
use crate::vulkan::Vertex;
use std::time::SystemTime;
+use gltf::mesh::util::{ReadPositions, ReadTexCoords, ReadNormals, ReadJoints, ReadWeights};
+use gltf::Error;
+use crate::mesh::LoadError::{GltfError, MeshDataMissing, NoIndices};
+#[derive(Debug)]
+pub enum LoadError {
+ GltfError(gltf::Error),
+ MeshDataMissing(String),
+ NoIndices
+}
+
+impl From for LoadError {
+ fn from(e: Error) -> Self {
+ GltfError(e)
+ }
+}
+
+impl From for LoadError {
+ fn from(e: String) -> Self {
+ MeshDataMissing(e)
+ }
+}
+
+#[derive(Debug)]
pub struct CPUMesh {
pub vertices: Vec,
pub indices: Vec,
@@ -9,7 +32,7 @@ pub struct CPUMesh {
pub name: Option,
}
-pub fn load_mesh(mesh_path: &str, print_status: bool) -> Result<(Vec, Vec), gltf::Error> {
+pub fn load_mesh(mesh_path: &str, print_status: bool) -> Result<(Vec, Vec), LoadError> {
let mut start_time = None;
let mut total_vertices = 0;
let mut total_indices = 0;
@@ -28,39 +51,29 @@ pub fn load_mesh(mesh_path: &str, print_status: bool) -> Result<(Vec, V
let texture_index = primitive.material().pbr_metallic_roughness().base_color_texture().map(|tex_info| tex_info.texture().index());
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(),
- texture_index,
- name: mesh.name().map(|n| n.to_owned()),
- };
- if print_status {
- let vert_count = cpu_mesh.vertices.len();
- let index_count = cpu_mesh.indices.len();
+ let indices = reader.read_indices().ok_or(NoIndices)?;
+ let vertices_result = create_vertices(reader.read_positions(), reader.read_tex_coords(0), reader.read_normals(), reader.read_joints(0), reader.read_weights(0));
+ let vertices = vertices_result?;
+ let cpu_mesh = CPUMesh {
+ vertices,
+ indices: indices.into_u32().collect(),
+ texture_index,
+ name: mesh.name().map(|n| n.to_owned()),
+ };
+ 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);
+ 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!"),
+ total_vertices += vert_count;
+ total_indices += index_count;
}
+ meshes.push(cpu_mesh);
}
}
@@ -69,4 +82,58 @@ pub fn load_mesh(mesh_path: &str, print_status: bool) -> Result<(Vec, V
}
Ok((meshes, textures))
+}
+
+fn create_vertices(positions: Option,
+ tex_coords: Option,
+ normals: Option,
+ joints: Option,
+ weights: Option)
+ -> Result, String> {
+ match (positions, tex_coords, normals, joints, weights) {
+ (Some(positions),
+ Some(tex_coords),
+ Some(normals),
+ Some(joints),
+ Some(weights)) => {
+ Ok(positions
+ .zip(tex_coords.into_f32())
+ .zip(normals)
+ .zip(joints.into_u16().map(|arr| {
+ let mut casted_joints: [i32; 4] = [0; 4];
+ for i in 0..4 {
+ casted_joints[i] = arr[i] as i32;
+ }
+ casted_joints
+ }))
+ .zip(weights.into_f32())
+ .map(|((((p, t), n), i), w)| Vertex {
+ position: p,
+ uv: t,
+ normal: n,
+ bone_index: i,
+ bone_weight: w
+ }).collect())
+ },
+ (Some(positions),
+ Some(tex_coords),
+ Some(normals),
+ None, None) => {
+ Ok(positions
+ .zip(tex_coords.into_f32())
+ .zip(normals)
+ .map(|((p, t), n)| Vertex {
+ position: p,
+ uv: t,
+ normal: n,
+ bone_index: [-1; 4],
+ bone_weight: [0.0; 4]
+ }).collect())
+ },
+ (None, _, _, _, _) => Err("Vertex positions missing!".to_string()),
+ (_, None, _, _, _) => Err("Tex coords missing!".to_string()),
+ (_, _, None, _, _) => Err("Normals missing!".to_string()),
+ (_, _, _, Some(_), None) => Err("Bone indices exist, but bone weights are missing!".to_string()),
+ (_, _, _, None, Some(_)) => Err("Bone weights exist, but bone incides are missing!".to_string()),
+ }
}
\ No newline at end of file
diff --git a/src/vulkan.rs b/src/vulkan.rs
index c013dfd..2d9529c 100644
--- a/src/vulkan.rs
+++ b/src/vulkan.rs
@@ -42,8 +42,10 @@ pub struct Vertex {
pub position: [f32; 3],
pub uv: [f32; 2],
pub normal: [f32; 3],
+ pub bone_index: [i32; 4],
+ pub bone_weight: [f32; 4],
}
-vulkano::impl_vertex!(Vertex, position, uv, normal);
+vulkano::impl_vertex!(Vertex, position, uv, normal, bone_index, bone_weight);
#[derive(Default, Debug, Clone)]
pub struct LinePoint {