openconfiguration/ig/
material.rs

1use std::collections::HashMap;
2
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5
6use crate::{color::Color, impl_visitable_noop, support::Visitable};
7
8#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Visitable, Default)]
9#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
10#[cfg_attr(feature = "schema", schemars(deny_unknown_fields))]
11#[serde(rename_all = "camelCase", rename = "igMaterial")]
12pub struct Material {
13    pub shininess: Option<f64>,
14
15    /// Diffuse property. Both color and map are supported.
16    /// Color and map replace each other.
17    pub diffuse: Option<AlphaColorMap>,
18
19    /// Specular color.
20    pub specular: Option<ColorNoMap>,
21
22    /// Emission color
23    pub emission: Option<ColorNoMap>,
24
25    /// Normal map.
26    pub normal: Option<BasicMap>,
27
28    /// Metallness map.
29    pub metalness: Option<BasicMap>,
30
31    /// Roughness map.
32    pub roughness: Option<BasicMap>,
33
34    /// Sheen map.
35    pub sheen: Option<BasicMap>,
36
37    /// Alpha value or map. Value and map replace each other.
38    /// Values in the range 0.0 to 1.0. 0.0 is transparent, 1.0 is opaque.
39    /// Map is grayscale. Black is transparent, white is opaque.
40    pub alpha: Option<ValueMap>,
41
42    /// Diffuse delta map. The delta map modifies the diffuse
43    /// color/map and typically has it's own mapping.
44    ///
45    /// Format: 24 Bit (RGB)
46    ///
47    /// The handling (for each channel/color) is:
48    /// - linear mapping of [0, 255] to [0, 2]
49    /// - multiplication with the diffuse/color value
50    ///
51    /// 0 sets the original value to 0.
52    /// 127/128 keeps the original value.
53    /// 255 doubles the original value.
54    pub diffuse_delta: Option<TextureMap>,
55
56    /// Roughness delta map. The delta map modifies the roughness
57    /// value/map and typically has it's own mapping.
58    ///
59    /// Format: 8 Bit (Grayscale)
60    ///
61    /// The handling is:
62    /// - linear mapping of [0, 255] to [0, 2]
63    /// - multiplication with the roughness value
64    ///
65    /// 0 sets the original value to 0.
66    /// 127/128 keeps the original value.
67    /// 255 doubles the original value.
68    pub roughness_delta: Option<TextureMap>,
69
70    /// Displacement map for material structures. Used only for high def renderings
71    /// with suitable high def meshes
72    pub displacement: Option<TextureMap>,
73
74    /// Default mapping, may be overridden by specific texture maps.
75    pub mapping: Option<TextureMapping>,
76
77    /// Taxonomy information according to docs/ig_Taxonomy
78    #[serde(
79        deserialize_with = "crate::utils::deserialize_optional_map_without_null_values",
80        default
81    )]
82    pub taxonomy: Option<HashMap<String, Value>>,
83
84    /// Optional geometry-related parameters, to be resolved at client-side.
85    ///
86    /// "DisplacementBase"
87    /// Like in Blender
88    ///
89    /// "DisplacementScale"
90    /// Like in Blender
91    ///
92    /// "DoNotRescale":
93    /// Marks the material as not re-scaleable. Re-scaling can be applied
94    /// for psychological reasons, for instance.
95    /// Target type: Boolean
96    ///
97    /// "Overlay":
98    /// For alpha-map materials, tells the renderer that the associated geometry
99    /// should be an overlay to other geometries at the same location.
100    /// Target type: Boolean
101    ///
102    /// IGXC Compatibility: Metamaterial parameters but without redundancy.
103    #[serde(
104        deserialize_with = "crate::utils::deserialize_optional_map_without_null_values",
105        default
106    )]
107    pub parameters: Option<HashMap<String, Value>>,
108}
109
110#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Visitable)]
111#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
112#[cfg_attr(feature = "schema", schemars(deny_unknown_fields))]
113#[serde(rename_all = "camelCase")]
114/// Texture map with additional scalar value. The relationship between both
115/// will be defined in the application context.
116pub struct ValueMap {
117    #[serde(flatten)]
118    pub basic: BasicMap,
119
120    /// A scalar value. If the map is supported or not, and it's relation-
121    /// ship to a map entry, is defined in the outer context.
122    pub value: Option<f64>,
123}
124
125#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Visitable)]
126#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
127#[cfg_attr(feature = "schema", schemars(deny_unknown_fields))]
128#[serde(rename_all = "camelCase")]
129pub struct AlphaColorMap {
130    #[serde(flatten)]
131    pub color_map: ColorMap,
132
133    pub alpha_mode: Option<AlphaMode>,
134}
135
136#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
137#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
138pub enum AlphaMode {
139    /// The alpha channel is considered, if the transparency value is at least 0.1.
140    /// If the Material has an alphamap, it is also considered.
141    Standard,
142    /// The alpha channel is always used "as is".
143    /// Alphamap and Transparency setting are ignored.
144    RGBA,
145}
146
147impl_visitable_noop!(AlphaMode);
148
149#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Visitable)]
150#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
151#[cfg_attr(feature = "schema", schemars(deny_unknown_fields))]
152#[serde(rename_all = "camelCase")]
153/// Color without texture map
154pub struct ColorNoMap {
155    /// A color value.
156    pub color: Option<Color>,
157}
158
159#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Visitable)]
160#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
161#[cfg_attr(feature = "schema", schemars(deny_unknown_fields))]
162#[serde(rename_all = "camelCase")]
163/// Texture map with additional color value. The relationship between both
164/// will be defined in the application context.
165pub struct ColorMap {
166    #[serde(flatten)]
167    pub basic: BasicMap,
168
169    /// A color value.
170    pub color: Option<Color>,
171}
172
173#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Visitable)]
174#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
175#[cfg_attr(feature = "schema", schemars(deny_unknown_fields))]
176#[serde(rename_all = "camelCase")]
177pub struct BasicMap {
178    pub map: Option<TextureMap>,
179}
180
181#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
182#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
183#[cfg_attr(feature = "schema", schemars(deny_unknown_fields))]
184#[serde(rename_all = "camelCase")]
185pub struct TextureMap {
186    /// The mandatory format of the map.
187    pub map_format: TextureMapFormat,
188
189    /// Absolute or relative path to the texture image.
190    pub map: String,
191
192    /// An optional UV mapping.	  
193    pub mapping: Option<TextureMapping>,
194}
195
196impl Visitable for TextureMap {
197    fn visit_with(&mut self, visitor: &mut dyn crate::support::Visitor) {
198        visitor.visit_texture_map(self);
199        visitor.visit_path(&mut self.map);
200    }
201}
202
203#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
204#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
205pub enum TextureMapFormat {
206    JPEG,
207    PNG,
208    WEBP,
209}
210
211impl_visitable_noop!(TextureMapFormat);
212
213#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
214#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
215#[cfg_attr(feature = "schema", schemars(deny_unknown_fields))]
216#[serde(rename_all = "camelCase")]
217/// A Transformation of the UV Set for a Material  
218/// Ordering R///S///T///V  
219/// Also see ThreeJS issue #15831
220///
221/// This order minimizes shearing and improves content creation.
222///
223/// Combination with a GeometryMapping looks like this:
224/// GS///GT///GR///MR///MS///MT///V
225///
226/// GR .. Matrix of GeometryMapping.Rotation
227/// GS .. Matrix of GeometryMapping.Scale///
228/// GT .. Matrix of GeometryMapping.Translation///
229///
230/// MR .. Matrix of TextureMapping.Rotation
231/// MS .. Matrix of TextureMapping.Scale///
232/// MT .. Matrix of TextureMapping.Translation///
233///
234/// V .. (UV)-Vector to be transformed
235///
236/// Rotation is clockwise in degrees
237pub struct TextureMapping {
238    pub translation_s: f64,
239
240    pub translation_t: f64,
241
242    pub rotation: f64,
243
244    #[serde(default = "default_scale")]
245    /// default value = 1
246    pub scale_s: f64,
247
248    #[serde(default = "default_scale")]
249    /// default value = 1
250    pub scale_t: f64,
251}
252
253impl_visitable_noop!(TextureMapping);
254
255fn default_scale() -> f64 {
256    1.0
257}