Files
another-boids-in-rust/vendor/gltf-json/src/material.rs

312 lines
11 KiB
Rust

use crate::validation::{Checked, Validate};
use crate::{extensions, texture, Extras, Index};
use gltf_derive::Validate;
use serde::{de, ser};
use serde_derive::{Deserialize, Serialize};
use std::fmt;
/// All valid alpha modes.
pub const VALID_ALPHA_MODES: &[&str] = &["OPAQUE", "MASK", "BLEND"];
/// The alpha rendering mode of a material.
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
pub enum AlphaMode {
/// The alpha value is ignored and the rendered output is fully opaque.
Opaque = 1,
/// The rendered output is either fully opaque or fully transparent depending on
/// the alpha value and the specified alpha cutoff value.
Mask,
/// The alpha value is used, to determine the transparency of the rendered output.
/// The alpha cutoff value is ignored.
Blend,
}
impl ser::Serialize for AlphaMode {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: ser::Serializer,
{
match *self {
AlphaMode::Opaque => serializer.serialize_str("OPAQUE"),
AlphaMode::Mask => serializer.serialize_str("MASK"),
AlphaMode::Blend => serializer.serialize_str("BLEND"),
}
}
}
/// The material appearance of a primitive.
#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
#[serde(default)]
pub struct Material {
/// The alpha cutoff value of the material.
#[serde(rename = "alphaCutoff")]
//#[cfg_attr(feature = "alphaCutoff", serde(skip_serializing_if = "Option::is_none"))]
#[serde(skip_serializing_if = "Option::is_none")]
pub alpha_cutoff: Option<AlphaCutoff>,
/// The alpha rendering mode of the material.
///
/// The material's alpha rendering mode enumeration specifying the
/// interpretation of the alpha value of the main factor and texture.
///
/// * In `Opaque` mode (default) the alpha value is ignored and the rendered
/// output is fully opaque.
///
/// * In `Mask` mode, the rendered output is either fully opaque or fully
/// transparent depending on the alpha value and the specified alpha cutoff
/// value.
///
/// * In `Blend` mode, the alpha value is used to composite the source and
/// destination areas and the rendered output is combined with the
/// background using the normal painting operation (i.e. the Porter and
/// Duff over operator).
#[serde(rename = "alphaMode")]
pub alpha_mode: Checked<AlphaMode>,
/// Specifies whether the material is double-sided.
///
/// * When this value is false, back-face culling is enabled.
///
/// * When this value is true, back-face culling is disabled and double sided
/// lighting is enabled.
///
/// The back-face must have its normals reversed before the lighting
/// equation is evaluated.
#[serde(rename = "doubleSided")]
pub double_sided: bool,
/// Optional user-defined name for this object.
#[cfg(feature = "names")]
#[cfg_attr(feature = "names", serde(skip_serializing_if = "Option::is_none"))]
pub name: Option<String>,
/// A set of parameter values that are used to define the metallic-roughness
/// material model from Physically-Based Rendering (PBR) methodology. When not
/// specified, all the default values of `pbrMetallicRoughness` apply.
#[serde(default, rename = "pbrMetallicRoughness")]
pub pbr_metallic_roughness: PbrMetallicRoughness,
/// A tangent space normal map. The texture contains RGB components in linear
/// space. Each texel represents the XYZ components of a normal vector in
/// tangent space. Red [0 to 255] maps to X [-1 to 1]. Green [0 to 255] maps to
/// Y [-1 to 1]. Blue [128 to 255] maps to Z [1/255 to 1]. The normal vectors
/// use OpenGL conventions where +X is right and +Y is up. +Z points toward the
/// viewer.
#[serde(rename = "normalTexture")]
#[serde(skip_serializing_if = "Option::is_none")]
pub normal_texture: Option<NormalTexture>,
/// The occlusion map texture. The occlusion values are sampled from the R
/// channel. Higher values indicate areas that should receive full indirect
/// lighting and lower values indicate no indirect lighting. These values are
/// linear. If other channels are present (GBA), they are ignored for occlusion
/// calculations.
#[serde(rename = "occlusionTexture")]
#[serde(skip_serializing_if = "Option::is_none")]
pub occlusion_texture: Option<OcclusionTexture>,
/// The emissive map controls the color and intensity of the light being emitted
/// by the material. This texture contains RGB components in sRGB color space.
/// If a fourth component (A) is present, it is ignored.
#[serde(rename = "emissiveTexture")]
#[serde(skip_serializing_if = "Option::is_none")]
pub emissive_texture: Option<texture::Info>,
/// The emissive color of the material.
#[serde(rename = "emissiveFactor")]
pub emissive_factor: EmissiveFactor,
/// Extension specific data.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub extensions: Option<extensions::material::Material>,
/// Optional application specific data.
#[cfg_attr(feature = "extras", serde(skip_serializing_if = "Option::is_none"))]
#[cfg_attr(not(feature = "extras"), serde(skip_serializing))]
pub extras: Extras,
}
/// A set of parameter values that are used to define the metallic-roughness
/// material model from Physically-Based Rendering (PBR) methodology.
#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
#[serde(default)]
pub struct PbrMetallicRoughness {
/// The material's base color factor.
#[serde(rename = "baseColorFactor")]
pub base_color_factor: PbrBaseColorFactor,
/// The base color texture.
#[serde(rename = "baseColorTexture")]
#[serde(skip_serializing_if = "Option::is_none")]
pub base_color_texture: Option<texture::Info>,
/// The metalness of the material.
#[serde(rename = "metallicFactor")]
pub metallic_factor: StrengthFactor,
/// The roughness of the material.
///
/// * A value of 1.0 means the material is completely rough.
/// * A value of 0.0 means the material is completely smooth.
#[serde(rename = "roughnessFactor")]
pub roughness_factor: StrengthFactor,
/// The metallic-roughness texture.
///
/// This texture has two components:
///
/// The metalness values are sampled from the B channel.
/// The roughness values are sampled from the G channel.
/// These values are linear. If other channels are present (R or A),
/// they are ignored for metallic-roughness calculations.
#[serde(rename = "metallicRoughnessTexture")]
#[serde(skip_serializing_if = "Option::is_none")]
pub metallic_roughness_texture: Option<texture::Info>,
/// Extension specific data.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub extensions: Option<extensions::material::PbrMetallicRoughness>,
/// Optional application specific data.
#[cfg_attr(feature = "extras", serde(skip_serializing_if = "Option::is_none"))]
#[cfg_attr(not(feature = "extras"), serde(skip_serializing))]
pub extras: Extras,
}
/// Defines the normal texture of a material.
#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
pub struct NormalTexture {
/// The index of the texture.
pub index: Index<texture::Texture>,
/// The scalar multiplier applied to each normal vector of the texture.
///
/// This value is ignored if normalTexture is not specified.
#[serde(default = "material_normal_texture_scale_default")]
pub scale: f32,
/// The set index of the texture's `TEXCOORD` attribute.
#[serde(default, rename = "texCoord")]
pub tex_coord: u32,
/// Extension specific data.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub extensions: Option<extensions::material::NormalTexture>,
/// Optional application specific data.
#[serde(default)]
#[cfg_attr(feature = "extras", serde(skip_serializing_if = "Option::is_none"))]
#[cfg_attr(not(feature = "extras"), serde(skip_serializing))]
pub extras: Extras,
}
fn material_normal_texture_scale_default() -> f32 {
1.0
}
/// Defines the occlusion texture of a material.
#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
pub struct OcclusionTexture {
/// The index of the texture.
pub index: Index<texture::Texture>,
/// The scalar multiplier controlling the amount of occlusion applied.
#[serde(default)]
pub strength: StrengthFactor,
/// The set index of the texture's `TEXCOORD` attribute.
#[serde(default, rename = "texCoord")]
pub tex_coord: u32,
/// Extension specific data.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub extensions: Option<extensions::material::OcclusionTexture>,
/// Optional application specific data.
#[serde(default)]
#[cfg_attr(feature = "extras", serde(skip_serializing_if = "Option::is_none"))]
#[cfg_attr(not(feature = "extras"), serde(skip_serializing))]
pub extras: Extras,
}
/// The alpha cutoff value of a material.
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub struct AlphaCutoff(pub f32);
/// The emissive color of a material.
#[derive(Clone, Copy, Debug, Default, Deserialize, Serialize)]
pub struct EmissiveFactor(pub [f32; 3]);
/// The base color factor of a material.
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub struct PbrBaseColorFactor(pub [f32; 4]);
/// A number in the inclusive range [0.0, 1.0] with a default value of 1.0.
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub struct StrengthFactor(pub f32);
impl Default for AlphaCutoff {
fn default() -> Self {
AlphaCutoff(0.5)
}
}
impl Validate for AlphaCutoff {}
impl Default for AlphaMode {
fn default() -> Self {
AlphaMode::Opaque
}
}
impl<'de> de::Deserialize<'de> for Checked<AlphaMode> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: de::Deserializer<'de>,
{
struct Visitor;
impl<'de> de::Visitor<'de> for Visitor {
type Value = Checked<AlphaMode>;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "any of: {:?}", VALID_ALPHA_MODES)
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
use self::AlphaMode::*;
use crate::validation::Checked::*;
Ok(match value {
"OPAQUE" => Valid(Opaque),
"MASK" => Valid(Mask),
"BLEND" => Valid(Blend),
_ => Invalid,
})
}
}
deserializer.deserialize_str(Visitor)
}
}
impl Validate for EmissiveFactor {}
impl Default for PbrBaseColorFactor {
fn default() -> Self {
PbrBaseColorFactor([1.0, 1.0, 1.0, 1.0])
}
}
impl Validate for PbrBaseColorFactor {}
impl Default for StrengthFactor {
fn default() -> Self {
StrengthFactor(1.0)
}
}
impl Validate for StrengthFactor {}