library: light: add PointLight implementation
This commit is contained in:
parent
7c8cc0d970
commit
22167a1b93
|
@ -12,3 +12,6 @@ pub trait SpatialLight: Light {
|
||||||
/// Get a unit vector from the origin to the position of the light, and its distance
|
/// Get a unit vector from the origin to the position of the light, and its distance
|
||||||
fn to_source(&self, origin: &Point) -> (Vector, f32);
|
fn to_source(&self, origin: &Point) -> (Vector, f32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub mod point_light;
|
||||||
|
pub use point_light::*;
|
||||||
|
|
66
src/light/point_light.rs
Normal file
66
src/light/point_light.rs
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
use super::super::core::LinearColor;
|
||||||
|
use super::super::{Point, Vector};
|
||||||
|
use super::{Light, SpatialLight};
|
||||||
|
|
||||||
|
/// Represent a light emanating from a point in space, following the square distance law.
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub struct PointLight {
|
||||||
|
position: Point,
|
||||||
|
color: LinearColor,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PointLight {
|
||||||
|
pub fn new(position: Point, color: LinearColor) -> Self {
|
||||||
|
PointLight { position, color }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Light for PointLight {
|
||||||
|
fn illumination(&self, point: &Point) -> LinearColor {
|
||||||
|
let dist = (self.position - point).norm();
|
||||||
|
self.color.clone() / dist
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SpatialLight for PointLight {
|
||||||
|
fn to_source(&self, point: &Point) -> (Vector, f32) {
|
||||||
|
let delt = self.position - point;
|
||||||
|
let dist = delt.norm();
|
||||||
|
(delt.normalize(), dist)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn new_works() {
|
||||||
|
let position = Point::origin();
|
||||||
|
let color = LinearColor::black();
|
||||||
|
let light = PointLight::new(position, color.clone());
|
||||||
|
let res = PointLight { position, color };
|
||||||
|
assert_eq!(light, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn simple_light() -> impl SpatialLight {
|
||||||
|
let position = Point::origin();
|
||||||
|
let color = LinearColor::new(1., 1., 1.);
|
||||||
|
PointLight::new(position, color)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn illumination_is_correct() {
|
||||||
|
let light = simple_light();
|
||||||
|
let lum = light.illumination(&Point::new(1., 0., 0.));
|
||||||
|
assert_eq!(lum, LinearColor::new(1., 1., 1.))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn to_source_is_correct() {
|
||||||
|
let light = simple_light();
|
||||||
|
let ans = light.to_source(&Point::new(1., 0., 0.));
|
||||||
|
let expected = (Vector::new(-1., 0., 0.), 1.);
|
||||||
|
assert_eq!(ans, expected);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue