gltf_json/
buffer.rs

1use crate::validation::{Checked, Error, USize64, Validate};
2use crate::{extensions, Extras, Index, Path, Root};
3use gltf_derive::Validate;
4use serde::{de, ser};
5use serde_derive::{Deserialize, Serialize};
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: usize = 4;
16
17/// The maximum byte stride.
18pub const MAX_BYTE_STRIDE: usize = 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/// Distance between individual items in a buffer view, measured in bytes.
46#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, Hash, PartialEq, Serialize)]
47pub struct Stride(pub usize);
48
49impl Validate for Stride {
50    fn validate<P, R>(&self, _root: &Root, path: P, report: &mut R)
51    where
52        P: Fn() -> Path,
53        R: FnMut(&dyn Fn() -> Path, Error),
54    {
55        if self.0 < MIN_BYTE_STRIDE || self.0 > MAX_BYTE_STRIDE {
56            report(&path, Error::Invalid);
57        }
58    }
59}
60
61/// A buffer points to binary data representing geometry, animations, or skins.
62#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
63pub struct Buffer {
64    /// The length of the buffer in bytes.
65    #[serde(default, rename = "byteLength")]
66    pub byte_length: USize64,
67
68    /// Optional user-defined name for this object.
69    #[cfg(feature = "names")]
70    #[cfg_attr(feature = "names", serde(skip_serializing_if = "Option::is_none"))]
71    pub name: Option<String>,
72
73    /// The uri of the buffer.  Relative paths are relative to the .gltf file.
74    /// Instead of referencing an external file, the uri can also be a data-uri.
75    #[serde(skip_serializing_if = "Option::is_none")]
76    pub uri: Option<String>,
77
78    /// Extension specific data.
79    #[serde(default, skip_serializing_if = "Option::is_none")]
80    pub extensions: Option<extensions::buffer::Buffer>,
81
82    /// Optional application specific data.
83    #[serde(default)]
84    #[cfg_attr(feature = "extras", serde(skip_serializing_if = "Option::is_none"))]
85    #[cfg_attr(not(feature = "extras"), serde(skip_serializing))]
86    pub extras: Extras,
87}
88
89/// A view into a buffer generally representing a subset of the buffer.
90///
91/// <https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#reference-bufferview>
92///
93#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
94pub struct View {
95    /// The parent `Buffer`.
96    pub buffer: Index<Buffer>,
97
98    /// The length of the `BufferView` in bytes.
99    #[serde(rename = "byteLength")]
100    pub byte_length: USize64,
101
102    /// Offset into the parent buffer in bytes.
103    #[serde(
104        default,
105        rename = "byteOffset",
106        skip_serializing_if = "Option::is_none"
107    )]
108    pub byte_offset: Option<USize64>,
109
110    /// The stride in bytes between vertex attributes or other interleavable data.
111    ///
112    /// When zero, data is assumed to be tightly packed.
113    #[serde(rename = "byteStride")]
114    #[serde(skip_serializing_if = "Option::is_none")]
115    pub byte_stride: Option<Stride>,
116
117    /// Optional user-defined name for this object.
118    #[cfg(feature = "names")]
119    #[cfg_attr(feature = "names", serde(skip_serializing_if = "Option::is_none"))]
120    pub name: Option<String>,
121
122    /// Optional target the buffer should be bound to.
123    #[serde(skip_serializing_if = "Option::is_none")]
124    pub target: Option<Checked<Target>>,
125
126    /// Extension specific data.
127    #[serde(default, skip_serializing_if = "Option::is_none")]
128    pub extensions: Option<extensions::buffer::View>,
129
130    /// Optional application specific data.
131    #[serde(default)]
132    #[cfg_attr(feature = "extras", serde(skip_serializing_if = "Option::is_none"))]
133    #[cfg_attr(not(feature = "extras"), serde(skip_serializing))]
134    pub extras: Extras,
135}
136
137impl<'de> de::Deserialize<'de> for Checked<Target> {
138    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
139    where
140        D: de::Deserializer<'de>,
141    {
142        struct Visitor;
143        impl<'de> de::Visitor<'de> for Visitor {
144            type Value = Checked<Target>;
145
146            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
147                write!(f, "any of: {:?}", VALID_TARGETS)
148            }
149
150            fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
151            where
152                E: de::Error,
153            {
154                use self::Target::*;
155                use crate::validation::Checked::*;
156                Ok(match value as u32 {
157                    ARRAY_BUFFER => Valid(ArrayBuffer),
158                    ELEMENT_ARRAY_BUFFER => Valid(ElementArrayBuffer),
159                    _ => Invalid,
160                })
161            }
162        }
163        deserializer.deserialize_u64(Visitor)
164    }
165}