1use std::fmt;
2
3use super::{common::StringIndex, image::Image, validation::Checked};
4use gltf_v1_derive::Validate;
5use serde::de;
6use serde::{Deserialize, Serialize};
7
8pub const NEAREST: u32 = 9728;
9pub const LINEAR: u32 = 9729;
10pub const NEAREST_MIPMAP_NEAREST: u32 = 9984;
11pub const LINEAR_MIPMAP_NEAREST: u32 = 9985;
12pub const NEAREST_MIPMAP_LINEAR: u32 = 9986;
13pub const LINEAR_MIPMAP_LINEAR: u32 = 9987;
14
15#[derive(Clone, Copy, Debug, Eq, PartialEq, Default)]
16pub enum SamplerMagFilter {
17 #[default]
18 Nearest,
19 Linear,
20}
21
22impl SamplerMagFilter {
23 pub const VALID_SAMPLER_MAG_FILTER: &[u32] = &[NEAREST, LINEAR];
24}
25
26impl From<SamplerMagFilter> for u32 {
27 fn from(value: SamplerMagFilter) -> Self {
28 match value {
29 SamplerMagFilter::Nearest => NEAREST,
30 SamplerMagFilter::Linear => LINEAR,
31 }
32 }
33}
34
35impl TryFrom<u32> for SamplerMagFilter {
36 type Error = ();
37
38 fn try_from(value: u32) -> Result<Self, Self::Error> {
39 match value {
40 NEAREST => Ok(SamplerMagFilter::Nearest),
41 LINEAR => Ok(SamplerMagFilter::Linear),
42 _ => Err(()),
43 }
44 }
45}
46impl Serialize for SamplerMagFilter {
47 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
48 where
49 S: serde::Serializer,
50 {
51 serializer.serialize_u32((*self).into())
52 }
53}
54
55impl<'de> Deserialize<'de> for Checked<SamplerMagFilter> {
56 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
57 where
58 D: serde::Deserializer<'de>,
59 {
60 struct Visitor;
61 impl de::Visitor<'_> for Visitor {
62 type Value = Checked<SamplerMagFilter>;
63
64 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
65 write!(
66 f,
67 "any of: {:?}",
68 SamplerMagFilter::VALID_SAMPLER_MAG_FILTER
69 )
70 }
71
72 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
73 where
74 E: de::Error,
75 {
76 Ok((value as u32)
77 .try_into()
78 .map(Checked::Valid)
79 .unwrap_or(Checked::Invalid))
80 }
81 }
82 deserializer.deserialize_u32(Visitor)
83 }
84}
85
86#[derive(Clone, Copy, Debug, Eq, PartialEq, Default)]
87pub enum SamplerMinFilter {
88 #[default]
89 Nearest,
90 Linear,
91 NearestMipmapNearest,
92 LinearMipmapNearest,
93 NearestMipmapLinear,
94 LinearMipmapLinear,
95}
96
97impl From<SamplerMinFilter> for u32 {
98 fn from(value: SamplerMinFilter) -> Self {
99 match value {
100 SamplerMinFilter::Nearest => NEAREST,
101 SamplerMinFilter::Linear => LINEAR,
102 SamplerMinFilter::NearestMipmapNearest => NEAREST_MIPMAP_NEAREST,
103 SamplerMinFilter::LinearMipmapNearest => LINEAR_MIPMAP_NEAREST,
104 SamplerMinFilter::NearestMipmapLinear => NEAREST_MIPMAP_LINEAR,
105 SamplerMinFilter::LinearMipmapLinear => LINEAR_MIPMAP_LINEAR,
106 }
107 }
108}
109
110impl TryFrom<u32> for SamplerMinFilter {
111 type Error = ();
112
113 fn try_from(value: u32) -> Result<Self, Self::Error> {
114 match value {
115 NEAREST => Ok(SamplerMinFilter::Nearest),
116 LINEAR => Ok(SamplerMinFilter::Linear),
117 NEAREST_MIPMAP_NEAREST => Ok(SamplerMinFilter::NearestMipmapNearest),
118 LINEAR_MIPMAP_NEAREST => Ok(SamplerMinFilter::LinearMipmapNearest),
119 NEAREST_MIPMAP_LINEAR => Ok(SamplerMinFilter::NearestMipmapLinear),
120 LINEAR_MIPMAP_LINEAR => Ok(SamplerMinFilter::LinearMipmapLinear),
121 _ => Err(()),
122 }
123 }
124}
125
126impl SamplerMinFilter {
127 pub const VALID_SAMPLER_MIN_FILTER: &[u32] = &[
128 NEAREST,
129 LINEAR,
130 NEAREST_MIPMAP_NEAREST,
131 LINEAR_MIPMAP_NEAREST,
132 NEAREST_MIPMAP_LINEAR,
133 LINEAR_MIPMAP_LINEAR,
134 ];
135}
136
137impl Serialize for SamplerMinFilter {
138 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
139 where
140 S: serde::Serializer,
141 {
142 serializer.serialize_u32((*self).into())
143 }
144}
145
146impl<'de> Deserialize<'de> for Checked<SamplerMinFilter> {
147 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
148 where
149 D: serde::Deserializer<'de>,
150 {
151 struct Visitor;
152 impl de::Visitor<'_> for Visitor {
153 type Value = Checked<SamplerMinFilter>;
154
155 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
156 write!(
157 f,
158 "any of: {:?}",
159 SamplerMinFilter::VALID_SAMPLER_MIN_FILTER
160 )
161 }
162
163 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
164 where
165 E: de::Error,
166 {
167 Ok((value as u32)
168 .try_into()
169 .map(Checked::Valid)
170 .unwrap_or(Checked::Invalid))
171 }
172 }
173 deserializer.deserialize_u32(Visitor)
174 }
175}
176
177pub const CLAMP_TO_EDGE: u32 = 33071;
178pub const MIRRORED_REPEAT: u32 = 33648;
179pub const REPEAT: u32 = 10497;
180
181#[derive(Clone, Copy, Debug, Eq, PartialEq, Default)]
182pub enum SamplerWrap {
183 #[default]
184 ClampToEdge,
185 MirroredRepeat,
186 Repeat,
187}
188
189impl From<SamplerWrap> for u32 {
190 fn from(value: SamplerWrap) -> Self {
191 match value {
192 SamplerWrap::ClampToEdge => CLAMP_TO_EDGE,
193 SamplerWrap::MirroredRepeat => MIRRORED_REPEAT,
194 SamplerWrap::Repeat => REPEAT,
195 }
196 }
197}
198
199impl TryFrom<u32> for SamplerWrap {
200 type Error = ();
201
202 fn try_from(value: u32) -> Result<Self, Self::Error> {
203 match value {
204 CLAMP_TO_EDGE => Ok(SamplerWrap::ClampToEdge),
205 MIRRORED_REPEAT => Ok(SamplerWrap::MirroredRepeat),
206 REPEAT => Ok(SamplerWrap::Repeat),
207 _ => Err(()),
208 }
209 }
210}
211
212impl SamplerWrap {
213 pub const VALID_SAMPLER_WRAP: &[u32] = &[CLAMP_TO_EDGE, MIRRORED_REPEAT, REPEAT];
214}
215
216impl Serialize for SamplerWrap {
217 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
218 where
219 S: serde::Serializer,
220 {
221 serializer.serialize_u32((*self).into())
222 }
223}
224
225impl<'de> Deserialize<'de> for Checked<SamplerWrap> {
226 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
227 where
228 D: serde::Deserializer<'de>,
229 {
230 struct Visitor;
231 impl de::Visitor<'_> for Visitor {
232 type Value = Checked<SamplerWrap>;
233
234 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
235 write!(f, "any of: {:?}", SamplerWrap::VALID_SAMPLER_WRAP)
236 }
237
238 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
239 where
240 E: de::Error,
241 {
242 Ok((value as u32)
243 .try_into()
244 .map(Checked::Valid)
245 .unwrap_or(Checked::Invalid))
246 }
247 }
248 deserializer.deserialize_u32(Visitor)
249 }
250}
251
252#[derive(Clone, Debug, serde_derive::Deserialize, serde_derive::Serialize, Validate, Default)]
253pub struct Sampler {
254 #[serde(rename = "magFilter", default = "default_mag_filter")]
255 pub mag_filter: Checked<SamplerMagFilter>,
256 #[serde(rename = "minFilter", default = "default_min_filter")]
257 pub min_filter: Checked<SamplerMinFilter>,
258 #[serde(rename = "wrapS", default = "default_wrap")]
259 pub wrap_s: Checked<SamplerWrap>,
260 #[serde(rename = "wrapT", default = "default_wrap")]
261 pub wrap_t: Checked<SamplerWrap>,
262 #[serde(skip_serializing_if = "Option::is_none")]
263 pub name: Option<String>,
264}
265
266fn default_mag_filter() -> Checked<SamplerMagFilter> {
267 Checked::Valid(SamplerMagFilter::Linear)
268}
269
270fn default_min_filter() -> Checked<SamplerMinFilter> {
271 Checked::Valid(SamplerMinFilter::LinearMipmapNearest)
272}
273
274fn default_wrap() -> Checked<SamplerWrap> {
275 Checked::Valid(SamplerWrap::Repeat)
276}
277
278pub const ALPHA: u32 = 6406;
279pub const RGB: u32 = 6407;
280pub const RGBA: u32 = 6408;
281pub const LUMINANCE: u32 = 6409;
282pub const LUMINANCE_ALPHA: u32 = 6410;
283
284#[derive(Clone, Copy, Debug, Eq, PartialEq, Default)]
285pub enum TextureFormat {
286 Alpha,
287 Rgb,
288 #[default]
289 Rgba,
290 Luminance,
291 LuminanceAlpha,
292}
293
294impl From<TextureFormat> for u32 {
295 fn from(value: TextureFormat) -> Self {
296 match value {
297 TextureFormat::Alpha => ALPHA,
298 TextureFormat::Rgb => RGB,
299 TextureFormat::Rgba => RGBA,
300 TextureFormat::Luminance => LUMINANCE,
301 TextureFormat::LuminanceAlpha => LUMINANCE_ALPHA,
302 }
303 }
304}
305
306impl TryFrom<u32> for TextureFormat {
307 type Error = ();
308
309 fn try_from(value: u32) -> Result<Self, Self::Error> {
310 match value {
311 ALPHA => Ok(TextureFormat::Alpha),
312 RGB => Ok(TextureFormat::Rgb),
313 RGBA => Ok(TextureFormat::Rgba),
314 LUMINANCE => Ok(TextureFormat::Luminance),
315 LUMINANCE_ALPHA => Ok(TextureFormat::LuminanceAlpha),
316 _ => Err(()),
317 }
318 }
319}
320
321impl TextureFormat {
322 pub const VALID_TEXTURE_FORMAT: &[u32] = &[ALPHA, RGB, RGBA, LUMINANCE, LUMINANCE_ALPHA];
323}
324
325impl Serialize for TextureFormat {
326 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
327 where
328 S: serde::Serializer,
329 {
330 serializer.serialize_u32((*self).into())
331 }
332}
333
334impl<'de> Deserialize<'de> for Checked<TextureFormat> {
335 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
336 where
337 D: serde::Deserializer<'de>,
338 {
339 struct Visitor;
340 impl serde::de::Visitor<'_> for Visitor {
341 type Value = Checked<TextureFormat>;
342
343 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
344 write!(f, "any of: {:?}", TextureFormat::VALID_TEXTURE_FORMAT)
345 }
346
347 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
348 where
349 E: de::Error,
350 {
351 Ok((value as u32)
352 .try_into()
353 .map(Checked::Valid)
354 .unwrap_or(Checked::Invalid))
355 }
356 }
357 deserializer.deserialize_u32(Visitor)
358 }
359}
360
361pub const TEXTURE_2D: u32 = 3553;
362
363#[derive(Clone, Copy, Debug, Eq, PartialEq, Default)]
364pub enum TextureTarget {
365 #[default]
366 Texture2d,
367}
368
369impl From<TextureTarget> for u32 {
370 fn from(value: TextureTarget) -> Self {
371 match value {
372 TextureTarget::Texture2d => TEXTURE_2D,
373 }
374 }
375}
376
377impl TryFrom<u32> for TextureTarget {
378 type Error = ();
379
380 fn try_from(value: u32) -> Result<Self, Self::Error> {
381 match value {
382 TEXTURE_2D => Ok(TextureTarget::Texture2d),
383 _ => Err(()),
384 }
385 }
386}
387
388impl TextureTarget {
389 pub const VALID_TEXTURE_TARGET: &[u32] = &[TEXTURE_2D];
390}
391
392impl Serialize for TextureTarget {
393 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
394 where
395 S: serde::Serializer,
396 {
397 serializer.serialize_u32((*self).into())
398 }
399}
400
401impl<'de> Deserialize<'de> for Checked<TextureTarget> {
402 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
403 where
404 D: serde::Deserializer<'de>,
405 {
406 struct Visitor;
407 impl de::Visitor<'_> for Visitor {
408 type Value = Checked<TextureTarget>;
409
410 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
411 write!(f, "any of: {:?}", TextureTarget::VALID_TEXTURE_TARGET)
412 }
413
414 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
415 where
416 E: de::Error,
417 {
418 Ok((value as u32)
419 .try_into()
420 .map(Checked::Valid)
421 .unwrap_or(Checked::Invalid))
422 }
423 }
424 deserializer.deserialize_u32(Visitor)
425 }
426}
427
428pub const UNSIGNED_BYTE: u32 = 5121;
429pub const UNSIGNED_SHORT5_6_5: u32 = 33635;
430pub const UNSIGNED_SHORT4_4_4_4: u32 = 32819;
431pub const UNSIGNED_SHORT5_5_5_1: u32 = 32820;
432
433#[derive(Clone, Copy, Debug, Eq, PartialEq, Default)]
434pub enum TextureType {
435 #[default]
436 UnsignedByte,
437 UnsignedShort5_6_5,
438 UnsignedShort4_4_4_4,
439 UnsignedShort5_5_5_1,
440}
441
442impl From<TextureType> for u32 {
443 fn from(value: TextureType) -> Self {
444 match value {
445 TextureType::UnsignedByte => UNSIGNED_BYTE,
446 TextureType::UnsignedShort5_6_5 => UNSIGNED_SHORT5_6_5,
447 TextureType::UnsignedShort4_4_4_4 => UNSIGNED_SHORT4_4_4_4,
448 TextureType::UnsignedShort5_5_5_1 => UNSIGNED_SHORT5_5_5_1,
449 }
450 }
451}
452
453impl TryFrom<u32> for TextureType {
454 type Error = ();
455
456 fn try_from(value: u32) -> Result<Self, Self::Error> {
457 match value {
458 UNSIGNED_BYTE => Ok(TextureType::UnsignedByte),
459 UNSIGNED_SHORT5_6_5 => Ok(TextureType::UnsignedShort5_6_5),
460 UNSIGNED_SHORT4_4_4_4 => Ok(TextureType::UnsignedShort4_4_4_4),
461 UNSIGNED_SHORT5_5_5_1 => Ok(TextureType::UnsignedShort5_5_5_1),
462 _ => Err(()),
463 }
464 }
465}
466
467impl TextureType {
468 pub const VALID_TEXTURE_TYPE: &[u32] = &[
469 UNSIGNED_BYTE,
470 UNSIGNED_SHORT5_6_5,
471 UNSIGNED_SHORT4_4_4_4,
472 UNSIGNED_SHORT5_5_5_1,
473 ];
474}
475
476impl Serialize for TextureType {
477 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
478 where
479 S: serde::Serializer,
480 {
481 serializer.serialize_u32((*self).into())
482 }
483}
484
485impl<'de> Deserialize<'de> for Checked<TextureType> {
486 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
487 where
488 D: serde::Deserializer<'de>,
489 {
490 struct Visitor;
491 impl de::Visitor<'_> for Visitor {
492 type Value = Checked<TextureType>;
493
494 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
495 write!(f, "any of: {:?}", TextureType::VALID_TEXTURE_TYPE)
496 }
497
498 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
499 where
500 E: de::Error,
501 {
502 Ok((value as u32)
503 .try_into()
504 .map(Checked::Valid)
505 .unwrap_or(Checked::Invalid))
506 }
507 }
508 deserializer.deserialize_u32(Visitor)
509 }
510}
511
512#[derive(Clone, Debug, serde_derive::Deserialize, serde_derive::Serialize, Validate)]
513pub struct Texture {
514 #[serde(default = "default_texture_format")]
515 pub format: Checked<TextureFormat>,
516 #[serde(rename = "internalFormat", default = "default_texture_format")]
517 pub internal_format: Checked<TextureFormat>,
518 pub sampler: StringIndex<Sampler>,
519 pub source: StringIndex<Image>,
520 #[serde(default = "default_texture_target")]
521 pub target: Checked<TextureTarget>,
522 #[serde(rename = "type", default = "default_texture_type")]
523 pub type_: Checked<TextureType>,
524 #[serde(skip_serializing_if = "Option::is_none")]
525 pub name: Option<String>,
526}
527
528impl Texture {
529 pub fn new(source: StringIndex<Image>, sampler: StringIndex<Sampler>) -> Self {
530 Self {
531 source,
532 format: Default::default(),
533 internal_format: Default::default(),
534 sampler,
535 target: Default::default(),
536 type_: Default::default(),
537 name: None,
538 }
539 }
540}
541
542fn default_texture_format() -> Checked<TextureFormat> {
543 Checked::Valid(TextureFormat::Rgba)
544}
545
546fn default_texture_target() -> Checked<TextureTarget> {
547 Checked::Valid(TextureTarget::Texture2d)
548}
549fn default_texture_type() -> Checked<TextureType> {
550 Checked::Valid(TextureType::UnsignedByte)
551}
552
553#[test]
554fn test_sampler_deserialize() {
555 let data = r#"{
556 "magFilter": 9729,
557 "minFilter": 9987,
558 "name": "user-defined sampler name",
559 "wrapS": 10497,
560 "wrapT": 10497,
561 "extensions" : {
562 "extension_name" : {
563 "extension specific" : "value"
564 }
565 },
566 "extras" : {
567 "Application specific" : "The extra object can contain any properties."
568 }
569 }"#;
570 let sampler: Result<Sampler, _> = serde_json::from_str(data);
571 let sampler_unwrap = sampler.unwrap();
572 println!("{}", serde_json::to_string(&sampler_unwrap).unwrap());
573 assert_eq!(
574 Some("user-defined sampler name".to_string()),
575 sampler_unwrap.name
576 );
577}
578
579#[test]
580fn test_texture_deserialize() {
581 let data = r#"{
582 "format": 6408,
583 "internalFormat": 6408,
584 "name": "user-defined texture name",
585 "sampler": "sampler_id",
586 "source": "image_id",
587 "target": 3553,
588 "type": 5121,
589 "extensions" : {
590 "extension_name" : {
591 "extension specific" : "value"
592 }
593 },
594 "extras" : {
595 "Application specific" : "The extra object can contain any properties."
596 }
597 }"#;
598 let texture: Result<Texture, _> = serde_json::from_str(data);
599 let texture_unwrap = texture.unwrap();
600 println!("{}", serde_json::to_string(&texture_unwrap).unwrap());
601 assert_eq!(
602 Some("user-defined texture name".to_string()),
603 texture_unwrap.name
604 );
605}