use alloc::borrow::Cow;
use ownable::IntoOwned;
use serde::Deserialize;
use crate::texture::Texture;
use crate::{Extensions, Extras, Idx};
fn default_base_color_factor() -> [f32; 4] {
[1.0; 4]
}
fn one_f32() -> f32 {
1.0
}
fn half_f32() -> f32 {
0.5
}
#[derive(Debug, Clone, Deserialize, IntoOwned)]
pub struct TextureInfo<'a> {
pub index: Idx<Texture<'static>>,
#[serde(rename = "texCoord")]
#[serde(default)]
pub texcoord: u64,
#[serde(borrow)]
pub extensions: Option<Extensions<'a>>,
#[serde(borrow)]
pub extras: Option<Extras<'a>>,
}
#[derive(Debug, Clone, Deserialize, IntoOwned)]
pub struct NormalTextureInfo<'a> {
#[serde(flatten, borrow)]
pub inner: TextureInfo<'a>,
#[serde(default = "one_f32")]
pub scale: f32,
}
#[derive(Debug, Clone, Deserialize, IntoOwned)]
pub struct OcclusionTextureInfo<'a> {
#[serde(flatten, borrow)]
pub inner: TextureInfo<'a>,
#[serde(default = "one_f32")]
pub strength: f32,
}
#[derive(Debug, Clone, Deserialize, IntoOwned)]
pub struct PbrMetallicRoughness<'a> {
#[serde(rename = "baseColorTexture")]
#[serde(borrow)]
pub base_color_texture: Option<TextureInfo<'a>>,
#[serde(rename = "metallicRoughnessTexture")]
#[serde(borrow)]
pub metallic_roughness_texture: Option<TextureInfo<'a>>,
#[serde(rename = "baseColorFactor")]
#[serde(default = "default_base_color_factor")]
pub base_color_factor: [f32; 4],
#[serde(rename = "metallicFactor")]
#[serde(default = "one_f32")]
pub metallic_factor: f32,
#[serde(rename = "roughnessFactor")]
#[serde(default = "one_f32")]
pub roughness_factor: f32,
#[serde(borrow)]
pub extensions: Option<Extensions<'a>>,
#[serde(borrow)]
pub extras: Option<Extras<'a>>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AlphaModeEnum {
Opaque,
Mask,
Blend,
}
#[derive(Clone, PartialEq, Eq, Deserialize, IntoOwned)]
#[serde(transparent)]
pub struct AlphaMode<'a>(#[serde(borrow)] pub Cow<'a, str>);
impl Default for AlphaMode<'_> {
fn default() -> Self {
Self::OPAQUE
}
}
impl core::fmt::Debug for AlphaMode<'_> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
if let Some(e) = self.to_enum() {
e.fmt(f)
} else {
self.0.fmt(f)
}
}
}
impl AlphaMode<'_> {
pub const OPAQUE: Self = Self(Cow::Borrowed("OPAQUE"));
pub const MASK: Self = Self(Cow::Borrowed("MASK"));
pub const BLEND: Self = Self(Cow::Borrowed("BLEND"));
pub fn to_enum(&self) -> Option<AlphaModeEnum> {
if *self == Self::OPAQUE {
return Some(AlphaModeEnum::Opaque);
} else if *self == Self::MASK {
return Some(AlphaModeEnum::Mask);
} else if *self == Self::BLEND {
return Some(AlphaModeEnum::Blend);
}
None
}
}
#[derive(Debug, Clone, Deserialize, IntoOwned)]
pub struct Material<'a> {
#[serde(borrow)]
pub name: Option<Cow<'a, str>>,
#[serde(rename = "pbrMetallicRoughness")]
#[serde(borrow)]
pub pbr_metallic_roughness: Option<PbrMetallicRoughness<'a>>,
#[serde(rename = "normalTexture")]
#[serde(borrow)]
pub normal_texture: Option<NormalTextureInfo<'a>>,
#[serde(rename = "occlusionTexture")]
#[serde(borrow)]
pub occlusion_texture: Option<OcclusionTextureInfo<'a>>,
#[serde(rename = "emissiveTexture")]
#[serde(borrow)]
pub emissive_texture: Option<TextureInfo<'a>>,
#[serde(rename = "emissiveFactor")]
#[serde(default)]
pub emissive_factor: [f32; 3],
#[serde(rename = "alphaMode")]
#[serde(default)]
pub alpha_mode: AlphaMode<'a>,
#[serde(rename = "alphaCutoff")]
#[serde(default = "half_f32")]
pub alpha_cutoff: f32,
#[serde(rename = "doubleSided")]
#[serde(default)]
pub double_sided: bool,
#[serde(borrow)]
pub extensions: Option<Extensions<'a>>,
#[serde(borrow)]
pub extras: Option<Extras<'a>>,
}