1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
mod vertex_attribute; pub use self::vertex_attribute::{BoneAttributes, VertexAttribute}; use crate::bone::BoneInfluencesPerVertex; mod single_indexed; pub use self::single_indexed::*; /// Points to the data for each vertex. /// /// Typically by the time a `MeshIr` has been prepared for rendering it will have every 3 indices /// correspond to one face - but this is not a requirement. /// /// You could - for example - have 4 indices correspond to a face. /// /// These can also be mixed. When exporting from Blender, for example, you might have /// `VertexIndices` that are grouped by 3 sometimes and 4 other times and even more other times - /// all within the same vector. /// /// You can decipher this by referencing the [`vertices_in_each_face`] /// /// ## A visualization /// /// So way we have `VertexIndices` that correspond to a `vertex_uvs: (Vec<f32>, 2)`. /// /// Say our `VertexIndices` and `vertex_uvs` look like the following: /// /// ```rust,no_run /// let vertex_indices = vec![0, 1, 2, 0, 2, 3]; /// let vertex_positions = vec![ /// 0., 0., /// 1., 0., /// 1., 1., /// 0., 1., /// ]; /// ``` /// /// In this case every vertex index corresponds to 3 vertex position floats. /// /// | Index | Uv | /// | --- | --- | /// | 0 | &[0., 0.,] | /// | 1 | &[1., 0.,] | /// | 2 | &[1., 1.,] | /// | 3 | &[0., 1.,] | /// /// When referenced in conjunction with `vertices_in_each_face` you can determine the /// positions of the vertices in each face. /// /// For example, if `vertices_in_each_face: [3, 4, 3]`, then the first three position indices /// give you the positions for the triangle for the first face, then the next 4 position indices /// give you the quad for the next face, then the next three give you positions for the next /// triangle. /// /// [`vertices_in_each_face`]: struct.MultiIndexVertexData.html#method.vertices_in_each_face pub type VertexIndices = Vec<u16>; /// Per vertex data from the BlenderMesh. /// /// When exporting from Blender there data is exported with multiple indices, /// then after running `combine_vertex_indices` there will be one single index /// for all of the vertex data. #[derive(Debug, Serialize, Deserialize, PartialEq)] pub enum VertexAttributes { /// The data has multiple indices per vertex, such as one for position data, uvs and normals, /// etc. Multi(MultiIndexedVertexAttributes), /// The data has one single index per vertex Single(SingleIndexedVertexAttributes), } impl Default for VertexAttributes { fn default() -> Self { VertexAttributes::Multi(MultiIndexedVertexAttributes::default()) } } /// Vertex data with multiple indices - not suited for OpenGL and other single index rendering /// pipelines, but good for on disk storage as their is less data duplicated when there are /// multiple indices. /// /// TODO: A HashMap so that we can have arbitrary vertex attributes #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)] pub struct MultiIndexedVertexAttributes { // The number of vertices that comprise each face of the mesh. // // For example, [3, 4, 4, 3, 3, 4] would mean that the first face has 3 vertices (triangle), // the next face has 4 (quad), then the next face has 4, etc. // // ## Example Use Cases // // - Triangulation, where faces with more than 3 vertices need to be split into triangles. // // - Calculating vertex tangents, where all vertices in the same face will have the same // tangent. pub(crate) vertices_in_each_face: Vec<u8>, pub(crate) positions: IndexedAttribute, pub(crate) normals: Option<IndexedAttribute>, pub(crate) uvs: Option<IndexedAttribute>, pub(crate) bone_influences: Option<VertexBoneInfluences>, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)] pub struct IndexedAttribute { pub(crate) indices: VertexIndices, pub(crate) attribute: VertexAttribute<f32>, } #[allow(missing_docs)] impl IndexedAttribute { pub fn new(indices: VertexIndices, attribute: VertexAttribute<f32>) -> Self { IndexedAttribute { indices, attribute } } } impl From<(VertexIndices, VertexAttribute<f32>)> for IndexedAttribute { fn from(v: (VertexIndices, VertexAttribute<f32>)) -> Self { Self { indices: v.0, attribute: v.1, } } } impl From<MultiIndexedVertexAttributes> for VertexAttributes { fn from(m: MultiIndexedVertexAttributes) -> Self { VertexAttributes::Multi(m) } } impl From<SingleIndexedVertexAttributes> for VertexAttributes { fn from(s: SingleIndexedVertexAttributes) -> Self { VertexAttributes::Single(s) } } /// The amount that each bone in the mesh's parent armature influences each vertex. /// /// For example, if `bone_indices = [0, 1, 2, 2, 5]` and /// `bone_weights = [0.2, 0.4, 0.2, 0.5, 0.5]` and `bones_per_vertex = [3, 2]` then /// the first vertex is influenced by bone 0 by 0.2, bone 1 by 0.4 and bone 2 by 0.2. /// /// Then the second vertex is influenced by bone 2 by 0.5 and bone 5 by 0.5 /// /// TODO: Remove this and use VertexAttribute with something like attribute_size: Varies(vec![]) /// this allows us to handle all attributes the same way. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)] pub struct VertexBoneInfluences { /// The number of bones that affect each vertex. /// /// Example: [3, 5, 2] would mean that the first vertex is influenced by 3 bones, second by /// 5, and third by 2 pub(crate) bones_per_vertex: BoneInfluencesPerVertex, /// The indices of the bones that affect each vertex. pub(crate) bone_indices: Vec<u8>, /// The corresponding weights of each bone index pub(crate) bone_weights: Vec<f32>, }