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}