library: material: split Material into trait

The former `Material` type is now `UniformMaterial` and implements the
`Material` trait.
This commit is contained in:
Bruno BELANYI 2020-03-17 19:16:25 +01:00
parent 2a36728468
commit d785800bfe
2 changed files with 73 additions and 52 deletions

View file

@ -1,56 +1,13 @@
use super::core::color::LinearColor;
use super::Point2D;
/// Represent the physical light properties of an object in the scene.
#[derive(Debug, PartialEq)]
pub struct Material {
/// The diffuse component.
diffuse: LinearColor,
/// The specular component.
specular: LinearColor,
/// Represent the physical light properties of an object in the scene;
pub trait Material: std::fmt::Debug {
/// The diffuse component on a texel point.
fn diffuse(&self, point: Point2D) -> LinearColor;
/// The specular component on a texel point.
fn specular(&self, point: Point2D) -> LinearColor;
}
impl Material {
pub fn new(diffuse: LinearColor, specular: LinearColor) -> Self {
Material { diffuse, specular }
}
pub fn diffuse(&self) -> &LinearColor {
&self.diffuse
}
pub fn specular(&self) -> &LinearColor {
&self.specular
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn new_works() {
let diffuse = LinearColor::new(0., 0.5, 0.);
let specular = LinearColor::new(1., 1., 1.);
let mat = Material::new(diffuse.clone(), specular.clone());
assert_eq!(mat, Material { diffuse, specular })
}
fn simple_material() -> Material {
Material::new(
LinearColor::new(0.5, 0.5, 0.5),
LinearColor::new(1., 1., 1.),
)
}
#[test]
fn diffuse_works() {
let mat = simple_material();
assert_eq!(mat.diffuse(), &LinearColor::new(0.5, 0.5, 0.5))
}
#[test]
fn specular_works() {
let mat = simple_material();
assert_eq!(mat.specular(), &LinearColor::new(1., 1., 1.))
}
}
pub mod uniform;
pub use uniform::*;

64
src/material/uniform.rs Normal file
View file

@ -0,0 +1,64 @@
use super::super::core::color::LinearColor;
use super::super::Point2D;
use super::Material;
/// A material with the same characteristics on all points.
#[derive(Debug, PartialEq)]
pub struct UniformMaterial {
diffuse: LinearColor,
specular: LinearColor,
}
impl UniformMaterial {
pub fn new(diffuse: LinearColor, specular: LinearColor) -> Self {
UniformMaterial { diffuse, specular }
}
}
impl Material for UniformMaterial {
fn diffuse(&self, _: Point2D) -> LinearColor {
self.diffuse.clone()
}
fn specular(&self, _: Point2D) -> LinearColor {
self.specular.clone()
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn new_works() {
let diffuse = LinearColor::new(0., 0.5, 0.);
let specular = LinearColor::new(1., 1., 1.);
let mat = UniformMaterial::new(diffuse.clone(), specular.clone());
assert_eq!(mat, UniformMaterial { diffuse, specular })
}
fn simple_material() -> impl Material {
UniformMaterial::new(
LinearColor::new(0.5, 0.5, 0.5),
LinearColor::new(1., 1., 1.),
)
}
#[test]
fn diffuse_works() {
let mat = simple_material();
assert_eq!(
mat.diffuse(Point2D::origin()),
LinearColor::new(0.5, 0.5, 0.5)
)
}
#[test]
fn specular_works() {
let mat = simple_material();
assert_eq!(
mat.specular(Point2D::origin()),
LinearColor::new(1., 1., 1.)
)
}
}