1use 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
14pub 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 pub visual: Box<Visual>,
62 pub render_sets_data: Vec<RenderSetData>,
64}
65
66#[derive(Debug)]
67pub struct RenderSetData {
68 pub vertices: Vec<Vertex>,
71 pub primitives: Vec<Primitive>,
73 pub groups: Vec<Group>,
75}
76
77impl Model {
78
79 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 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#[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}