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}