91 lines
2.5 KiB
Rust
91 lines
2.5 KiB
Rust
use crate::core::light::lookup_spectrum;
|
|
use crate::core::spectrum::spectrum_to_photometric;
|
|
use crate::core::texture::FloatTexture;
|
|
use crate::utils::{Arena, FileLoc, ParameterDictionary};
|
|
use anyhow::Result;
|
|
use shared::core::geometry::Point3f;
|
|
use shared::core::light::{Light, LightBase, LightType};
|
|
use shared::core::medium::{Medium, MediumInterface};
|
|
use shared::core::shape::Shape;
|
|
use shared::core::spectrum::Spectrum;
|
|
use shared::core::texture::SpectrumType;
|
|
use shared::lights::PointLight;
|
|
use shared::spectra::RGBColorSpace;
|
|
use shared::{Float, PI, Transform};
|
|
|
|
pub trait CreatePointLight {
|
|
fn new(
|
|
render_from_light: Transform,
|
|
medium_interface: MediumInterface,
|
|
le: Spectrum,
|
|
scale: Float,
|
|
arena: &Arena,
|
|
) -> Self;
|
|
}
|
|
|
|
impl CreatePointLight for PointLight {
|
|
fn new(
|
|
render_from_light: Transform,
|
|
medium_interface: MediumInterface,
|
|
le: Spectrum,
|
|
scale: Float,
|
|
arena: &Arena,
|
|
) -> Self {
|
|
let base = LightBase::new(
|
|
LightType::DeltaPosition,
|
|
render_from_light,
|
|
medium_interface,
|
|
);
|
|
let iemit = lookup_spectrum(&le);
|
|
let i = arena.alloc((*iemit).clone());
|
|
Self { base, scale, i }
|
|
}
|
|
}
|
|
|
|
|
|
pub fn create(
|
|
render_from_light: Transform,
|
|
medium: Option<Medium>,
|
|
parameters: &ParameterDictionary,
|
|
_loc: &FileLoc,
|
|
_shape: &Shape,
|
|
_alpha: &FloatTexture,
|
|
colorspace: Option<&RGBColorSpace>,
|
|
arena: &Arena,
|
|
) -> Result<Light> {
|
|
let default_cs = crate::spectra::default_colorspace();
|
|
let cs = colorspace.unwrap_or(&default_cs);
|
|
|
|
let l = parameters
|
|
.get_one_spectrum(
|
|
"L",
|
|
Some(Spectrum::Dense(cs.illuminant)),
|
|
SpectrumType::Illuminant,
|
|
)
|
|
.unwrap();
|
|
let mut scale = parameters.get_one_float("scale", 1.)?;
|
|
scale /= spectrum_to_photometric(l);
|
|
let phi_v = parameters.get_one_float("power", 1.)?;
|
|
if phi_v > 0. {
|
|
let k_e = 4. * PI;
|
|
scale *= phi_v / k_e;
|
|
}
|
|
|
|
let from = parameters.get_one_point3f("from", Point3f::zero())?;
|
|
let tf = Transform::translate(from.into());
|
|
let final_render = render_from_light * tf;
|
|
|
|
let mi = match medium {
|
|
Some(m) => {
|
|
let ptr = arena.alloc(m);
|
|
MediumInterface {
|
|
inside: ptr,
|
|
outside: ptr,
|
|
}
|
|
}
|
|
None => MediumInterface::default(),
|
|
};
|
|
|
|
let specific = PointLight::new(final_render, mi, l, scale, arena);
|
|
Ok(Light::Point(specific))
|
|
}
|