shine_gltf/
buffer.rs

1use crate::validation::{Checked, Error, Validate};
2use crate::{extensions, Index, Path, Root};
3use serde::{de, ser};
4use serde_derive::{Deserialize, Serialize};
5use shine_gltf_macro::Validate;
6use std::fmt;
7
8/// Corresponds to `GL_ARRAY_BUFFER`.
9pub const ARRAY_BUFFER: u32 = 34_962;
10
11/// Corresponds to `GL_ELEMENT_ARRAY_BUFFER`.
12pub const ELEMENT_ARRAY_BUFFER: u32 = 34_963;
13
14/// The minimum byte stride.
15pub const MIN_BYTE_STRIDE: u32 = 4;
16
17/// The maximum byte stride.
18pub const MAX_BYTE_STRIDE: u32 = 252;
19
20/// All valid GPU buffer targets.
21pub const VALID_TARGETS: &[u32] = &[ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER];
22
23/// Specifies the target a GPU buffer should be bound to.
24#[derive(Clone, Copy, Debug, Eq, PartialEq)]
25pub enum Target {
26    /// Corresponds to `GL_ARRAY_BUFFER`.
27    ArrayBuffer = 1,
28
29    /// Corresponds to `GL_ELEMENT_ARRAY_BUFFER`.
30    ElementArrayBuffer,
31}
32
33impl ser::Serialize for Target {
34    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
35    where
36        S: ser::Serializer,
37    {
38        match *self {
39            Target::ArrayBuffer => serializer.serialize_u32(ARRAY_BUFFER),
40            Target::ElementArrayBuffer => serializer.serialize_u32(ELEMENT_ARRAY_BUFFER),
41        }
42    }
43}
44
45/// A buffer points to binary data representing geometry, animations, or skins.
46#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
47pub struct Buffer {
48    /// The length of the buffer in bytes.
49    #[serde(default, rename = "byteLength")]
50    pub byte_length: u32,
51
52    /// The uri of the buffer.  Relative paths are relative to the .gltf file.
53    /// Instead of referencing an external file, the uri can also be a data-uri.
54    #[serde(skip_serializing_if = "Option::is_none")]
55    pub uri: Option<String>,
56
57    /// Extension specific data.
58    #[serde(default, skip_serializing_if = "Option::is_none")]
59    pub extensions: Option<extensions::buffer::Buffer>,
60}
61
62/// A view into a buffer generally representing a subset of the buffer.
63///
64/// <https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#reference-bufferview>
65///
66#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
67pub struct View {
68    /// The parent `Buffer`.
69    pub buffer: Index<Buffer>,
70
71    /// The length of the `BufferView` in bytes.
72    #[serde(rename = "byteLength")]
73    pub byte_length: u32,
74
75    /// Offset into the parent buffer in bytes.
76    #[serde(default, rename = "byteOffset", skip_serializing_if = "Option::is_none")]
77    pub byte_offset: Option<u32>,
78
79    /// The stride in bytes between vertex attributes or other interleavable data.
80    ///
81    /// When zero, data is assumed to be tightly packed.
82    #[serde(rename = "byteStride")]
83    #[serde(skip_serializing_if = "Option::is_none")]
84    pub byte_stride: Option<ByteStride>,
85
86    /// Optional target the buffer should be bound to.
87    #[serde(skip_serializing_if = "Option::is_none")]
88    pub target: Option<Checked<Target>>,
89
90    /// Extension specific data.
91    #[serde(default, skip_serializing_if = "Option::is_none")]
92    pub extensions: Option<extensions::buffer::View>,
93}
94
95impl View {
96    pub fn with_buffer(buffer: Index<Buffer>) -> View {
97        View {
98            buffer,
99            byte_length: 0,
100            byte_offset: None,
101            byte_stride: None,
102            target: None,
103            extensions: None,
104        }
105    }
106}
107
108/// The stride, in bytes, between vertex attributes.
109#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
110pub struct ByteStride(pub u32);
111
112impl Validate for ByteStride {
113    fn validate_completely<P, R>(&self, _: &Root, path: P, report: &mut R)
114    where
115        P: Fn() -> Path,
116        R: FnMut(&dyn Fn() -> Path, Error),
117    {
118        if self.0 % 4 != 0 {
119            // Not a multiple of 4
120            report(&path, Error::Invalid);
121        }
122
123        if self.0 < MIN_BYTE_STRIDE || self.0 > MAX_BYTE_STRIDE {
124            report(&path, Error::Invalid);
125        }
126    }
127}
128
129impl<'de> de::Deserialize<'de> for Checked<Target> {
130    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
131    where
132        D: de::Deserializer<'de>,
133    {
134        struct Visitor;
135        impl<'de> de::Visitor<'de> for Visitor {
136            type Value = Checked<Target>;
137
138            fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
139                write!(f, "any of: {:?}", VALID_TARGETS)
140            }
141
142            fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
143            where
144                E: de::Error,
145            {
146                use self::Target::*;
147                use crate::validation::Checked::*;
148                Ok(match value as u32 {
149                    ARRAY_BUFFER => Valid(ArrayBuffer),
150                    ELEMENT_ARRAY_BUFFER => Valid(ElementArrayBuffer),
151                    _ => Invalid,
152                })
153            }
154        }
155        deserializer.deserialize_u64(Visitor)
156    }
157}