gltf_v1_json/extensions/
material.rs1use std::fmt;
2
3use gltf_v1_derive::Validate;
4use serde::{de, ser};
5use serde_derive::{Deserialize, Serialize};
6
7use crate::validation::Checked;
8
9#[derive(Clone, Debug, PartialEq, Eq, Copy, Default)]
10pub enum Technique {
11 Blinn,
12 Phong,
13 Lambert,
14 #[default]
15 Constant,
16}
17
18impl Technique {
19 pub const VALID_TECHNIQUES: &[&str] = &["LAMBERT", "PHONG", "BLINN", "CONSTANT"];
20}
21
22impl TryFrom<&str> for Technique {
23 type Error = ();
24
25 fn try_from(value: &str) -> Result<Self, Self::Error> {
26 match value {
27 "LAMBERT" => Ok(Technique::Lambert),
28 "PHONG" => Ok(Technique::Phong),
29 "BLINN" => Ok(Technique::Blinn),
30 "CONSTANT" => Ok(Technique::Constant),
31 _ => Err(()),
32 }
33 }
34}
35
36impl From<Technique> for &str {
37 fn from(value: Technique) -> Self {
38 match value {
39 Technique::Lambert => "LAMBERT",
40 Technique::Blinn => "BLINN",
41 Technique::Phong => "PHONG",
42 Technique::Constant => "CONSTANT",
43 }
44 }
45}
46
47impl ser::Serialize for Technique {
48 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
49 where
50 S: ser::Serializer,
51 {
52 serializer.serialize_str(Into::into(*self))
53 }
54}
55impl<'de> de::Deserialize<'de> for Checked<Technique> {
56 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
57 where
58 D: de::Deserializer<'de>,
59 {
60 struct Visitor;
61 impl de::Visitor<'_> for Visitor {
62 type Value = Checked<Technique>;
63
64 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
65 write!(f, "any of: {:?}", Technique::VALID_TECHNIQUES)
66 }
67
68 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
69 where
70 E: de::Error,
71 {
72 Ok(TryInto::try_into(value)
73 .map(Checked::Valid)
74 .unwrap_or(Checked::Invalid))
75 }
76 }
77 deserializer.deserialize_str(Visitor)
78 }
79}
80
81fn f32vec4_is_default(value: &[f32; 4]) -> bool {
82 value[0] == 0.0 && value[1] == 0.0 && value[2] == 0.0 && value[3] == 1.0
83}
84
85fn default_f32vec4() -> [f32; 4] {
86 [0.0, 0.0, 0.0, 1.0]
87}
88
89fn f320_default() -> f32 {
90 0.0
91}
92fn f321_default() -> f32 {
93 1.0
94}
95
96#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
97pub struct MaterialValues {
98 #[serde(
99 skip_serializing_if = "f32vec4_is_default",
100 default = "default_f32vec4"
101 )]
102 pub ambient: [f32; 4],
103 #[serde(
104 skip_serializing_if = "f32vec4_is_default",
105 default = "default_f32vec4"
106 )]
107 pub diffuse: [f32; 4],
108 #[serde(rename = "doubleSided")]
109 pub double_sided: bool,
110 #[serde(
111 skip_serializing_if = "f32vec4_is_default",
112 default = "default_f32vec4"
113 )]
114 pub emission: [f32; 4],
115 #[serde(
116 skip_serializing_if = "f32vec4_is_default",
117 default = "default_f32vec4"
118 )]
119 pub specular: [f32; 4],
120 #[serde(default = "f320_default")]
121 pub shininess: f32,
122 #[serde(default = "f321_default")]
123 pub transparency: f32,
124 pub transparent: bool,
125}
126
127#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
128pub struct MaterialCommon {
129 pub technique: Checked<Technique>,
130 pub values: MaterialValues,
131}
132
133#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
134pub struct Material {
135 #[cfg(feature = "KHR_materials_common")]
136 #[serde(rename = "KHR_materials_common")]
137 pub khr_material_common: Option<MaterialCommon>,
138 #[cfg(feature = "extensions")]
139 #[serde(default, flatten)]
140 pub others: Map<String, Value>,
141}