mod3d_base/
types.rs

1//a Imports
2#[cfg(feature = "serde")]
3use serde::{Deserialize, Serialize};
4
5//a Basic types
6//tp Vec3
7/// 3-dimensional vector
8pub type Vec3 = [f32; 3];
9
10//tp Vec4
11/// 3-dimensional vector with extra coord (1 for position, 0 for direction)
12pub type Vec4 = [f32; 4];
13
14//tp Mat3
15/// 3-by-3 matrix for transformation of Vec3
16pub type Mat3 = [f32; 9];
17
18//tp Mat4
19/// 4-by-4 matrix for transformation of Vec4
20pub type Mat4 = [f32; 16];
21
22//tp Quat - Quaternion
23/// Quaternion
24pub type Quat = [f32; 4];
25
26//a Buffer
27//tp BufferElementType
28/// The type of an element in a buffer
29///
30/// This deliberately does not implement Default
31#[derive(Debug, Clone, Copy, PartialEq, Eq)]
32#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
33#[repr(u8)]
34pub enum BufferElementType {
35    /// 32-bit floating point
36    Float32,
37    /// 16-bit floating point
38    Float16,
39    /// Signed 8-bit integers
40    SInt8,
41    /// Signed 16-bit integers
42    SInt16,
43    /// Signed 32-bit integers
44    SInt32,
45    /// Unsigned 8-bit integers
46    UInt8,
47    /// Unsigned 16-bit integers
48    UInt16,
49    /// Unsigned 32-bit integers
50    UInt32,
51}
52
53//ip BufferElementType
54impl BufferElementType {
55    /// Create a 16-bit float type
56    pub const fn float16() -> Self {
57        Self::Float16
58    }
59    /// Create a 32-bit float type
60    pub const fn float32() -> Self {
61        Self::Float32
62    }
63    /// Create a signed/unsigned int type
64    pub const fn new_int(signed: bool, bits: usize) -> Self {
65        match bits {
66            8 => {
67                if signed {
68                    Self::SInt8
69                } else {
70                    Self::UInt8
71                }
72            }
73            16 => {
74                if signed {
75                    Self::SInt16
76                } else {
77                    Self::UInt16
78                }
79            }
80            32 => {
81                if signed {
82                    Self::SInt32
83                } else {
84                    Self::UInt32
85                }
86            }
87            _ => {
88                panic!("An int value must be 8, 16 or 32 bits");
89            }
90        }
91    }
92
93    /// Get the length in bytes of the element type
94    pub fn byte_length(self) -> usize {
95        use BufferElementType::*;
96        match self {
97            Float32 => 4,
98            Float16 => 2,
99            SInt8 => 1,
100            SInt16 => 2,
101            SInt32 => 4,
102            UInt8 => 1,
103            UInt16 => 2,
104            UInt32 => 4,
105        }
106    }
107}
108
109//tp VertexDesc
110/// A descriptor of the contents of one aspect of data for a Vertex
111#[derive(Debug, Clone, Copy)]
112#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
113pub struct VertexDesc {
114    attr: VertexAttr,
115    byte_offset: u16,
116    dims: [u8; 2],
117    ele_type: BufferElementType,
118}
119
120//a Drawing
121/// A [VertexAttr] is a possible vertex attribute that can be used by
122/// a renderer; a vertex always has a position attribute, but
123/// additional attributes may or maynot be provided by a model
124#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq)]
125#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
126#[repr(u8)]
127pub enum VertexAttr {
128    /// Position (3xf32) of the point
129    Position,
130    /// Normal (3xf32) at the point
131    Normal,
132    /// Color at the point (4xf32)
133    Color,
134    /// Tangent at the point (4xf32?)
135    Tangent,
136    /// A set of joints (n x int)
137    Joints,
138    /// Weights (n x f16?) to apply to each bone\[joint\[i\]\]
139    Weights,
140    /// Texture coordinates (2 x f32)
141    TexCoords0,
142    /// Texture coordinates (2 x f32)
143    TexCoords1,
144    /// Texture coordinates (2 x f32)
145    TexCoords2,
146}
147
148//tp PrimitiveType
149/// Type of a primitive
150///
151/// This is set to match the GLTF
152#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
153#[repr(u8)]
154pub enum PrimitiveType {
155    /// Points (of an indeterminate size?)
156    Points,
157    /// Lines (n-1) (ab, cd, ef, ...)
158    Lines,
159    /// Close loop of (n) lines (ab, cd, ef, ..., za)
160    LineLoop,
161    /// Connected (n-1) lines (ab, bc, cd, de, ...)
162    LineStrip,
163    /// Individual (n/3) triangles (one for every three indices)
164    #[default]
165    Triangles,
166    /// Strip of (n-2) triangles (abc, bcd, cde, def, ...)
167    TriangleStrip,
168    /// Fan of (n-2) triangles (abc, acd, ade, aef, ...)
169    TriangleFan,
170}
171
172//tp MaterialAspect
173/// The aspect of a material
174#[derive(Debug, Clone, Copy, PartialEq, Eq)]
175pub enum MaterialAspect {
176    /// Color (notionally RGBA as 4xf32)
177    Color,
178    /// Normal
179    Normal,
180    /// MetallicRoughness (notionally MR as 2xf32)
181    MetallicRoughness,
182    /// Occlusion (as f32)
183    Occlusion,
184    /// Emission (as f32)
185    Emission,
186}
187
188//tp ShortIndex
189/// An optional index used within the model system, that is up to 65000
190///
191/// It can be, effectively, 'None' or Some(usize less than 65000)
192///
193/// The purpose is to keep the size of indexed structures small and
194/// permit the optional aspect; it is used to index Vec of textures,
195/// vertices descriptor sets, etc
196///
197/// It has implementations of From<> to map a [usize] into a
198/// [ShortIndex], and to map from [ShortIndex] to Option<usize>; plus
199/// to map from Option<usize> (or anything that is Into<usize>) to a
200/// ShortIndex, to ease use.
201///
202/// These extra implementations remove some of the type safety one
203/// might have, but make it simpler to use the index
204#[derive(Debug, Clone, Copy, PartialEq, Eq)]
205pub struct ShortIndex(u16);
206
207//ip Default for ShortIndex
208impl std::default::Default for ShortIndex {
209    fn default() -> Self {
210        Self(65535)
211    }
212}
213
214//ip ShortIndex
215impl ShortIndex {
216    ///cp none
217    /// Create a 'None' value
218    #[inline]
219    pub fn none() -> Self {
220        Default::default()
221    }
222
223    ///ap as_usize
224    /// Return the value - if it is effectively None, then panic
225    #[inline]
226    pub fn as_usize(self) -> usize {
227        assert!(self.0 != 65535);
228        self.0 as usize
229    }
230
231    ///ap is_none
232    /// Return true if the index is None
233    #[inline]
234    pub fn is_none(self) -> bool {
235        self.0 == 65535
236    }
237
238    ///ap is_some
239    /// Return true if the index is not None
240    #[inline]
241    pub fn is_some(self) -> bool {
242        self.0 != 65535
243    }
244}
245
246//ip From<usize> for ShortIndex
247impl From<usize> for ShortIndex {
248    fn from(index: usize) -> Self {
249        assert!(index < 65535);
250        Self(index as u16)
251    }
252}
253
254//ip From<ShortIndex> for Option<usize>
255impl From<ShortIndex> for Option<usize> {
256    fn from(index: ShortIndex) -> Option<usize> {
257        if index.is_none() {
258            None
259        } else {
260            Some(index.as_usize())
261        }
262    }
263}
264
265//ip From<Option<into usize >> for ShortIndex
266impl<I: Into<usize>> From<Option<I>> for ShortIndex {
267    fn from(opt_index: Option<I>) -> Self {
268        if let Some(index) = opt_index {
269            let index: usize = index.into();
270            assert!(index < 65535);
271            Self(index as u16)
272        } else {
273            Self(65535_u16)
274        }
275    }
276}