blender_mesh/vertex_attributes/
vertex_attribute.rs

1use std::ops::Deref;
2
3/// Data for an individual vertex attribute such as positions, normals or uvs.
4///
5/// All of the x, y and z positions of the vertices in this mesh, indexed by `position_indices`.
6///
7/// For example, vec![0., 10., 2., 65.2, 4., 5.] with an attribute size of three would mean that
8/// there are is data for two vertices.
9///
10/// Data set one being (0., 10., 2.) and (65.2, 4., 5.).
11///
12/// This does not, however, mean that there are two vertices in the mesh that is using these
13/// vertices.
14///
15/// There could be multiple vertices that happened to have the same positions.
16#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
17pub struct VertexAttribute<T> {
18    pub(crate) data: Vec<T>,
19    pub(crate) attribute_size: u8,
20}
21
22impl<T> Deref for VertexAttribute<T> {
23    type Target = Vec<T>;
24
25    fn deref(&self) -> &Self::Target {
26        &self.data
27    }
28}
29
30// TODO: Remove this - just quickly lightly refactoring the codebase ..
31#[cfg(test)]
32impl<T> From<(Vec<T>, u8)> for VertexAttribute<T> {
33    fn from(v: (Vec<T>, u8)) -> Self {
34        VertexAttribute {
35            data: v.0,
36            attribute_size: v.1,
37        }
38    }
39}
40
41impl<T> VertexAttribute<T> {
42    /// TODO: Introduce thiserror and add error handling to this library
43    pub fn new(data: Vec<T>, attribute_size: u8) -> Result<VertexAttribute<T>, ()> {
44        if attribute_size as usize % data.len() != 0 {
45            // Return an error ...
46        }
47
48        Ok(VertexAttribute {
49            data,
50            attribute_size,
51        })
52    }
53
54    #[allow(missing_docs)]
55    pub fn as_slice(&self) -> &[T] {
56        &self.data[..]
57    }
58
59    /// The number of values per vertex.
60    ///
61    /// Typically positions and normals have a size of 3 (x, y, z)
62    ///
63    /// Uvs have a size of 2 (u, v)
64    ///
65    /// But other data types can vary. Bone influences / weights might have 3, 4, or some other
66    /// number attribute size depending on the application's needs.
67    pub fn attribute_size(&self) -> u8 {
68        self.attribute_size
69    }
70}
71
72/// Used for vertex skinning
73#[derive(Debug, Serialize, Deserialize, PartialEq, Default)]
74pub struct BoneAttributes {
75    pub(crate) bone_influencers: VertexAttribute<u8>,
76    pub(crate) bone_weights: VertexAttribute<f32>,
77}
78
79impl<T> VertexAttribute<T> {
80    /// Get the underlying data for this attribute.
81    /// Useful for buffering vertex data onto the GPU
82    pub fn data(&self) -> &Vec<T> {
83        &self.data
84    }
85}
86
87impl<T> VertexAttribute<T> {
88    /// Given a vertex indexm return the data at that index.
89    ///
90    /// If there are 3 attributes per vertex the size will be 3, if 2 then 2, etc.
91    pub(crate) fn data_at_idx(&self, vertex_idx: u16) -> &[T] {
92        let attribute_size = self.attribute_size as usize;
93        let idx = (vertex_idx as usize) * attribute_size;
94
95        &self.data[idx..idx + attribute_size]
96    }
97}