mod3d_gltf/
buffers_accessors.rs1#[cfg(feature = "serde")]
3use serde::{Deserialize, Serialize};
4
5#[cfg(feature = "serde")]
6use crate::{deserialize, serialize};
7
8use crate::{BufferIndex, ViewIndex};
9
10#[derive(Debug, Default)]
18#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
19#[cfg_attr(feature = "serde", serde(default))]
20pub struct GltfBuffer {
21 uri: String,
24 #[cfg_attr(feature = "serde", serde(rename = "byteLength"))]
27 byte_length: usize,
28}
29
30impl GltfBuffer {
32 pub fn uri(&self) -> &str {
35 &self.uri
36 }
37
38 pub fn byte_length(&self) -> usize {
41 self.byte_length
42 }
43
44 pub fn of_base64<T: AsRef<[u8]>>(data: T) -> Self {
47 use base64::engine::general_purpose;
48 use base64::Engine;
49 let byte_length = data.as_ref().len();
50 let mut uri = general_purpose::STANDARD.encode(data);
51 uri.insert_str(0, "data:application/octet-stream;base64,");
52 Self { uri, byte_length }
53 }
54
55 pub fn take_buffer(&mut self) -> Self {
62 Self {
63 uri: std::mem::take(&mut self.uri),
64 byte_length: self.byte_length,
65 }
66 }
67}
68
69#[derive(Debug, Default)]
75#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
76#[cfg_attr(feature = "serde", serde(default))]
77pub struct GltfBufferView {
78 pub buffer: BufferIndex,
79 #[cfg_attr(feature = "serde", serde(rename = "byteLength"))]
80 pub byte_length: usize,
81 #[cfg_attr(feature = "serde", serde(rename = "byteOffset"))]
82 pub byte_offset: usize,
83 #[cfg_attr(feature = "serde", serde(rename = "byteStride"))]
84 pub byte_stride: Option<usize>,
85}
86
87impl GltfBufferView {
88 pub fn buffer(&self) -> BufferIndex {
90 self.buffer
91 }
92
93 pub fn byte_offset(&self) -> usize {
95 self.byte_offset
96 }
97
98 pub fn byte_length(&self) -> usize {
100 self.byte_length
101 }
102
103 pub fn byte_stride(&self, default: usize) -> usize {
105 self.byte_stride.unwrap_or(default)
106 }
107
108 pub fn byte_end(&self) -> usize {
110 self.byte_offset + self.byte_length
111 }
112}
113
114#[derive(Debug)]
125#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
126pub struct GltfAccessor {
128 #[cfg_attr(feature = "serde", serde(rename = "bufferView"))]
133 buffer_view: Option<ViewIndex>,
134
135 #[cfg_attr(feature = "serde", serde(rename = "byteOffset"))]
138 #[cfg_attr(feature = "serde", serde(default))]
139 byte_offset: usize,
140
141 #[cfg_attr(feature = "serde", serde(rename = "componentType"))]
144 #[cfg_attr(
146 feature = "serde",
147 serde(deserialize_with = "deserialize::comp_type_to_ele_type")
148 )]
149 #[cfg_attr(feature = "serde", serde(default = "deserialize::ele_type_s32"))]
150 #[cfg_attr(
151 feature = "serde",
152 serde(serialize_with = "serialize::ele_type_to_comp_type")
153 )]
154 component_type: mod3d_base::BufferElementType,
155
156 #[cfg_attr(feature = "serde", serde(rename = "count"))]
159 count: usize,
160
161 #[cfg_attr(feature = "serde", serde(rename = "type"))]
163 #[cfg_attr(
164 feature = "serde",
165 serde(deserialize_with = "deserialize::type_to_num")
166 )]
167 #[cfg_attr(feature = "serde", serde(serialize_with = "serialize::num_to_type"))]
168 elements_per_data: usize,
170 }
173
174impl GltfAccessor {
176 pub fn new(
177 buffer_view: ViewIndex,
178 byte_offset: usize,
179 count: usize,
180 component_type: mod3d_base::BufferElementType,
181 elements_per_data: usize,
182 ) -> Self {
183 let buffer_view = Some(buffer_view);
184 Self {
185 buffer_view,
186 byte_offset,
187 count,
188 component_type,
189 elements_per_data,
190 }
191 }
192
193 pub fn buffer_view(&self) -> Option<ViewIndex> {
195 self.buffer_view
196 }
197
198 pub fn byte_offset(&self) -> usize {
200 self.byte_offset
201 }
202
203 pub fn count(&self) -> usize {
205 self.count
206 }
207
208 pub fn component_type(&self) -> mod3d_base::BufferElementType {
210 self.component_type
211 }
212
213 pub fn ele_byte_size(&self) -> usize {
215 self.elements_per_data * self.component_type().byte_length() as usize
216 }
217
218 pub fn elements_per_data(&self) -> usize {
220 self.elements_per_data
221 }
222
223 pub fn byte_stride(&self, view_byte_stride: usize) -> usize {
225 if view_byte_stride != 0 {
226 view_byte_stride
227 } else {
228 self.ele_byte_size()
229 }
230 }
231
232 pub fn byte_view_end(&self, view_byte_stride: usize) -> usize {
235 let byte_stride = self.byte_stride(view_byte_stride);
236 self.byte_offset + byte_stride * (self.count - 1) + self.ele_byte_size()
237 }
238}