94 lines
2.7 KiB
Rust
94 lines
2.7 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, VectorLike};
|
|
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::DistantLight;
|
|
use shared::spectra::RGBColorSpace;
|
|
use shared::utils::{Ptr, Transform};
|
|
use shared::Float;
|
|
|
|
trait CreateDistantLight {
|
|
fn new(render_from_light: Transform, le: Spectrum, scale: Float) -> Self;
|
|
}
|
|
|
|
impl CreateDistantLight for DistantLight {
|
|
fn new(render_from_light: Transform, le: Spectrum, scale: Float) -> Self {
|
|
let base = LightBase::new(
|
|
LightType::DeltaDirection,
|
|
render_from_light,
|
|
MediumInterface::empty(),
|
|
);
|
|
let lemit = lookup_spectrum(&le);
|
|
Self {
|
|
base,
|
|
lemit: Ptr::from(&*lemit),
|
|
scale,
|
|
scene_center: Point3f::default(),
|
|
scene_radius: 0.,
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn create(
|
|
render_from_light: Transform,
|
|
_medium: Option<Medium>,
|
|
parameters: &ParameterDictionary,
|
|
_loc: &FileLoc,
|
|
_shape: &Shape,
|
|
_alpha_text: &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.)?;
|
|
|
|
let from = parameters.get_one_point3f("from", Point3f::new(0., 0., 0.))?;
|
|
let to = parameters.get_one_point3f("to", Point3f::new(0., 0., 1.))?;
|
|
let w = (from - to).normalize();
|
|
let (v1, v2) = w.coordinate_system();
|
|
let m: [Float; 16] = [
|
|
v1.x(),
|
|
v2.x(),
|
|
w.x(),
|
|
0.,
|
|
v1.y(),
|
|
v2.y(),
|
|
w.y(),
|
|
0.,
|
|
v1.z(),
|
|
v2.z(),
|
|
w.z(),
|
|
0.,
|
|
0.,
|
|
0.,
|
|
0.,
|
|
1.,
|
|
];
|
|
let t = Transform::from_flat(&m).expect("Could not create transform for DistantLight");
|
|
let final_render = render_from_light * t;
|
|
scale /= spectrum_to_photometric(l);
|
|
// Adjust scale to meet target illuminance value
|
|
let e_v = parameters.get_one_float("illuminance", -1.)?;
|
|
if e_v > 0. {
|
|
scale *= e_v;
|
|
}
|
|
|
|
let specific = DistantLight::new(final_render, l, scale);
|
|
|
|
Ok(Light::Distant(specific))
|
|
}
|