mod3d_gltf/
primitives_meshes.rs

1//a Imports
2#[cfg(feature = "serde")]
3use serde::{Deserialize, Serialize};
4
5#[cfg(feature = "serde")]
6use crate::{deserialize, serialize};
7
8use crate::{AccessorIndex, Indexable, MaterialIndex, PrimitiveIndex};
9
10//a GltfPrimitive
11//tp GltfPrimitive
12/// A Gltf primitive, as deserialized from the Gltf Json
13#[derive(Debug, Default)]
14#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
15pub struct GltfPrimitive {
16    /// Attributes mapping a VertexAttr to an AccessorIndex
17    // This must be a map from attribute name to accessor index
18    //
19    // attribute name - corresponds to mod3d_base::VertexAttr
20    #[cfg_attr(
21        feature = "serde",
22        serde(deserialize_with = "deserialize::attr_to_attr")
23    )]
24    #[cfg_attr(feature = "serde", serde(serialize_with = "serialize::attr_to_attr"))]
25    attributes: Vec<(mod3d_base::VertexAttr, AccessorIndex)>,
26
27    /// Mode for drawing the primitive
28    // 0-6: POINTS, LINES, LINE_LOOP, LINE_STRIP, TRIANGLES, TRIANGLE_STRIP,
29    // TRIANGLE_FAN default is 4:triangles
30    #[cfg_attr(feature = "serde", serde(default = "deserialize::pt_triangles"))]
31    #[cfg_attr(
32        feature = "serde",
33        serde(deserialize_with = "deserialize::primitive_type")
34    )]
35    #[cfg_attr(feature = "serde", serde(serialize_with = "serialize::primitive_type"))]
36    mode: mod3d_base::PrimitiveType,
37
38    /// Material index to use when drawing the primitive
39    // optional
40    #[cfg_attr(feature = "serde", serde(default))]
41    material: Option<MaterialIndex>,
42
43    /// Indices to use (AccessorIndex) if indexed (otherwise use 0..N)
44    // optional - if not present then drawArrays should be used
45    #[cfg_attr(feature = "serde", serde(default))]
46    indices: Option<AccessorIndex>,
47    // optional: targets
48    // optional: extensions, extras
49}
50
51//ip GltfPrimitive
52impl GltfPrimitive {
53    pub fn new(
54        mode: mod3d_base::PrimitiveType,
55        indices: Option<AccessorIndex>,
56        material: Option<MaterialIndex>,
57    ) -> Self {
58        Self {
59            mode,
60            indices,
61            material,
62            ..Default::default()
63        }
64    }
65    //ap indices
66    /// Return the AccessorIndex for the indices of the primitive - or
67    /// None if one was not specified (drawArrays should be used to
68    /// render the primitive)
69    pub fn indices(&self) -> Option<AccessorIndex> {
70        self.indices
71    }
72
73    //ap primitive_type
74    /// Return the mod3d_base::PrimitiveType of the primitive
75    /// (TriangleStrip, etc)
76    pub fn primitive_type(&self) -> mod3d_base::PrimitiveType {
77        self.mode
78    }
79
80    //ap attributes
81    /// Return a slice of tuples of mod3d_base::VertexAttr and
82    /// AccessorIndex from the Gltf for the primitive
83    pub fn attributes(&self) -> &[(mod3d_base::VertexAttr, AccessorIndex)] {
84        &self.attributes
85    }
86
87    //ap material
88    /// Return the
89    /// AccessorIndex from the Gltf for the primitive
90    pub fn material(&self) -> Option<MaterialIndex> {
91        self.material
92    }
93    pub fn add_attribute(&mut self, attr: mod3d_base::VertexAttr, accessor: AccessorIndex) {
94        self.attributes.push((attr, accessor))
95    }
96}
97
98//tp GltfMesh
99#[derive(Debug, Default)]
100#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
101#[cfg_attr(feature = "serde", serde(default))]
102pub struct GltfMesh {
103    /// The name of the mesh, if any
104    #[cfg_attr(feature = "serde", serde(default))]
105    name: String,
106    /// The primitives that make up the mesh
107    primitives: Vec<GltfPrimitive>,
108    // optional: weights (ignored as morph targets are not supported)
109    // optional: name, extensions, extras
110}
111
112impl GltfMesh {
113    pub fn add_primitive(
114        &mut self,
115        mode: mod3d_base::PrimitiveType,
116        indices: Option<AccessorIndex>,
117        material: Option<MaterialIndex>,
118    ) -> PrimitiveIndex {
119        let p = GltfPrimitive::new(mode, indices, material);
120        let n = self.primitives.len();
121        self.primitives.push(p);
122        n.into()
123    }
124    pub fn name(&self) -> &str {
125        &self.name
126    }
127    pub fn primitives(&self) -> &[GltfPrimitive] {
128        &self.primitives
129    }
130}
131
132//ip Index<PrimitiveIndex> for GltfMesh
133impl std::ops::Index<PrimitiveIndex> for GltfMesh {
134    type Output = GltfPrimitive;
135    fn index(&self, index: PrimitiveIndex) -> &Self::Output {
136        &self.primitives[index.as_usize()]
137    }
138}
139
140//ip IndexMut<PrimitiveIndex> for GltfMesh
141impl std::ops::IndexMut<PrimitiveIndex> for GltfMesh {
142    fn index_mut(&mut self, index: PrimitiveIndex) -> &mut Self::Output {
143        &mut self.primitives[index.as_usize()]
144    }
145}