#[derive(Copy, Clone, PartialEq, Debug)]
pub struct Material {
pub absorption: [f32; 3],
pub scattering: f32,
pub transmission: [f32; 3],
}
impl Default for Material {
fn default() -> Self {
Self::GENERIC
}
}
impl Material {
pub const GENERIC: Self = Self {
absorption: [0.10, 0.20, 0.30],
scattering: 0.05,
transmission: [0.100, 0.050, 0.030],
};
pub const BRICK: Self = Self {
absorption: [0.03, 0.04, 0.07],
scattering: 0.05,
transmission: [0.015, 0.015, 0.015],
};
pub const CONCRETE: Self = Self {
absorption: [0.05, 0.07, 0.08],
scattering: 0.05,
transmission: [0.015, 0.002, 0.001],
};
pub const CERAMIC: Self = Self {
absorption: [0.01, 0.02, 0.02],
scattering: 0.05,
transmission: [0.060, 0.044, 0.011],
};
pub const GRAVEL: Self = Self {
absorption: [0.60, 0.70, 0.80],
scattering: 0.05,
transmission: [0.031, 0.012, 0.008],
};
pub const CARPET: Self = Self {
absorption: [0.24, 0.69, 0.73],
scattering: 0.05,
transmission: [0.020, 0.005, 0.003],
};
pub const GLASS: Self = Self {
absorption: [0.06, 0.03, 0.02],
scattering: 0.05,
transmission: [0.060, 0.044, 0.011],
};
pub const PLASTER: Self = Self {
absorption: [0.12, 0.06, 0.04],
scattering: 0.05,
transmission: [0.056, 0.056, 0.004],
};
pub const WOOD: Self = Self {
absorption: [0.11, 0.07, 0.06],
scattering: 0.05,
transmission: [0.070, 0.014, 0.005],
};
pub const METAL: Self = Self {
absorption: [0.20, 0.07, 0.06],
scattering: 0.05,
transmission: [0.200, 0.025, 0.010],
};
pub const ROCK: Self = Self {
absorption: [0.13, 0.20, 0.24],
scattering: 0.05,
transmission: [0.015, 0.002, 0.001],
};
}
impl From<Material> for audionimbus_sys::IPLMaterial {
fn from(material: Material) -> Self {
Self {
absorption: material.absorption,
scattering: material.scattering,
transmission: material.transmission,
}
}
}
impl From<&audionimbus_sys::IPLMaterial> for Material {
fn from(material: &audionimbus_sys::IPLMaterial) -> Self {
Self {
absorption: material.absorption,
scattering: material.scattering,
transmission: material.transmission,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_material_default() {
let m = Material::default();
assert_eq!(m.absorption, Material::GENERIC.absorption);
assert_eq!(m.scattering, Material::GENERIC.scattering);
assert_eq!(m.transmission, Material::GENERIC.transmission);
}
#[test]
fn test_all_material_presets_valid() {
let materials = [
Material::GENERIC,
Material::BRICK,
Material::CONCRETE,
Material::CERAMIC,
Material::GRAVEL,
Material::CARPET,
Material::GLASS,
Material::PLASTER,
Material::WOOD,
Material::METAL,
Material::ROCK,
];
for material in materials {
for &absorption in &material.absorption {
assert!(
(0.0..=1.0).contains(&absorption),
"invalid absorption value: {}",
absorption
);
}
assert!(material.scattering >= 0.0 && material.scattering <= 1.0);
for &transmission in &material.transmission {
assert!(
(0.0..=1.0).contains(&transmission),
"invalid transmission value: {}",
transmission
);
}
}
}
}