use serde::{Deserialize, Serialize};
use crate::ecs::material::components::{AlphaMode, Material};
use super::asset_uuid::AssetUuid;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SceneMaterial {
pub base_color: [f32; 4],
pub emissive_factor: [f32; 3],
#[serde(default)]
pub alpha_mode: SceneAlphaMode,
#[serde(default = "default_alpha_cutoff")]
pub alpha_cutoff: f32,
#[serde(default)]
pub base_texture_uuid: Option<AssetUuid>,
#[serde(default)]
pub base_texture_name: Option<String>,
#[serde(default)]
pub base_texture_uv_set: u32,
#[serde(default)]
pub emissive_texture_uuid: Option<AssetUuid>,
#[serde(default)]
pub emissive_texture_name: Option<String>,
#[serde(default)]
pub emissive_texture_uv_set: u32,
#[serde(default)]
pub normal_texture_uuid: Option<AssetUuid>,
#[serde(default)]
pub normal_texture_name: Option<String>,
#[serde(default)]
pub normal_texture_uv_set: u32,
#[serde(default = "default_normal_scale")]
pub normal_scale: f32,
#[serde(default)]
pub normal_map_flip_y: bool,
#[serde(default)]
pub normal_map_two_component: bool,
#[serde(default)]
pub metallic_roughness_texture_uuid: Option<AssetUuid>,
#[serde(default)]
pub metallic_roughness_texture_name: Option<String>,
#[serde(default)]
pub metallic_roughness_texture_uv_set: u32,
#[serde(default)]
pub occlusion_texture_uuid: Option<AssetUuid>,
#[serde(default)]
pub occlusion_texture_name: Option<String>,
#[serde(default)]
pub occlusion_texture_uv_set: u32,
#[serde(default = "default_occlusion_strength")]
pub occlusion_strength: f32,
#[serde(default = "default_roughness")]
pub roughness: f32,
#[serde(default)]
pub metallic: f32,
#[serde(default)]
pub unlit: bool,
#[serde(default)]
pub double_sided: bool,
#[serde(default = "default_uv_scale")]
pub uv_scale: [f32; 2],
#[serde(default)]
pub transmission_factor: f32,
#[serde(default)]
pub transmission_texture_uuid: Option<AssetUuid>,
#[serde(default)]
pub transmission_texture_name: Option<String>,
#[serde(default)]
pub transmission_texture_uv_set: u32,
#[serde(default)]
pub thickness: f32,
#[serde(default)]
pub thickness_texture_uuid: Option<AssetUuid>,
#[serde(default)]
pub thickness_texture_name: Option<String>,
#[serde(default)]
pub thickness_texture_uv_set: u32,
#[serde(default = "default_attenuation_color")]
pub attenuation_color: [f32; 3],
#[serde(default = "default_attenuation_distance")]
pub attenuation_distance: f32,
#[serde(default = "default_ior")]
pub ior: f32,
#[serde(default = "default_specular_factor")]
pub specular_factor: f32,
#[serde(default = "default_specular_color_factor")]
pub specular_color_factor: [f32; 3],
#[serde(default)]
pub specular_texture_uuid: Option<AssetUuid>,
#[serde(default)]
pub specular_texture_name: Option<String>,
#[serde(default)]
pub specular_texture_uv_set: u32,
#[serde(default)]
pub specular_color_texture_uuid: Option<AssetUuid>,
#[serde(default)]
pub specular_color_texture_name: Option<String>,
#[serde(default)]
pub specular_color_texture_uv_set: u32,
#[serde(default = "default_emissive_strength")]
pub emissive_strength: f32,
}
fn default_alpha_cutoff() -> f32 {
0.5
}
fn default_roughness() -> f32 {
0.5
}
fn default_uv_scale() -> [f32; 2] {
[1.0, 1.0]
}
fn default_normal_scale() -> f32 {
1.0
}
fn default_occlusion_strength() -> f32 {
1.0
}
fn default_attenuation_color() -> [f32; 3] {
[1.0, 1.0, 1.0]
}
fn default_attenuation_distance() -> f32 {
f32::INFINITY
}
fn default_ior() -> f32 {
1.5
}
fn default_specular_factor() -> f32 {
1.0
}
fn default_specular_color_factor() -> [f32; 3] {
[1.0, 1.0, 1.0]
}
fn default_emissive_strength() -> f32 {
1.0
}
impl Default for SceneMaterial {
fn default() -> Self {
Self {
base_color: [1.0, 1.0, 1.0, 1.0],
emissive_factor: [0.0, 0.0, 0.0],
alpha_mode: SceneAlphaMode::Opaque,
alpha_cutoff: 0.5,
base_texture_uuid: None,
base_texture_name: None,
base_texture_uv_set: 0,
emissive_texture_uuid: None,
emissive_texture_name: None,
emissive_texture_uv_set: 0,
normal_texture_uuid: None,
normal_texture_name: None,
normal_texture_uv_set: 0,
normal_scale: 1.0,
normal_map_flip_y: false,
normal_map_two_component: false,
metallic_roughness_texture_uuid: None,
metallic_roughness_texture_name: None,
metallic_roughness_texture_uv_set: 0,
occlusion_texture_uuid: None,
occlusion_texture_name: None,
occlusion_texture_uv_set: 0,
occlusion_strength: 1.0,
roughness: 0.5,
metallic: 0.0,
unlit: false,
double_sided: false,
uv_scale: [1.0, 1.0],
transmission_factor: 0.0,
transmission_texture_uuid: None,
transmission_texture_name: None,
transmission_texture_uv_set: 0,
thickness: 0.0,
thickness_texture_uuid: None,
thickness_texture_name: None,
thickness_texture_uv_set: 0,
attenuation_color: [1.0, 1.0, 1.0],
attenuation_distance: f32::INFINITY,
ior: 1.5,
specular_factor: 1.0,
specular_color_factor: [1.0, 1.0, 1.0],
specular_texture_uuid: None,
specular_texture_name: None,
specular_texture_uv_set: 0,
specular_color_texture_uuid: None,
specular_color_texture_name: None,
specular_color_texture_uv_set: 0,
emissive_strength: 1.0,
}
}
}
impl SceneMaterial {
pub fn to_material(&self) -> Material {
Material {
base_color: self.base_color,
emissive_factor: self.emissive_factor,
alpha_mode: self.alpha_mode.into(),
alpha_cutoff: self.alpha_cutoff,
base_texture: self.base_texture_name.clone(),
base_texture_uv_set: self.base_texture_uv_set,
emissive_texture: self.emissive_texture_name.clone(),
emissive_texture_uv_set: self.emissive_texture_uv_set,
normal_texture: self.normal_texture_name.clone(),
normal_texture_uv_set: self.normal_texture_uv_set,
normal_scale: self.normal_scale,
normal_map_flip_y: self.normal_map_flip_y,
normal_map_two_component: self.normal_map_two_component,
metallic_roughness_texture: self.metallic_roughness_texture_name.clone(),
metallic_roughness_texture_uv_set: self.metallic_roughness_texture_uv_set,
occlusion_texture: self.occlusion_texture_name.clone(),
occlusion_texture_uv_set: self.occlusion_texture_uv_set,
occlusion_strength: self.occlusion_strength,
roughness: self.roughness,
metallic: self.metallic,
unlit: self.unlit,
double_sided: self.double_sided,
uv_scale: self.uv_scale,
transmission_factor: self.transmission_factor,
transmission_texture: self.transmission_texture_name.clone(),
transmission_texture_uv_set: self.transmission_texture_uv_set,
thickness: self.thickness,
thickness_texture: self.thickness_texture_name.clone(),
thickness_texture_uv_set: self.thickness_texture_uv_set,
attenuation_color: self.attenuation_color,
attenuation_distance: self.attenuation_distance,
ior: self.ior,
specular_factor: self.specular_factor,
specular_color_factor: self.specular_color_factor,
specular_texture: self.specular_texture_name.clone(),
specular_texture_uv_set: self.specular_texture_uv_set,
specular_color_texture: self.specular_color_texture_name.clone(),
specular_color_texture_uv_set: self.specular_color_texture_uv_set,
emissive_strength: self.emissive_strength,
}
}
}
impl From<&Material> for SceneMaterial {
fn from(material: &Material) -> Self {
Self {
base_color: material.base_color,
emissive_factor: material.emissive_factor,
alpha_mode: material.alpha_mode.into(),
alpha_cutoff: material.alpha_cutoff,
base_texture_uuid: None,
base_texture_name: material.base_texture.clone(),
base_texture_uv_set: material.base_texture_uv_set,
emissive_texture_uuid: None,
emissive_texture_name: material.emissive_texture.clone(),
emissive_texture_uv_set: material.emissive_texture_uv_set,
normal_texture_uuid: None,
normal_texture_name: material.normal_texture.clone(),
normal_texture_uv_set: material.normal_texture_uv_set,
normal_scale: material.normal_scale,
normal_map_flip_y: material.normal_map_flip_y,
normal_map_two_component: material.normal_map_two_component,
metallic_roughness_texture_uuid: None,
metallic_roughness_texture_name: material.metallic_roughness_texture.clone(),
metallic_roughness_texture_uv_set: material.metallic_roughness_texture_uv_set,
occlusion_texture_uuid: None,
occlusion_texture_name: material.occlusion_texture.clone(),
occlusion_texture_uv_set: material.occlusion_texture_uv_set,
occlusion_strength: material.occlusion_strength,
roughness: material.roughness,
metallic: material.metallic,
unlit: material.unlit,
double_sided: material.double_sided,
uv_scale: material.uv_scale,
transmission_factor: material.transmission_factor,
transmission_texture_uuid: None,
transmission_texture_name: material.transmission_texture.clone(),
transmission_texture_uv_set: material.transmission_texture_uv_set,
thickness: material.thickness,
thickness_texture_uuid: None,
thickness_texture_name: material.thickness_texture.clone(),
thickness_texture_uv_set: material.thickness_texture_uv_set,
attenuation_color: material.attenuation_color,
attenuation_distance: material.attenuation_distance,
ior: material.ior,
specular_factor: material.specular_factor,
specular_color_factor: material.specular_color_factor,
specular_texture_uuid: None,
specular_texture_name: material.specular_texture.clone(),
specular_texture_uv_set: material.specular_texture_uv_set,
specular_color_texture_uuid: None,
specular_color_texture_name: material.specular_color_texture.clone(),
specular_color_texture_uv_set: material.specular_color_texture_uv_set,
emissive_strength: material.emissive_strength,
}
}
}
#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq)]
pub enum SceneAlphaMode {
#[default]
Opaque,
Mask,
Blend,
}
impl From<AlphaMode> for SceneAlphaMode {
fn from(mode: AlphaMode) -> Self {
match mode {
AlphaMode::Opaque => SceneAlphaMode::Opaque,
AlphaMode::Mask => SceneAlphaMode::Mask,
AlphaMode::Blend => SceneAlphaMode::Blend,
}
}
}
impl From<SceneAlphaMode> for AlphaMode {
fn from(mode: SceneAlphaMode) -> Self {
match mode {
SceneAlphaMode::Opaque => AlphaMode::Opaque,
SceneAlphaMode::Mask => AlphaMode::Mask,
SceneAlphaMode::Blend => AlphaMode::Blend,
}
}
}