#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct MaterialPreviewConfig {
pub sphere_segments: u32,
pub show_environment: bool,
pub exposure: f32,
pub max_materials: usize,
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct PreviewPbrMaterial {
pub name: String,
pub albedo: [f32; 3],
pub metallic: f32,
pub roughness: f32,
pub emissive: [f32; 3],
pub alpha: f32,
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct MaterialPreviewScene {
pub config: MaterialPreviewConfig,
pub materials: Vec<PreviewPbrMaterial>,
}
#[allow(dead_code)]
pub fn default_material_preview_config() -> MaterialPreviewConfig {
MaterialPreviewConfig {
sphere_segments: 32,
show_environment: true,
exposure: 1.0,
max_materials: 64,
}
}
#[allow(dead_code)]
pub fn new_pbr_material(name: &str) -> PreviewPbrMaterial {
PreviewPbrMaterial {
name: name.to_string(),
albedo: [1.0, 1.0, 1.0],
metallic: 0.0,
roughness: 0.5,
emissive: [0.0, 0.0, 0.0],
alpha: 1.0,
}
}
#[allow(dead_code)]
pub fn pbr_set_albedo(mat: &mut PreviewPbrMaterial, r: f32, g: f32, b: f32) {
mat.albedo = [r.clamp(0.0, 1.0), g.clamp(0.0, 1.0), b.clamp(0.0, 1.0)];
}
#[allow(dead_code)]
pub fn pbr_set_metallic(mat: &mut PreviewPbrMaterial, metallic: f32) {
mat.metallic = metallic.clamp(0.0, 1.0);
}
#[allow(dead_code)]
pub fn pbr_set_roughness(mat: &mut PreviewPbrMaterial, roughness: f32) {
mat.roughness = roughness.clamp(0.0, 1.0);
}
#[allow(dead_code)]
pub fn pbr_set_emissive(mat: &mut PreviewPbrMaterial, r: f32, g: f32, b: f32) {
mat.emissive = [r.max(0.0), g.max(0.0), b.max(0.0)];
}
#[allow(dead_code)]
pub fn new_material_preview_scene(cfg: &MaterialPreviewConfig) -> MaterialPreviewScene {
MaterialPreviewScene {
config: cfg.clone(),
materials: Vec::new(),
}
}
#[allow(dead_code)]
pub fn scene_add_material(scene: &mut MaterialPreviewScene, mat: PreviewPbrMaterial) {
scene.materials.push(mat);
}
#[allow(dead_code)]
pub fn scene_material_count(scene: &MaterialPreviewScene) -> usize {
scene.materials.len()
}
#[allow(dead_code)]
pub fn pbr_material_to_string(mat: &PreviewPbrMaterial) -> String {
format!(
"PreviewPbrMaterial {{ name: \"{}\", albedo: [{:.3},{:.3},{:.3}], \
metallic: {:.3}, roughness: {:.3}, emissive: [{:.3},{:.3},{:.3}], alpha: {:.3} }}",
mat.name,
mat.albedo[0],
mat.albedo[1],
mat.albedo[2],
mat.metallic,
mat.roughness,
mat.emissive[0],
mat.emissive[1],
mat.emissive[2],
mat.alpha,
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_config() {
let cfg = default_material_preview_config();
assert_eq!(cfg.sphere_segments, 32);
assert!(cfg.show_environment);
assert!((cfg.exposure - 1.0).abs() < 1e-6);
}
#[test]
fn test_new_pbr_material_defaults() {
let mat = new_pbr_material("TestMat");
assert_eq!(mat.name, "TestMat");
assert_eq!(mat.albedo, [1.0, 1.0, 1.0]);
assert!((mat.metallic - 0.0).abs() < 1e-6);
assert!((mat.roughness - 0.5).abs() < 1e-6);
}
#[test]
fn test_pbr_set_albedo() {
let mut mat = new_pbr_material("M");
pbr_set_albedo(&mut mat, 0.8, 0.5, 0.3);
assert!((mat.albedo[0] - 0.8).abs() < 1e-6);
assert!((mat.albedo[1] - 0.5).abs() < 1e-6);
}
#[test]
fn test_pbr_set_albedo_clamps() {
let mut mat = new_pbr_material("M");
pbr_set_albedo(&mut mat, -1.0, 2.0, 0.5);
assert!((mat.albedo[0] - 0.0).abs() < 1e-6);
assert!((mat.albedo[1] - 1.0).abs() < 1e-6);
}
#[test]
fn test_pbr_set_metallic_roughness() {
let mut mat = new_pbr_material("Metal");
pbr_set_metallic(&mut mat, 1.0);
pbr_set_roughness(&mut mat, 0.1);
assert!((mat.metallic - 1.0).abs() < 1e-6);
assert!((mat.roughness - 0.1).abs() < 1e-6);
}
#[test]
fn test_pbr_set_emissive() {
let mut mat = new_pbr_material("Glow");
pbr_set_emissive(&mut mat, 2.0, 0.0, 0.5);
assert!((mat.emissive[0] - 2.0).abs() < 1e-6);
}
#[test]
fn test_scene_add_and_count() {
let cfg = default_material_preview_config();
let mut scene = new_material_preview_scene(&cfg);
scene_add_material(&mut scene, new_pbr_material("Mat1"));
scene_add_material(&mut scene, new_pbr_material("Mat2"));
assert_eq!(scene_material_count(&scene), 2);
}
#[test]
fn test_pbr_material_to_string() {
let mat = new_pbr_material("Preview");
let s = pbr_material_to_string(&mat);
assert!(s.contains("Preview"));
assert!(s.contains("metallic"));
assert!(s.contains("roughness"));
}
#[test]
fn test_scene_starts_empty() {
let cfg = default_material_preview_config();
let scene = new_material_preview_scene(&cfg);
assert_eq!(scene_material_count(&scene), 0);
}
}