71 lines
1.9 KiB
Rust
71 lines
1.9 KiB
Rust
use crate::Float;
|
|
use crate::core::color::{RGB, XYZ};
|
|
use enum_dispatch::enum_dispatch;
|
|
|
|
pub use crate::spectra::*;
|
|
|
|
#[enum_dispatch]
|
|
pub trait SpectrumTrait: Copy {
|
|
fn evaluate(&self, lambda: Float) -> Float;
|
|
fn sample(&self, lambda: &SampledWavelengths) -> SampledSpectrum {
|
|
SampledSpectrum::from_fn(|i| self.evaluate(lambda[i]))
|
|
}
|
|
fn max_value(&self) -> Float;
|
|
}
|
|
|
|
#[repr(C)]
|
|
#[derive(Debug, Clone, Copy)]
|
|
pub struct StandardSpectra {
|
|
pub x: DenselySampledSpectrum,
|
|
pub y: DenselySampledSpectrum,
|
|
pub z: DenselySampledSpectrum,
|
|
pub d65: DenselySampledSpectrum,
|
|
}
|
|
|
|
unsafe impl Send for StandardSpectra {}
|
|
unsafe impl Sync for StandardSpectra {}
|
|
|
|
#[repr(C)]
|
|
#[enum_dispatch(SpectrumTrait)]
|
|
#[derive(Debug, Clone, Copy)]
|
|
pub enum Spectrum {
|
|
Constant(ConstantSpectrum),
|
|
Dense(DenselySampledSpectrum),
|
|
Piecewise(PiecewiseLinearSpectrum),
|
|
Blackbody(BlackbodySpectrum),
|
|
RGBAlbedo(RGBAlbedoSpectrum),
|
|
RGBIlluminant(RGBIlluminantSpectrum),
|
|
RGBUnbounded(RGBUnboundedSpectrum),
|
|
}
|
|
|
|
impl Spectrum {
|
|
pub fn std_illuminant_d65() -> Self {
|
|
unimplemented!("Use crate::spectra::default_illuminant() on host")
|
|
}
|
|
|
|
pub fn to_xyz(&self, std: &StandardSpectra) -> XYZ {
|
|
let x = self.inner_product(&Spectrum::Dense(std.x));
|
|
let y = self.inner_product(&Spectrum::Dense(std.y));
|
|
let z = self.inner_product(&Spectrum::Dense(std.z));
|
|
|
|
XYZ::new(x, y, z) / CIE_Y_INTEGRAL
|
|
}
|
|
|
|
pub fn to_rgb(&self, cs: &RGBColorSpace, std: &StandardSpectra) -> RGB {
|
|
let xyz = self.to_xyz(std);
|
|
cs.to_rgb(xyz)
|
|
}
|
|
|
|
pub fn inner_product(&self, other: &Spectrum) -> Float {
|
|
let mut integral = 0.0;
|
|
for lambda in LAMBDA_MIN..=LAMBDA_MAX {
|
|
let l = lambda as Float;
|
|
integral += self.evaluate(l) * other.evaluate(l);
|
|
}
|
|
integral
|
|
}
|
|
|
|
pub fn is_constant(&self) -> bool {
|
|
matches!(self, Spectrum::Constant(_))
|
|
}
|
|
}
|