wgtk/model/
mod.rs

1//! Compiled model memory representation, encoding and decoding.
2
3use std::io::{Read, Seek};
4
5use thiserror::Error;
6
7pub mod primitive;
8pub mod visual;
9
10use self::visual::{Visual, RenderSet};
11use self::primitive::{PrimitiveReader, Vertices, Indices, Vertex, Primitive, Group};
12
13
14/// Decode and resolve a compiled model.
15pub fn from_readers<Rv, Rp>(visual_reader: Rv, primitive_reader: Rp) -> Result<Model, DeError>
16where
17    Rv: Read + Seek,
18    Rp: Read + Seek,
19{
20
21    let visual = visual::from_reader(visual_reader)?;
22    let mut primitive_reader = PrimitiveReader::open(primitive_reader)?;
23    let mut render_sets_data = Vec::new();
24
25    for render_set in &visual.render_sets {
26
27        let vertices_section = &render_set.geometry.vertices_section;
28        let indices_section = &render_set.geometry.indices_section;
29
30        let vertices = match primitive_reader.read_section::<Vertices>(vertices_section) {
31            Some(Ok(v)) => v,
32            Some(Err(e)) => return Err(DeError::SectionPrimitive(vertices_section.clone(), e)),
33            None => return Err(DeError::MissingVerticesSection(vertices_section.clone())),
34        };
35
36        let indices = match primitive_reader.read_section::<Indices>(indices_section) {
37            Some(Ok(v)) => v,
38            Some(Err(e)) => return Err(DeError::SectionPrimitive(indices_section.clone(), e)),
39            None => return Err(DeError::MissingIndicesSection(indices_section.clone())),
40        };
41
42        render_sets_data.push(RenderSetData {
43            vertices: vertices.vertices,
44            primitives: indices.primitives,
45            groups: indices.groups,
46        });
47
48    }
49
50    Ok(Model {
51        visual, 
52        render_sets_data,
53    })
54
55}
56
57
58#[derive(Debug)]
59pub struct Model {
60    /// Description of the visual components of the model.
61    pub visual: Box<Visual>,
62    /// Decoded data for each render set.
63    pub render_sets_data: Vec<RenderSetData>,
64}
65
66#[derive(Debug)]
67pub struct RenderSetData {
68    /// All vertices for the model. To access correct vertices,
69    /// use correct method of the model to get access to them.
70    pub vertices: Vec<Vertex>,
71    /// Indices of the model, linking all vertices.
72    pub primitives: Vec<Primitive>,
73    /// Groups of indices.
74    pub groups: Vec<Group>,
75}
76
77impl Model {
78
79    /// Shortcut method to get a render set metadata together with its data.
80    pub fn get_render_set(&self, index: usize) -> Option<(&RenderSet, &RenderSetData)> {
81        Some((
82            self.visual.render_sets.get(index)?,
83            self.render_sets_data.get(index)?,
84        ))
85    }
86
87}
88
89impl RenderSetData {
90
91    /// Get a specific primitive group. Only its vertices and primitives are
92    /// returned.
93    pub fn get_group(&self, index: usize) -> Option<(&[Vertex], &[Primitive])> {
94        let group = self.groups.get(index)?;
95        Some((
96            &self.vertices[group.vertices_offset as usize..][..group.vertices_count as usize],
97            &self.primitives[group.primitives_offset as usize..][..group.primitives_count as usize],
98        ))
99    }
100
101}
102
103
104/// Deserialization errors that can happen while read a whole compiled model.
105#[derive(Debug, Error)]
106pub enum DeError {
107    #[error("the vertices section '{0}' is missing")]
108    MissingVerticesSection(String),
109    #[error("the indices section '{0}' is missing")]
110    MissingIndicesSection(String),
111    #[error("primitive error in section '{0}': {1}")]
112    SectionPrimitive(String, primitive::DeError),
113    #[error("visual error: {0}")]
114    Visual(#[from] visual::DeError),
115    #[error("primitive error: {0}")]
116    Primitive(#[from] primitive::DeError),
117}