use geometry::prelude::*;
use spectrum::*;
use component::Composable;
use renderer::scene::Scene;
pub use filming::SampleInfo;
pub trait Light: Sync+ Send {
fn flags(&self) -> LightFlag;
#[inline]
fn is_delta(&self) -> bool {
self.flags().is_delta()
}
#[inline]
fn evaluate_ray(&self, rd: &RayDifferential) -> RGBSpectrumf {
self.evaluate_path(rd.ray.origin(), rd.ray.direction())
}
#[inline]
fn evaluate_path(&self, _pos: Point3f, _dir: Vector3f) -> RGBSpectrumf {
RGBSpectrumf::black()
}
fn evaluate_sampled(&self, pos: Point3f, sample: Point2f) -> LightSample;
fn generate_path(&self, samples: SampleInfo) -> PathInfo;
fn pdf_path(&self, pos: Point3f, dir: Vector3f, normal: Vector3f) -> (Float, Float);
#[inline]
fn pdf(&self, _pos: Point3f, _wi: Vector3f) -> Float {
0. as Float
}
fn power(&self) -> RGBSpectrumf;
#[inline]
fn preprocess(&mut self, _s: &Scene) { }
}
bitflags! {
pub flags LightFlag: u32 {
const LIGHT_DPOS = 0x1,
const LIGHT_DDIR = 0x2,
const LIGHT_AREA = 0x4,
const LIGHT_INFINITE = 0x8,
}
}
impl LightFlag {
pub fn is_delta(self) -> bool {
(self & LIGHT_DPOS == LIGHT_DPOS) ||
(self & LIGHT_DDIR == LIGHT_DDIR)
}
}
#[derive(Debug, PartialEq, Copy, Clone)]
pub struct LightSample {
pub radiance: RGBSpectrumf,
pub pdf: Float,
pub pfrom: Point3f,
pub pto: Point3f,
}
#[must_use]
impl LightSample {
#[inline]
pub fn wi(&self) -> Vector3f {
(self.pfrom - self.pto).normalize()
}
#[inline]
pub fn occluded<C: Composable + ?Sized>(&self, components: &C) -> bool {
let epsilon = Point3f::default_epsilon()*2.0;
let dir = self.pto - self.pfrom;
let pfrom = self.pfrom + dir*epsilon;
let pto = self.pto + (-dir*epsilon);
let ray = RawRay::spawn(pfrom, pto);
components.can_intersect(&ray)
}
#[inline]
pub fn apply_transform<T>(&self, t: &T) -> LightSample
where T: TransformExt
{
LightSample {
radiance: self.radiance,
pdf: self.pdf,
pfrom: t.transform_point(self.pfrom),
pto: t.transform_point(self.pto),
}
}
#[inline]
pub fn no_effect(&self) -> bool {
self.pdf == 0.0 as Float || self.radiance == RGBSpectrumf::black()
}
}
#[derive(Debug, PartialEq, Copy, Clone)]
#[must_use]
pub struct PathInfo {
pub ray: RawRay,
pub normal: Vector3f,
pub pdfpos: Float,
pub pdfdir: Float,
pub radiance: RGBSpectrumf,
}
impl PathInfo {
#[inline]
pub fn apply_transform(&self, t: &Matrix4f) -> Self {
PathInfo{
ray: self.ray.apply_transform(t),
normal: t.transform_norm(self.normal),
pdfpos: self.pdfpos,
pdfdir: self.pdfdir,
radiance: self.radiance,
}
}
}
pub mod pointlights;
pub mod distantlight;
pub mod prelude;