hxa/
layer.rs

1use crate::enums::HXALayerDataType;
2use crate::macros::{buffer,read_bytes,whereami,read_str};
3use std::fs::File;
4use std::io::{BufReader, Read, Seek};
5use std::{str};
6
7
8#[derive(Debug)]
9pub struct  HXALayer {
10    /// name of the layer. List of predefined names for common usages like uv, reference, blendshapes, weights ...
11    pub name: String,
12
13    /// 2 for uv, 3 for xyz or rgb, 4 for rgba;
14    pub components: u8,
15
16    /// Stored in the file as a uint8.
17    pub layer_type: HXALayerDataType
18}
19impl HXALayer {
20    fn new() -> Self {
21        HXALayer {
22            name: String::from("NO NAME"),
23            components: 0,
24            layer_type: HXALayerDataType::Unknown,
25        }
26    }
27
28    fn parse(self: &mut HXALayer, input: &mut BufReader<File>, num_items: &u32) {
29        // Get the name of the layer
30        //whereami!(input);
31        let name_length:u8 = read_bytes!(input u8);
32        let mut name_buffer = buffer!(exactly name_length);
33        let name = read_str!(input name_buffer);
34        self.name = String::from(name);
35
36        // Get the number of components for the layer
37        self.components = read_bytes!(input u8);
38
39        // Get layer type
40        let u8_layer_type:u8 = read_bytes!(input u8);
41        self.layer_type = HXALayerDataType::from(u8_layer_type);
42
43        match &mut self.layer_type {
44            HXALayerDataType::UINT8(uint_array) => {
45                for _ in 0..((*num_items) * (self.components as u32)){
46                    uint_array.push(read_bytes!(input u8));
47                }
48            },
49            HXALayerDataType::INT32(int_array) => {
50                for _ in 0..((*num_items) * (self.components as u32)){
51                    int_array.push(read_bytes!(input i32));
52                }
53            },
54            HXALayerDataType::FLOAT(float_array) => {
55                for _ in 0..((*num_items) * (self.components as u32)){
56                    float_array.push(read_bytes!(input f32));
57                }
58            },
59            HXALayerDataType::DOUBLE(double_array) => {
60                for _ in 0..((*num_items) * (self.components as u32)){
61                    double_array.push(read_bytes!(input f64));
62                }
63            },
64            HXALayerDataType::Unknown => {},
65        }
66    }
67
68    pub fn try_as_vec_i32(&self) -> Option<&Vec<i32>>{
69        match &self.layer_type{
70            HXALayerDataType::INT32(int_array) => return Some(int_array),
71            _ => return None,
72        }
73    }
74
75    /// Gets and unwraps the underlying vector
76    /// # Panics
77    /// Panics if the underlying vector is the wrong type
78    /// ## Recommendation
79    /// Use this function if following a `HxA` standard where  a `HXALayer` with a specific name always has a specific type
80    pub fn as_vec_i32(&self) -> &Vec<i32>{
81        self.try_as_vec_i32().expect("Expected the underlying type to be a Vec<i32>")
82    }
83
84    pub fn try_as_vec_f32(&self) -> Option<&Vec<f32>>{
85        match &self.layer_type{
86            HXALayerDataType::FLOAT(float_array) => return Some(float_array),
87            _ => return None,
88        }
89    }
90
91    /// Gets and unwraps the underlying vector
92    /// # Panics
93    /// Panics if the underlying vector is the wrong type
94    /// ## Recommendation
95    /// Use this function if following a `HxA` standard where  a `HXALayer` with a specific name always has a specific type
96    pub fn as_vec_f32(&self) -> &Vec<f32>{
97        self.try_as_vec_f32().expect("Expected the underlying type to be a Vec<f32>")
98    }
99
100    /// Gets and unwraps the underlying vector and returns a copy of the vector in sets of 3
101    /// # Panics
102    ///  - If the underlying vector is the wrong type
103    ///  - If the number of elements is not divisible by 3 
104    /// ## Recommendation
105    /// Use this function if following a `HxA` standard where  a `HXALayer` with a specific name always has a specific type
106    /// 
107    /// This was designed to make it easier to move data into `Vertex` objects from libraries such as `Vulkano` and `glium`
108    pub fn as_tri_tup_vec_f32(&self) -> Vec<(f32,f32,f32)>{
109        
110        let vec_ref = self.as_vec_f32();
111        if self.components != 3 {
112            panic!("Components must be exactly 3")
113        }
114
115        let num_tris = vec_ref.len()/3;
116        let mut out:Vec<(f32,f32,f32)> = Vec::with_capacity(num_tris);
117
118        for multiplier in 0..num_tris{
119            let idx = multiplier * (self.components as usize);
120
121            out.push((
122                *vec_ref.get(idx).unwrap(),
123                *vec_ref.get(idx+1).unwrap(),
124                *vec_ref.get(idx+2).unwrap(),
125            ));
126        }
127
128        out
129    }
130
131    pub fn try_as_vec_f64(&self) -> Option<&Vec<f64>>{
132        match &self.layer_type{
133            HXALayerDataType::DOUBLE(double_array) => return Some(double_array),
134            _ => return None,
135        }
136    }
137
138    /// Gets and unwraps the underlying vector
139    /// # Panics
140    /// Panics if the underlying vector is the wrong type
141    /// ## Recommendation
142    /// Use this function if following a `HxA` standard where  a `HXALayer` with a specific name always has a specific type
143    pub fn as_vec_f64(&self) -> &Vec<f64>{
144        self.try_as_vec_f64().expect("Expected the underlying type to be a Vec<f64>")
145    }
146
147    pub fn try_as_vec_u8(&self) -> Option<&Vec<u8>>{
148        match &self.layer_type{
149            HXALayerDataType::UINT8(uint_array) => return Some(uint_array),
150            _ => return None,
151        }
152    }
153
154    /// Gets and unwraps the underlying vector
155    /// # Panics
156    /// Panics if the underlying vector is the wrong type
157    /// ## Recommendation
158    /// Use this function if following a `HxA` standard where  a `HXALayer` with a specific name always has a specific type
159    pub fn as_vec_u8(&self) -> &Vec<u8>{
160        self.try_as_vec_u8().expect("Expected the underlying type to be a Vec<u8>")
161    }
162}
163
164#[derive(Debug)]
165pub struct HXALayerStack{
166    pub layer_count: u32,
167    pub layers: Vec<HXALayer>
168}
169
170impl HXALayerStack {
171    pub fn new() -> Self {
172        HXALayerStack { 
173            layer_count: 0,
174            layers: Vec::with_capacity(1)
175        }
176    }
177
178    pub fn parse(self: &mut HXALayerStack, input: &mut BufReader<File>, num_items: &u32){
179
180        self.layer_count = read_bytes!(input u32);
181
182        for _ in 0..self.layer_count{
183            let mut new_layer = HXALayer::new();
184            new_layer.parse(input, num_items);
185            self.layers.push(new_layer)
186        }
187    }
188
189    /// Finds the first layer with the specified name
190    pub fn find(&self, layer_name:&str) -> Option<&HXALayer>{
191        // In the future I might change layer names to just be string slices too
192        let search_string = String::from(layer_name);
193
194        for layer in &self.layers{
195            if layer.name == search_string{
196                return Some(layer);
197            }
198        }
199        None
200    }
201}
202