gltf_v1_json/
material.rs

1use std::fmt;
2
3use gltf_v1_derive::Validate;
4use indexmap::IndexMap;
5use serde::{Deserialize, Serialize, de, ser::SerializeSeq};
6
7use crate::{
8    Path, Program, Root, extensions,
9    validation::{Error, USize64},
10};
11
12use super::{common::StringIndex, node::Node, validation::Checked};
13
14pub const BYTE: u32 = 5120;
15pub const UNSIGNED_BYTE: u32 = 5121;
16pub const SHORT: u32 = 5122;
17pub const UNSIGNED_SHORT: u32 = 5123;
18pub const INT: u32 = 5124;
19pub const UNSIGNED_INT: u32 = 5125;
20pub const FLOAT: u32 = 5126;
21pub const FLOAT_VEC2: u32 = 35664;
22pub const FLOAT_VEC3: u32 = 35665;
23pub const FLOAT_VEC4: u32 = 35666;
24pub const INT_VEC2: u32 = 35667;
25pub const INT_VEC3: u32 = 35668;
26pub const INT_VEC4: u32 = 35669;
27pub const BOOL: u32 = 35670;
28pub const BOOL_VEC2: u32 = 35671;
29pub const BOOL_VEC3: u32 = 35672;
30pub const BOOL_VEC4: u32 = 35673;
31pub const FLOAT_MAT2: u32 = 35674;
32pub const FLOAT_MAT3: u32 = 35675;
33pub const FLOAT_MAT4: u32 = 35676;
34pub const SAMPLER_2D: u32 = 35678;
35
36#[derive(Clone, Debug, Copy, Default)]
37pub enum ParameterType {
38    Byte,
39    UnsignedByte,
40    Short,
41    UnsignedShort,
42    Int,
43    UnsignedInt,
44    #[default]
45    Float,
46    FloatVec2,
47    FloatVec3,
48    FloatVec4,
49    IntVec2,
50    IntVec3,
51    IntVec4,
52    Bool,
53    BoolVec2,
54    BoolVec3,
55    BoolVec4,
56    FloatMat2,
57    FloatMat3,
58    FloatMat4,
59    Sampler2d,
60}
61
62impl ParameterType {
63    pub const VALID_PARAMETER_TYPES: &[u32] = &[
64        BYTE,
65        UNSIGNED_BYTE,
66        SHORT,
67        UNSIGNED_SHORT,
68        INT,
69        UNSIGNED_INT,
70        FLOAT,
71        FLOAT_VEC2,
72        FLOAT_VEC3,
73        FLOAT_VEC4,
74        INT_VEC2,
75        INT_VEC3,
76        INT_VEC4,
77        BOOL,
78        BOOL_VEC2,
79        BOOL_VEC3,
80        BOOL_VEC4,
81        FLOAT_MAT2,
82        FLOAT_MAT3,
83        FLOAT_MAT4,
84        SAMPLER_2D,
85    ];
86}
87
88impl TryFrom<u32> for ParameterType {
89    type Error = ();
90
91    fn try_from(value: u32) -> Result<Self, Self::Error> {
92        match value {
93            BYTE => Ok(ParameterType::Byte),
94            UNSIGNED_BYTE => Ok(ParameterType::UnsignedByte),
95            SHORT => Ok(ParameterType::Short),
96            UNSIGNED_SHORT => Ok(ParameterType::UnsignedShort),
97            INT => Ok(ParameterType::Int),
98            UNSIGNED_INT => Ok(ParameterType::UnsignedInt),
99            FLOAT => Ok(ParameterType::Float),
100            FLOAT_VEC2 => Ok(ParameterType::FloatVec2),
101            FLOAT_VEC3 => Ok(ParameterType::FloatVec3),
102            FLOAT_VEC4 => Ok(ParameterType::FloatVec4),
103            INT_VEC2 => Ok(ParameterType::IntVec2),
104            INT_VEC3 => Ok(ParameterType::IntVec3),
105            INT_VEC4 => Ok(ParameterType::IntVec4),
106            BOOL => Ok(ParameterType::Bool),
107            BOOL_VEC2 => Ok(ParameterType::BoolVec2),
108            BOOL_VEC3 => Ok(ParameterType::BoolVec3),
109            BOOL_VEC4 => Ok(ParameterType::BoolVec4),
110            FLOAT_MAT2 => Ok(ParameterType::FloatMat2),
111            FLOAT_MAT3 => Ok(ParameterType::FloatMat3),
112            FLOAT_MAT4 => Ok(ParameterType::FloatMat4),
113            SAMPLER_2D => Ok(ParameterType::Sampler2d),
114            _ => Err(()),
115        }
116    }
117}
118
119impl From<ParameterType> for u32 {
120    fn from(value: ParameterType) -> Self {
121        match value {
122            ParameterType::Byte => BYTE,
123            ParameterType::UnsignedByte => UNSIGNED_BYTE,
124            ParameterType::Short => SHORT,
125            ParameterType::UnsignedShort => UNSIGNED_SHORT,
126            ParameterType::Int => INT,
127            ParameterType::UnsignedInt => UNSIGNED_INT,
128            ParameterType::Float => FLOAT,
129            ParameterType::FloatVec2 => FLOAT_VEC2,
130            ParameterType::FloatVec3 => FLOAT_VEC3,
131            ParameterType::FloatVec4 => FLOAT_VEC4,
132            ParameterType::IntVec2 => INT_VEC2,
133            ParameterType::IntVec3 => INT_VEC3,
134            ParameterType::IntVec4 => INT_VEC4,
135            ParameterType::Bool => BOOL,
136            ParameterType::BoolVec2 => BOOL_VEC2,
137            ParameterType::BoolVec3 => BOOL_VEC3,
138            ParameterType::BoolVec4 => BOOL_VEC4,
139            ParameterType::FloatMat2 => FLOAT_MAT2,
140            ParameterType::FloatMat3 => FLOAT_MAT3,
141            ParameterType::FloatMat4 => FLOAT_MAT4,
142            ParameterType::Sampler2d => SAMPLER_2D,
143        }
144    }
145}
146
147impl Serialize for ParameterType {
148    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
149    where
150        S: serde::Serializer,
151    {
152        serializer.serialize_u32((*self).into())
153    }
154}
155
156impl<'de> Deserialize<'de> for Checked<ParameterType> {
157    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
158    where
159        D: serde::Deserializer<'de>,
160    {
161        struct Visitor;
162        impl serde::de::Visitor<'_> for Visitor {
163            type Value = Checked<ParameterType>;
164
165            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
166                write!(f, "any of: {:?}", ParameterType::VALID_PARAMETER_TYPES)
167            }
168
169            fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
170            where
171                E: de::Error,
172            {
173                Ok((value as u32)
174                    .try_into()
175                    .map(Checked::Valid)
176                    .unwrap_or(Checked::Invalid))
177            }
178        }
179        deserializer.deserialize_u32(Visitor)
180    }
181}
182
183#[derive(Clone, Debug)]
184pub enum ParameterValue {
185    Number(f32),
186    Boolean(bool),
187    String(String),
188    NumberArray(Vec<f32>),
189    BoolArray(Vec<bool>),
190    StringArray(Vec<String>),
191}
192
193impl Serialize for ParameterValue {
194    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
195    where
196        S: serde::Serializer,
197    {
198        match self {
199            ParameterValue::Number(value) => serializer.serialize_f32(*value),
200            ParameterValue::Boolean(value) => serializer.serialize_bool(*value),
201            ParameterValue::String(value) => serializer.serialize_str(value),
202            ParameterValue::NumberArray(value) => {
203                let mut seq = serializer.serialize_seq(Some(value.len()))?;
204                for v in value {
205                    seq.serialize_element(v)?;
206                }
207                seq.end()
208            }
209            ParameterValue::BoolArray(value) => {
210                let mut seq = serializer.serialize_seq(Some(value.len()))?;
211                for v in value {
212                    seq.serialize_element(v)?;
213                }
214                seq.end()
215            }
216            ParameterValue::StringArray(value) => {
217                let mut seq = serializer.serialize_seq(Some(value.len()))?;
218                for v in value {
219                    seq.serialize_element(v)?;
220                }
221                seq.end()
222            }
223        }
224    }
225}
226
227impl<'de> Deserialize<'de> for Checked<ParameterValue> {
228    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
229    where
230        D: serde::Deserializer<'de>,
231    {
232        struct ParameterValueVisitor;
233
234        impl<'de> serde::de::Visitor<'de> for ParameterValueVisitor {
235            type Value = Checked<ParameterValue>;
236
237            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
238                formatter.write_str("a number, boolean, string, or array of these types")
239            }
240
241            fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
242            where
243                E: de::Error,
244            {
245                Ok(Checked::Valid(ParameterValue::Number(value as f32)))
246            }
247
248            fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
249            where
250                E: de::Error,
251            {
252                Ok(Checked::Valid(ParameterValue::Number(value as f32)))
253            }
254
255            fn visit_f64<E>(self, value: f64) -> Result<Self::Value, E>
256            where
257                E: de::Error,
258            {
259                Ok(Checked::Valid(ParameterValue::Number(value as f32)))
260            }
261
262            fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E>
263            where
264                E: de::Error,
265            {
266                Ok(Checked::Valid(ParameterValue::Boolean(value)))
267            }
268
269            fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
270            where
271                E: de::Error,
272            {
273                Ok(Checked::Valid(ParameterValue::String(value.to_string())))
274            }
275
276            fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
277            where
278                A: serde::de::SeqAccess<'de>,
279            {
280                // Try to deserialize as Vec<f32>
281                if let Some(first) = seq.next_element::<f64>()? {
282                    let mut vec = vec![first as f32];
283                    while let Some(val) = seq.next_element::<f64>()? {
284                        vec.push(val as f32);
285                    }
286                    return Ok(Checked::Valid(ParameterValue::NumberArray(vec)));
287                }
288
289                // Try to deserialize as Vec<bool>
290                if let Some(first) = seq.next_element::<bool>()? {
291                    let mut vec = vec![first];
292                    while let Some(val) = seq.next_element()? {
293                        vec.push(val);
294                    }
295                    return Ok(Checked::Valid(ParameterValue::BoolArray(vec)));
296                }
297
298                // Try to deserialize as Vec<String>
299                if let Some(first) = seq.next_element::<String>()? {
300                    let mut vec = vec![first];
301                    while let Some(val) = seq.next_element()? {
302                        vec.push(val);
303                    }
304                    return Ok(Checked::Valid(ParameterValue::StringArray(vec)));
305                }
306
307                Ok(Checked::Invalid)
308            }
309        }
310
311        deserializer.deserialize_any(ParameterValueVisitor)
312    }
313}
314
315pub const BLEND: u32 = 3042;
316pub const CULL_FACE: u32 = 2884;
317pub const DEPTH_TEST: u32 = 2929;
318pub const POLYGON_OFFSET_FILL: u32 = 32823;
319pub const SAMPLE_ALPHA_TO_COVERAGE: u32 = 32926;
320pub const SCISSOR_TEST: u32 = 3089;
321
322#[derive(Clone, Debug, PartialEq, Eq, Copy)]
323pub enum WebGLState {
324    Blend,
325    CullFace,
326    DepthTest,
327    PolygonOffsetFill,
328    SampleAlphaToCoverage,
329    ScissorTest,
330}
331
332impl WebGLState {
333    pub const VALID_WEB_GL_STATES: &[u32] = &[
334        BLEND,
335        CULL_FACE,
336        DEPTH_TEST,
337        POLYGON_OFFSET_FILL,
338        SAMPLE_ALPHA_TO_COVERAGE,
339        SCISSOR_TEST,
340    ];
341}
342
343impl From<WebGLState> for u32 {
344    fn from(value: WebGLState) -> Self {
345        match value {
346            WebGLState::Blend => BLEND,
347            WebGLState::CullFace => CULL_FACE,
348            WebGLState::DepthTest => DEPTH_TEST,
349            WebGLState::PolygonOffsetFill => POLYGON_OFFSET_FILL,
350            WebGLState::SampleAlphaToCoverage => SAMPLE_ALPHA_TO_COVERAGE,
351            WebGLState::ScissorTest => SCISSOR_TEST,
352        }
353    }
354}
355
356impl TryFrom<u32> for WebGLState {
357    type Error = ();
358
359    fn try_from(value: u32) -> Result<Self, Self::Error> {
360        match value {
361            BLEND => Ok(WebGLState::Blend),
362            CULL_FACE => Ok(WebGLState::CullFace),
363            DEPTH_TEST => Ok(WebGLState::DepthTest),
364            POLYGON_OFFSET_FILL => Ok(WebGLState::PolygonOffsetFill),
365            SAMPLE_ALPHA_TO_COVERAGE => Ok(WebGLState::SampleAlphaToCoverage),
366            SCISSOR_TEST => Ok(WebGLState::ScissorTest),
367            _ => Err(()),
368        }
369    }
370}
371
372impl Serialize for WebGLState {
373    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
374    where
375        S: serde::Serializer,
376    {
377        serializer.serialize_u32((*self).into())
378    }
379}
380
381impl<'de> Deserialize<'de> for Checked<WebGLState> {
382    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
383    where
384        D: serde::Deserializer<'de>,
385    {
386        struct Visitor;
387        impl serde::de::Visitor<'_> for Visitor {
388            type Value = Checked<WebGLState>;
389
390            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
391                write!(f, "any of: {:?}", WebGLState::VALID_WEB_GL_STATES)
392            }
393
394            fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
395            where
396                E: de::Error,
397            {
398                Ok((value as u32)
399                    .try_into()
400                    .map(Checked::Valid)
401                    .unwrap_or(Checked::Invalid))
402            }
403        }
404        deserializer.deserialize_u32(Visitor)
405    }
406}
407
408#[derive(Clone, Debug, serde_derive::Deserialize, serde_derive::Serialize, Validate, Default)]
409pub struct TechniqueParameter {
410    #[serde(skip_serializing_if = "Option::is_none")]
411    pub count: Option<USize64>,
412    #[serde(skip_serializing_if = "Option::is_none")]
413    pub node: Option<StringIndex<Node>>,
414    #[serde(rename = "type")]
415    pub type_: Checked<ParameterType>,
416    #[serde(skip_serializing_if = "Option::is_none")]
417    pub semantic: Option<String>,
418    #[serde(skip_serializing_if = "Option::is_none")]
419    pub value: Option<Checked<ParameterValue>>,
420}
421
422pub const FUNC_ADD: u32 = 32774;
423pub const FUNC_SUBTRACT: u32 = 32778;
424pub const FUNC_REVERSE_SUBTRACT: u32 = 32779;
425
426#[derive(Clone, Debug, PartialEq, Eq, Copy)]
427pub enum BlendEquationSeparate {
428    FuncAdd,
429    FuncSubtract,
430    FuncReverseSubtract,
431}
432
433impl BlendEquationSeparate {
434    pub const VALID_BLEND_EQUATION_SEPARATES: &[u32] =
435        &[FUNC_ADD, FUNC_SUBTRACT, FUNC_REVERSE_SUBTRACT];
436}
437
438impl From<BlendEquationSeparate> for u32 {
439    fn from(value: BlendEquationSeparate) -> Self {
440        match value {
441            BlendEquationSeparate::FuncAdd => FUNC_ADD,
442            BlendEquationSeparate::FuncSubtract => FUNC_SUBTRACT,
443            BlendEquationSeparate::FuncReverseSubtract => FUNC_REVERSE_SUBTRACT,
444        }
445    }
446}
447
448impl TryFrom<u32> for BlendEquationSeparate {
449    type Error = ();
450
451    fn try_from(value: u32) -> Result<Self, Self::Error> {
452        match value {
453            FUNC_ADD => Ok(BlendEquationSeparate::FuncAdd),
454            FUNC_SUBTRACT => Ok(BlendEquationSeparate::FuncSubtract),
455            FUNC_REVERSE_SUBTRACT => Ok(BlendEquationSeparate::FuncReverseSubtract),
456            _ => Err(()),
457        }
458    }
459}
460
461impl Serialize for BlendEquationSeparate {
462    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
463    where
464        S: serde::Serializer,
465    {
466        serializer.serialize_u32((*self).into())
467    }
468}
469
470impl<'de> Deserialize<'de> for Checked<BlendEquationSeparate> {
471    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
472    where
473        D: serde::Deserializer<'de>,
474    {
475        struct Visitor;
476        impl serde::de::Visitor<'_> for Visitor {
477            type Value = Checked<BlendEquationSeparate>;
478
479            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
480                write!(
481                    f,
482                    "any of: {:?}",
483                    BlendEquationSeparate::VALID_BLEND_EQUATION_SEPARATES
484                )
485            }
486
487            fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
488            where
489                E: de::Error,
490            {
491                Ok((value as u32)
492                    .try_into()
493                    .map(Checked::Valid)
494                    .unwrap_or(Checked::Invalid))
495            }
496        }
497        deserializer.deserialize_u32(Visitor)
498    }
499}
500
501pub const ZERO: u32 = 0;
502pub const ONE: u32 = 1;
503pub const SRC_COLOR: u32 = 768;
504pub const ONE_MINUS_SRC_COLOR: u32 = 769;
505pub const DST_COLOR: u32 = 774;
506pub const ONE_MINUS_DST_COLOR: u32 = 775;
507pub const SRC_ALPHA: u32 = 770;
508pub const ONE_MINUS_SRC_ALPHA: u32 = 771;
509pub const DST_ALPHA: u32 = 772;
510pub const ONE_MINUS_DST_ALPHA: u32 = 773;
511pub const CONSTANT_COLOR: u32 = 32769;
512pub const ONE_MINUS_CONSTANT_COLOR: u32 = 32770;
513pub const CONSTANT_ALPHA: u32 = 32771;
514pub const ONE_MINUS_CONSTANT_ALPHA: u32 = 32772;
515pub const SRC_ALPHA_SATURATE: u32 = 776;
516
517#[derive(Clone, Debug, PartialEq, Eq, Copy)]
518pub enum BlendFuncSeparate {
519    Zero,
520    One,
521    SrcColor,
522    OneMinusSrcColor,
523    DstColor,
524    OneMinusDstColor,
525    SrcAlpha,
526    OneMinusSrcAlpha,
527    DstAlpha,
528    OneMinusDstAlpha,
529    ConstantColor,
530    OneMinusConstantColor,
531    ConstantAlpha,
532    OneMinusConstantAlpha,
533    SrcAlphaSaturate,
534}
535
536impl BlendFuncSeparate {
537    pub const VALID_BLEND_FUNC_SEPARATES: &[u32] = &[
538        ZERO,
539        ONE,
540        SRC_COLOR,
541        ONE_MINUS_SRC_COLOR,
542        DST_COLOR,
543        ONE_MINUS_DST_COLOR,
544        SRC_ALPHA,
545        ONE_MINUS_SRC_ALPHA,
546        DST_ALPHA,
547        ONE_MINUS_DST_ALPHA,
548        CONSTANT_COLOR,
549        ONE_MINUS_CONSTANT_COLOR,
550        CONSTANT_ALPHA,
551        ONE_MINUS_CONSTANT_ALPHA,
552        SRC_ALPHA_SATURATE,
553    ];
554}
555
556impl From<BlendFuncSeparate> for u32 {
557    fn from(value: BlendFuncSeparate) -> Self {
558        match value {
559            BlendFuncSeparate::Zero => ZERO,
560            BlendFuncSeparate::One => ONE,
561            BlendFuncSeparate::SrcColor => SRC_COLOR,
562            BlendFuncSeparate::OneMinusSrcColor => ONE_MINUS_SRC_COLOR,
563            BlendFuncSeparate::DstColor => DST_COLOR,
564            BlendFuncSeparate::OneMinusDstColor => ONE_MINUS_DST_COLOR,
565            BlendFuncSeparate::SrcAlpha => SRC_ALPHA,
566            BlendFuncSeparate::OneMinusSrcAlpha => ONE_MINUS_SRC_ALPHA,
567            BlendFuncSeparate::DstAlpha => DST_ALPHA,
568            BlendFuncSeparate::OneMinusDstAlpha => ONE_MINUS_DST_ALPHA,
569            BlendFuncSeparate::ConstantColor => CONSTANT_COLOR,
570            BlendFuncSeparate::OneMinusConstantColor => ONE_MINUS_CONSTANT_COLOR,
571            BlendFuncSeparate::ConstantAlpha => CONSTANT_ALPHA,
572            BlendFuncSeparate::OneMinusConstantAlpha => ONE_MINUS_CONSTANT_ALPHA,
573            BlendFuncSeparate::SrcAlphaSaturate => SRC_ALPHA_SATURATE,
574        }
575    }
576}
577
578impl TryFrom<u32> for BlendFuncSeparate {
579    type Error = ();
580
581    fn try_from(value: u32) -> Result<Self, Self::Error> {
582        match value {
583            ZERO => Ok(BlendFuncSeparate::Zero),
584            ONE => Ok(BlendFuncSeparate::One),
585            SRC_COLOR => Ok(BlendFuncSeparate::SrcColor),
586            ONE_MINUS_SRC_COLOR => Ok(BlendFuncSeparate::OneMinusSrcColor),
587            DST_COLOR => Ok(BlendFuncSeparate::DstColor),
588            ONE_MINUS_DST_COLOR => Ok(BlendFuncSeparate::OneMinusDstColor),
589            SRC_ALPHA => Ok(BlendFuncSeparate::SrcAlpha),
590            ONE_MINUS_SRC_ALPHA => Ok(BlendFuncSeparate::OneMinusSrcAlpha),
591            DST_ALPHA => Ok(BlendFuncSeparate::DstAlpha),
592            ONE_MINUS_DST_ALPHA => Ok(BlendFuncSeparate::OneMinusDstAlpha),
593            CONSTANT_COLOR => Ok(BlendFuncSeparate::ConstantColor),
594            ONE_MINUS_CONSTANT_COLOR => Ok(BlendFuncSeparate::OneMinusConstantColor),
595            CONSTANT_ALPHA => Ok(BlendFuncSeparate::ConstantAlpha),
596            ONE_MINUS_CONSTANT_ALPHA => Ok(BlendFuncSeparate::OneMinusConstantAlpha),
597            SRC_ALPHA_SATURATE => Ok(BlendFuncSeparate::SrcAlphaSaturate),
598            _ => Err(()),
599        }
600    }
601}
602
603impl Serialize for BlendFuncSeparate {
604    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
605    where
606        S: serde::Serializer,
607    {
608        serializer.serialize_u32((*self).into())
609    }
610}
611
612impl<'de> Deserialize<'de> for Checked<BlendFuncSeparate> {
613    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
614    where
615        D: serde::Deserializer<'de>,
616    {
617        struct Visitor;
618        impl serde::de::Visitor<'_> for Visitor {
619            type Value = Checked<BlendFuncSeparate>;
620
621            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
622                write!(
623                    f,
624                    "any of: {:?}",
625                    BlendFuncSeparate::VALID_BLEND_FUNC_SEPARATES
626                )
627            }
628
629            fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
630            where
631                E: de::Error,
632            {
633                Ok((value as u32)
634                    .try_into()
635                    .map(Checked::Valid)
636                    .unwrap_or(Checked::Invalid))
637            }
638        }
639        deserializer.deserialize_u32(Visitor)
640    }
641}
642
643pub const FRONT: u32 = 1028;
644pub const BACK: u32 = 1029;
645pub const FRONT_AND_BACK: u32 = 1032;
646
647#[derive(Clone, Debug, PartialEq, Eq, Copy)]
648pub enum CullFace {
649    Front,
650    Back,
651    FrontAndBack,
652}
653
654impl CullFace {
655    pub const VALID_CULL_FACES: &[u32] = &[FRONT, BACK, FRONT_AND_BACK];
656}
657
658impl From<CullFace> for u32 {
659    fn from(value: CullFace) -> Self {
660        match value {
661            CullFace::Front => FRONT,
662            CullFace::Back => BACK,
663            CullFace::FrontAndBack => FRONT_AND_BACK,
664        }
665    }
666}
667
668impl TryFrom<u32> for CullFace {
669    type Error = ();
670
671    fn try_from(value: u32) -> Result<Self, Self::Error> {
672        match value {
673            FRONT => Ok(CullFace::Front),
674            BACK => Ok(CullFace::Back),
675            FRONT_AND_BACK => Ok(CullFace::FrontAndBack),
676            _ => Err(()),
677        }
678    }
679}
680
681impl Serialize for CullFace {
682    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
683    where
684        S: serde::Serializer,
685    {
686        serializer.serialize_u32((*self).into())
687    }
688}
689
690impl<'de> Deserialize<'de> for Checked<CullFace> {
691    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
692    where
693        D: serde::Deserializer<'de>,
694    {
695        struct Visitor;
696        impl serde::de::Visitor<'_> for Visitor {
697            type Value = Checked<CullFace>;
698
699            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
700                write!(f, "any of: {:?}", CullFace::VALID_CULL_FACES)
701            }
702
703            fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
704            where
705                E: de::Error,
706            {
707                Ok((value as u32)
708                    .try_into()
709                    .map(Checked::Valid)
710                    .unwrap_or(Checked::Invalid))
711            }
712        }
713        deserializer.deserialize_u32(Visitor)
714    }
715}
716
717pub const NEVER: u32 = 512;
718pub const LESS: u32 = 513;
719pub const LEQUAL: u32 = 515;
720pub const EQUAL: u32 = 514;
721pub const GREATER: u32 = 516;
722pub const NOTEQUAL: u32 = 517;
723pub const GEQUAL: u32 = 518;
724pub const ALWAYS: u32 = 519;
725
726#[derive(Clone, Debug, PartialEq, Eq, Copy)]
727pub enum DepthFunc {
728    Never,
729    Less,
730    LEqual,
731    Equal,
732    Greater,
733    NotEqual,
734    GEqual,
735    Always,
736}
737
738impl DepthFunc {
739    pub const VALID_DEPTH_FUNCS: &[u32] = &[
740        NEVER, LESS, LEQUAL, EQUAL, GREATER, NOTEQUAL, GEQUAL, ALWAYS,
741    ];
742}
743
744impl From<DepthFunc> for u32 {
745    fn from(value: DepthFunc) -> Self {
746        match value {
747            DepthFunc::Never => NEVER,
748            DepthFunc::Less => LESS,
749            DepthFunc::LEqual => LEQUAL,
750            DepthFunc::Equal => EQUAL,
751            DepthFunc::Greater => GREATER,
752            DepthFunc::NotEqual => NOTEQUAL,
753            DepthFunc::GEqual => GEQUAL,
754            DepthFunc::Always => ALWAYS,
755        }
756    }
757}
758
759impl TryFrom<u32> for DepthFunc {
760    type Error = ();
761
762    fn try_from(value: u32) -> Result<Self, Self::Error> {
763        match value {
764            NEVER => Ok(DepthFunc::Never),
765            LESS => Ok(DepthFunc::Less),
766            LEQUAL => Ok(DepthFunc::LEqual),
767            EQUAL => Ok(DepthFunc::Equal),
768            GREATER => Ok(DepthFunc::Greater),
769            NOTEQUAL => Ok(DepthFunc::NotEqual),
770            GEQUAL => Ok(DepthFunc::GEqual),
771            ALWAYS => Ok(DepthFunc::Always),
772            _ => Err(()),
773        }
774    }
775}
776
777impl Serialize for DepthFunc {
778    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
779    where
780        S: serde::Serializer,
781    {
782        serializer.serialize_u32((*self).into())
783    }
784}
785
786impl<'de> Deserialize<'de> for Checked<DepthFunc> {
787    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
788    where
789        D: serde::Deserializer<'de>,
790    {
791        struct Visitor;
792        impl serde::de::Visitor<'_> for Visitor {
793            type Value = Checked<DepthFunc>;
794
795            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
796                write!(f, "any of: {:?}", DepthFunc::VALID_DEPTH_FUNCS)
797            }
798
799            fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
800            where
801                E: de::Error,
802            {
803                Ok((value as u32)
804                    .try_into()
805                    .map(Checked::Valid)
806                    .unwrap_or(Checked::Invalid))
807            }
808        }
809        deserializer.deserialize_u32(Visitor)
810    }
811}
812
813pub const CW: u32 = 2304;
814pub const CCW: u32 = 2305;
815
816#[derive(Clone, Debug, PartialEq, Eq, Copy)]
817pub enum FrontFace {
818    CW,
819    CCW,
820}
821
822impl FrontFace {
823    pub const VALID_FRONT_FACES: &[u32] = &[CW, CCW];
824}
825
826impl From<FrontFace> for u32 {
827    fn from(value: FrontFace) -> Self {
828        match value {
829            FrontFace::CW => CW,
830            FrontFace::CCW => CCW,
831        }
832    }
833}
834
835impl TryFrom<u32> for FrontFace {
836    type Error = ();
837
838    fn try_from(value: u32) -> Result<Self, Self::Error> {
839        match value {
840            CW => Ok(FrontFace::CW),
841            CCW => Ok(FrontFace::CCW),
842            _ => Err(()),
843        }
844    }
845}
846
847impl Serialize for FrontFace {
848    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
849    where
850        S: serde::Serializer,
851    {
852        serializer.serialize_u32((*self).into())
853    }
854}
855
856impl<'de> Deserialize<'de> for Checked<FrontFace> {
857    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
858    where
859        D: serde::Deserializer<'de>,
860    {
861        struct Visitor;
862        impl serde::de::Visitor<'_> for Visitor {
863            type Value = Checked<FrontFace>;
864
865            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
866                write!(f, "any of: {:?}", FrontFace::VALID_FRONT_FACES)
867            }
868
869            fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
870            where
871                E: de::Error,
872            {
873                Ok((value as u32)
874                    .try_into()
875                    .map(Checked::Valid)
876                    .unwrap_or(Checked::Invalid))
877            }
878        }
879        deserializer.deserialize_u32(Visitor)
880    }
881}
882#[derive(Clone, Debug, serde_derive::Deserialize, serde_derive::Serialize, Validate)]
883pub struct TechniqueStateFunction {
884    #[serde(
885        rename = "blendColor",
886        skip_serializing_if = "blend_color_is_zero",
887        default = "default_blend_color"
888    )]
889    pub blend_color: [f32; 4],
890    #[serde(
891        rename = "blendEquationSeparate",
892        skip_serializing_if = "blend_equation_seperate_is_default",
893        default = "default_blend_equation_seperate"
894    )]
895    pub blend_equation_seperate: [Checked<BlendEquationSeparate>; 2],
896    #[serde(
897        rename = "blendFuncSeparate",
898        skip_serializing_if = "blend_func_seperate_is_default",
899        default = "default_blend_func_seperate"
900    )]
901    pub blend_func_seperate: [Checked<BlendFuncSeparate>; 4],
902    #[serde(
903        rename = "colorMask",
904        skip_serializing_if = "color_mask_is_default",
905        default = "default_color_mask"
906    )]
907    pub color_mask: [bool; 4],
908    #[serde(
909        rename = "cullFace",
910        skip_serializing_if = "cull_face_is_default",
911        default = "default_cull_face"
912    )]
913    pub cull_face: [Checked<CullFace>; 1],
914    #[serde(
915        rename = "depthFunc",
916        skip_serializing_if = "depth_func_is_default",
917        default = "default_depth_func"
918    )]
919    pub depth_func: [Checked<DepthFunc>; 1],
920    #[serde(
921        rename = "depthMask",
922        skip_serializing_if = "depth_mask_is_default",
923        default = "default_depth_mask"
924    )]
925    pub depth_mask: [bool; 1],
926    #[serde(
927        rename = "depthRange",
928        skip_serializing_if = "depth_range_is_default",
929        default = "default_depth_range"
930    )]
931    pub depth_range: [f32; 2],
932    #[serde(
933        rename = "frontFace",
934        skip_serializing_if = "front_face_is_default",
935        default = "default_front_face"
936    )]
937    pub front_face: [Checked<FrontFace>; 1],
938    #[serde(
939        rename = "lineWidth",
940        skip_serializing_if = "line_width_is_default",
941        default = "default_line_width"
942    )]
943    pub line_width: [f32; 1],
944    #[serde(
945        rename = "polygonOffset",
946        skip_serializing_if = "polygon_offset_is_default",
947        default = "default_polygon_offset"
948    )]
949    pub polygon_offset: [f32; 2],
950    #[serde(
951        skip_serializing_if = "scissor_is_default",
952        default = "default_scissor"
953    )]
954    pub scissor: [f32; 4],
955}
956
957fn blend_color_is_zero(value: &[f32; 4]) -> bool {
958    value[0] == 0.0 && value[1] == 0.0 && value[2] == 0.0 && value[3] == 0.0
959}
960
961fn default_blend_color() -> [f32; 4] {
962    [0.0, 0.0, 0.0, 0.0]
963}
964
965fn blend_equation_seperate_is_default(value: &[Checked<BlendEquationSeparate>; 2]) -> bool {
966    value[0] == Checked::Valid(BlendEquationSeparate::FuncAdd)
967        && value[1] == Checked::Valid(BlendEquationSeparate::FuncAdd)
968}
969
970fn default_blend_equation_seperate() -> [Checked<BlendEquationSeparate>; 2] {
971    [
972        Checked::Valid(BlendEquationSeparate::FuncAdd),
973        Checked::Valid(BlendEquationSeparate::FuncAdd),
974    ]
975}
976fn blend_func_seperate_is_default(value: &[Checked<BlendFuncSeparate>; 4]) -> bool {
977    value[0] == Checked::Valid(BlendFuncSeparate::One)
978        && value[1] == Checked::Valid(BlendFuncSeparate::Zero)
979        && value[2] == Checked::Valid(BlendFuncSeparate::One)
980        && value[3] == Checked::Valid(BlendFuncSeparate::Zero)
981}
982
983fn default_blend_func_seperate() -> [Checked<BlendFuncSeparate>; 4] {
984    [
985        Checked::Valid(BlendFuncSeparate::One),
986        Checked::Valid(BlendFuncSeparate::Zero),
987        Checked::Valid(BlendFuncSeparate::One),
988        Checked::Valid(BlendFuncSeparate::Zero),
989    ]
990}
991
992fn color_mask_is_default(value: &[bool; 4]) -> bool {
993    value[0] && value[1] && value[2] && value[3]
994}
995
996fn default_color_mask() -> [bool; 4] {
997    [true, true, true, true]
998}
999
1000fn cull_face_is_default(value: &[Checked<CullFace>; 1]) -> bool {
1001    value[0] == Checked::Valid(CullFace::Back)
1002}
1003
1004fn default_cull_face() -> [Checked<CullFace>; 1] {
1005    [Checked::Valid(CullFace::Back)]
1006}
1007
1008fn depth_func_is_default(value: &[Checked<DepthFunc>; 1]) -> bool {
1009    value[0] == Checked::Valid(DepthFunc::Less)
1010}
1011
1012fn default_depth_func() -> [Checked<DepthFunc>; 1] {
1013    [Checked::Valid(DepthFunc::Less)]
1014}
1015
1016fn depth_mask_is_default(value: &[bool; 1]) -> bool {
1017    value[0]
1018}
1019
1020fn default_depth_mask() -> [bool; 1] {
1021    [true]
1022}
1023
1024fn depth_range_is_default(value: &[f32; 2]) -> bool {
1025    value[0] == 0.0 && value[1] == 1.0
1026}
1027
1028fn default_depth_range() -> [f32; 2] {
1029    [0.0, 1.0]
1030}
1031
1032fn front_face_is_default(value: &[Checked<FrontFace>; 1]) -> bool {
1033    value[0] == Checked::Valid(FrontFace::CCW)
1034}
1035
1036fn default_front_face() -> [Checked<FrontFace>; 1] {
1037    [Checked::Valid(FrontFace::CCW)]
1038}
1039
1040fn line_width_is_default(value: &[f32; 1]) -> bool {
1041    value[0] == 1.0
1042}
1043
1044fn default_line_width() -> [f32; 1] {
1045    [1.0]
1046}
1047
1048fn polygon_offset_is_default(value: &[f32; 2]) -> bool {
1049    value[0] == 0.0 && value[1] == 0.0
1050}
1051
1052fn default_polygon_offset() -> [f32; 2] {
1053    [0.0, 0.0]
1054}
1055
1056fn scissor_is_default(value: &[f32; 4]) -> bool {
1057    value[0] == 0.0 && value[1] == 0.0 && value[2] == 0.0 && value[3] == 0.0
1058}
1059
1060fn default_scissor() -> [f32; 4] {
1061    [0.0, 0.0, 0.0, 0.0]
1062}
1063
1064#[derive(Clone, Debug, serde_derive::Deserialize, serde_derive::Serialize, Validate)]
1065pub struct TechniqueState {
1066    #[serde(default)]
1067    #[serde(skip_serializing_if = "Vec::is_empty")]
1068    pub enable: Vec<Checked<WebGLState>>,
1069    #[serde(skip_serializing_if = "Option::is_none")]
1070    pub functions: Option<TechniqueStateFunction>,
1071}
1072
1073#[derive(Clone, Debug, serde_derive::Deserialize, serde_derive::Serialize, Validate)]
1074#[gltf(validate_hook = "technique_validate_technique")]
1075pub struct Technique {
1076    #[serde(skip_serializing_if = "IndexMap::is_empty")]
1077    pub parameters: IndexMap<String, TechniqueParameter>,
1078    #[serde(skip_serializing_if = "IndexMap::is_empty")]
1079    pub attributes: IndexMap<String, String>,
1080    pub program: StringIndex<Program>,
1081    #[serde(skip_serializing_if = "IndexMap::is_empty")]
1082    pub uniforms: IndexMap<String, String>,
1083    #[serde(skip_serializing_if = "Option::is_none")]
1084    pub states: Option<TechniqueState>,
1085    #[serde(skip_serializing_if = "Option::is_none")]
1086    pub name: Option<String>,
1087}
1088
1089impl Technique {
1090    pub(crate) fn default_technique(program: String) -> Self {
1091        let mut attributes = IndexMap::new();
1092        attributes.insert("a_position".to_string(), "position".to_string());
1093
1094        let mut parameters = IndexMap::new();
1095        parameters.insert(
1096            "modelViewMatrix".to_string(),
1097            TechniqueParameter {
1098                semantic: Some("MODELVIEW".to_string()),
1099                type_: Checked::Valid(ParameterType::FloatMat4),
1100                ..TechniqueParameter::default()
1101            },
1102        );
1103        parameters.insert(
1104            "projectionMatrix".to_string(),
1105            TechniqueParameter {
1106                semantic: Some("PROJECTION".to_string()),
1107                type_: Checked::Valid(ParameterType::FloatMat4),
1108                ..TechniqueParameter::default()
1109            },
1110        );
1111        parameters.insert(
1112            "emission".to_string(),
1113            TechniqueParameter {
1114                value: Some(Checked::Valid(ParameterValue::NumberArray(vec![
1115                    0.5, 0.5, 0.5, 1.0,
1116                ]))),
1117                type_: Checked::Valid(ParameterType::FloatVec4),
1118                ..TechniqueParameter::default()
1119            },
1120        );
1121        parameters.insert(
1122            "position".to_string(),
1123            TechniqueParameter {
1124                semantic: Some("POSITION".to_string()),
1125                type_: Checked::Valid(ParameterType::FloatVec3),
1126                ..TechniqueParameter::default()
1127            },
1128        );
1129
1130        let mut uniforms = IndexMap::new();
1131        uniforms.insert(
1132            "u_modelViewMatrix".to_string(),
1133            "modelViewMatrix".to_string(),
1134        );
1135        uniforms.insert(
1136            "u_projectionMatrix".to_string(),
1137            "projectionMatrix".to_string(),
1138        );
1139        uniforms.insert("u_emission".to_string(), "emission".to_string());
1140
1141        Technique {
1142            attributes,
1143            parameters,
1144            program: StringIndex::new(program),
1145            uniforms,
1146            states: Some(TechniqueState {
1147                enable: vec![
1148                    Checked::Valid(WebGLState::CullFace),
1149                    Checked::Valid(WebGLState::DepthTest),
1150                ],
1151                functions: None,
1152            }),
1153            name: None,
1154        }
1155    }
1156}
1157fn technique_validate_technique<P, R>(technique: &Technique, _root: &Root, path: P, report: &mut R)
1158where
1159    P: Fn() -> Path,
1160    R: FnMut(&dyn Fn() -> Path, Error),
1161{
1162    for (_, parameter_key) in &technique.attributes {
1163        if !technique.parameters.contains_key(parameter_key) {
1164            report(&path, Error::IndexNotFound);
1165        }
1166    }
1167    for (_, parameter_key) in &technique.uniforms {
1168        if !technique.parameters.contains_key(parameter_key) {
1169            report(&path, Error::IndexNotFound);
1170        }
1171    }
1172}
1173
1174#[derive(Clone, Debug, serde_derive::Deserialize, serde_derive::Serialize, Validate, Default)]
1175pub struct Material {
1176    #[serde(skip_serializing_if = "Option::is_none")]
1177    pub technique: Option<StringIndex<Technique>>,
1178    #[serde(skip_serializing_if = "IndexMap::is_empty")]
1179    pub values: IndexMap<String, Checked<ParameterValue>>,
1180    #[serde(skip_serializing_if = "Option::is_none")]
1181    pub name: Option<String>,
1182    #[serde(default, skip_serializing_if = "Option::is_none")]
1183    pub extensions: Option<extensions::material::Material>,
1184}
1185
1186#[test]
1187fn test_technique_deserialize() {
1188    let data = r#"{
1189            "name": "user-defined technique name",
1190            "parameters": {
1191                "ambient": {
1192                    "type": 35666,
1193		            "extensions" : {
1194		               "extension_name" : {
1195		                  "extension specific" : "value"
1196		               }
1197		            },
1198                    "extras" : {
1199                        "Application specific" : "The extra object can contain any properties."
1200                    }
1201                },
1202                "diffuse": {
1203                    "type": 35678
1204                },
1205                "lightColor": {
1206                    "type": 35665,
1207                    "value": [
1208                        1,
1209                        1,
1210                        1
1211                    ]
1212                },
1213                "lightTransform": {
1214                    "node": "directional_light_node_id",
1215                    "type": 35676
1216                },
1217                "modelViewMatrix": {
1218                    "semantic": "MODELVIEW",
1219                    "type": 35676
1220                },
1221                "projectionMatrix": {
1222                    "semantic": "PROJECTION",
1223                    "type": 35676
1224                },
1225                "normalMatrix": {
1226                    "semantic": "MODELVIEWINVERSETRANSPOSE",
1227                    "type": 35675
1228                },
1229
1230                "position": {
1231                    "semantic": "POSITION",
1232                    "type": 35665
1233                },
1234                "normal": {
1235                    "semantic": "NORMAL",
1236                    "type": 35665
1237                },
1238                "texcoord": {
1239                    "semantic": "TEXCOORD_0",
1240                    "type": 35664
1241                },
1242
1243                "joint": {
1244                    "semantic": "JOINT",
1245                    "type": 35666
1246                },
1247                "jointMatrix": {
1248                    "semantic": "JOINTMATRIX",
1249                    "type": 35676
1250                },
1251                "weight": {
1252                    "semantic": "WEIGHT",
1253                    "type": 35666
1254                }
1255            },
1256            "attributes": {
1257                "a_position": "position",
1258                "a_normal": "normal",
1259                "a_texcoord0": "texcoord0",
1260                "a_joint": "joint",
1261                "a_weight": "weight"
1262            },
1263            "program": "program_id",
1264            "uniforms": {
1265                "u_ambient": "ambient",
1266                "u_diffuse": "diffuse",
1267                "u_lightColor": "lightColor",
1268                "u_lightTransformMatrix": "lightTransform",
1269                "u_modelViewMatrix": "modelViewMatrix",
1270                "u_projectionMatrix": "projectionMatrix",
1271                "u_normalMatrix": "normalMatrix",
1272                "u_jointMatrix": "jointMatrix"
1273            },
1274            "states" : {
1275                "enable" : [3042, 2884, 2929, 32823, 32926, 3089],
1276                "functions" : {
1277                    "blendColor": [0.0, 0.0, 0.0, 0.0],
1278                    "blendEquationSeparate" : [32774, 32774],
1279                    "blendFuncSeparate" : [1, 0, 1, 0],
1280                    "colorMask" : [true, true, true, true],
1281                    "cullFace" : [1029],
1282                    "depthFunc" : [513],
1283                    "depthMask" : [true],
1284                    "depthRange" : [0.0, 1.0],
1285                    "frontFace" : [2305],
1286                    "lineWidth" : [1.0],
1287                    "polygonOffset" : [0.0, 0.0],
1288                    "scissor" : [0, 0, 0, 0],
1289                    "extensions" : {
1290                       "extension_name" : {
1291                          "extension specific" : "value"
1292                       }
1293                    },
1294                    "extras" : {
1295                        "Application specific" : "The extra object can contain any properties."
1296                    }
1297                },
1298                "extensions" : {
1299                   "extension_name" : {
1300                      "extension specific" : "value"
1301                   }
1302                },
1303                "extras" : {
1304                    "Application specific" : "The extra object can contain any properties."
1305                }
1306            },
1307            "extensions" : {
1308               "extension_name" : {
1309                  "extension specific" : "value"
1310               }
1311            },
1312            "extras" : {
1313                "Application specific" : "The extra object can contain any properties."
1314            }
1315        }"#;
1316    let technique: Result<Technique, _> = serde_json::from_str(data);
1317    let technique_unwrap = technique.unwrap();
1318    println!("{}", serde_json::to_string(&technique_unwrap).unwrap());
1319    assert_eq!(
1320        Some("user-defined technique name".to_string()),
1321        technique_unwrap.name
1322    );
1323}
1324#[test]
1325fn test_material_deserialize() {
1326    let data = r#"{
1327            "technique": "technique_id",
1328            "values": {
1329                "ambient": [
1330                    0,
1331                    0,
1332                    0,
1333                    1
1334                ],
1335                "diffuse": "texture_image_0",
1336                "shininess": 38.4
1337            },
1338            "name": "user-defined material name",
1339            "extensions" : {
1340               "extension_name" : {
1341                  "extension specific" : "value"
1342               }
1343            },
1344            "extras" : {
1345                "Application specific" : "The extra object can contain any properties."
1346            }     
1347        }"#;
1348    let material: Result<Material, _> = serde_json::from_str(data);
1349    let material_unwrap = material.unwrap();
1350    println!("{}", serde_json::to_string(&material_unwrap).unwrap());
1351    assert_eq!(
1352        Some("user-defined material name".to_string()),
1353        material_unwrap.name
1354    );
1355}