Beginnings of parsing sphere lights.
This commit is contained in:
parent
1cbf20e67f
commit
c2d36e0d14
|
@ -4,6 +4,7 @@ use math::Matrix4x4;
|
||||||
use bvh::BVH;
|
use bvh::BVH;
|
||||||
use boundable::Boundable;
|
use boundable::Boundable;
|
||||||
use surface::Surface;
|
use surface::Surface;
|
||||||
|
use light::LightSource;
|
||||||
use bbox::{BBox, transform_bbox_slice_from};
|
use bbox::{BBox, transform_bbox_slice_from};
|
||||||
|
|
||||||
|
|
||||||
|
@ -160,6 +161,7 @@ impl AssemblyBuilder {
|
||||||
let obj = &self.objects[inst.data_index];
|
let obj = &self.objects[inst.data_index];
|
||||||
match obj {
|
match obj {
|
||||||
&Object::Surface(ref s) => bbs.extend(s.bounds()),
|
&Object::Surface(ref s) => bbs.extend(s.bounds()),
|
||||||
|
&Object::Light(_) => unimplemented!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,6 +195,7 @@ impl AssemblyBuilder {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Object {
|
pub enum Object {
|
||||||
Surface(Box<Surface>),
|
Surface(Box<Surface>),
|
||||||
|
Light(Box<LightSource>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
mod sphere_light;
|
mod sphere_light;
|
||||||
|
|
||||||
// pub use sphere_light::{SphereLight};
|
use std::fmt::Debug;
|
||||||
|
|
||||||
|
pub use self::sphere_light::SphereLight;
|
||||||
|
|
||||||
use math::{Vector, Point};
|
use math::{Vector, Point};
|
||||||
use color::SpectralSample;
|
use color::SpectralSample;
|
||||||
|
use boundable::Boundable;
|
||||||
|
|
||||||
pub trait LightSource {
|
pub trait LightSource: Boundable + Debug + Sync {
|
||||||
/// Samples the light source for a given point to be illuminated.
|
/// Samples the light source for a given point to be illuminated.
|
||||||
///
|
///
|
||||||
/// - arr: The point to be illuminated.
|
/// - arr: The point to be illuminated.
|
||||||
|
@ -49,7 +52,7 @@ pub trait LightSource {
|
||||||
/// - dir: The direction of the outgoing light.
|
/// - dir: The direction of the outgoing light.
|
||||||
/// - u: Random parameter U.
|
/// - u: Random parameter U.
|
||||||
/// - v: Random parameter V.
|
/// - v: Random parameter V.
|
||||||
/// - wavelength: The wavelength of light to sample at.
|
/// - wavelength: The hero wavelength of light to sample at.
|
||||||
/// - time: The time to sample at.
|
/// - time: The time to sample at.
|
||||||
fn outgoing(&self, dir: Vector, u: f32, v: f32, wavelength: f32, time: f32) -> SpectralSample;
|
fn outgoing(&self, dir: Vector, u: f32, v: f32, wavelength: f32, time: f32) -> SpectralSample;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use math::{Vector, Point, coordinate_system_from_vector};
|
use math::{Vector, Point, coordinate_system_from_vector};
|
||||||
use bbox::BBox;
|
use bbox::BBox;
|
||||||
|
use boundable::Boundable;
|
||||||
use color::{XYZ, SpectralSample, Color};
|
use color::{XYZ, SpectralSample, Color};
|
||||||
use super::LightSource;
|
use super::LightSource;
|
||||||
use lerp::lerp_slice;
|
use lerp::lerp_slice;
|
||||||
|
@ -7,15 +8,15 @@ use sampling::{uniform_sample_cone, uniform_sample_cone_pdf, uniform_sample_sphe
|
||||||
use std::f64::consts::PI as PI_64;
|
use std::f64::consts::PI as PI_64;
|
||||||
use std::f32::consts::PI as PI_32;
|
use std::f32::consts::PI as PI_32;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct SphereLight {
|
pub struct SphereLight {
|
||||||
positions: Vec<Point>,
|
|
||||||
radii: Vec<f32>,
|
radii: Vec<f32>,
|
||||||
colors: Vec<XYZ>,
|
colors: Vec<XYZ>,
|
||||||
bounds_: Vec<BBox>,
|
bounds_: Vec<BBox>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SphereLight {
|
impl SphereLight {
|
||||||
fn new() -> SphereLight {
|
pub fn new(radii: Vec<f32>, colors: Vec<XYZ>) -> SphereLight {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +30,7 @@ impl LightSource for SphereLight {
|
||||||
time: f32)
|
time: f32)
|
||||||
-> (SpectralSample, Vector, f32) {
|
-> (SpectralSample, Vector, f32) {
|
||||||
// Calculate time interpolated values
|
// Calculate time interpolated values
|
||||||
let pos = lerp_slice(&self.positions, time);
|
let pos = Point::new(0.0, 0.0, 0.0); // Light position is always at origin
|
||||||
let radius: f64 = lerp_slice(&self.radii, time) as f64;
|
let radius: f64 = lerp_slice(&self.radii, time) as f64;
|
||||||
let col = lerp_slice(&self.colors, time);
|
let col = lerp_slice(&self.colors, time);
|
||||||
let surface_area_inv: f64 = 1.0 / (4.0 * PI_64 * radius * radius);
|
let surface_area_inv: f64 = 1.0 / (4.0 * PI_64 * radius * radius);
|
||||||
|
@ -98,7 +99,7 @@ impl LightSource for SphereLight {
|
||||||
wavelength: f32,
|
wavelength: f32,
|
||||||
time: f32)
|
time: f32)
|
||||||
-> f32 {
|
-> f32 {
|
||||||
let pos = lerp_slice(&self.positions, time);
|
let pos = Point::new(0.0, 0.0, 0.0); // Light position is always at origin
|
||||||
let radius: f64 = lerp_slice(&self.radii, time) as f64;
|
let radius: f64 = lerp_slice(&self.radii, time) as f64;
|
||||||
|
|
||||||
let d2: f64 = (pos - arr).length2() as f64; // Distance from center of sphere squared
|
let d2: f64 = (pos - arr).length2() as f64; // Distance from center of sphere squared
|
||||||
|
@ -127,3 +128,9 @@ impl LightSource for SphereLight {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Boundable for SphereLight {
|
||||||
|
fn bounds<'a>(&'a self) -> &'a [BBox] {
|
||||||
|
&self.bounds_
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ mod data_tree;
|
||||||
mod psy;
|
mod psy;
|
||||||
mod psy_assembly;
|
mod psy_assembly;
|
||||||
mod psy_mesh_surface;
|
mod psy_mesh_surface;
|
||||||
|
mod psy_light;
|
||||||
pub mod basics;
|
pub mod basics;
|
||||||
|
|
||||||
pub use self::data_tree::DataTree;
|
pub use self::data_tree::DataTree;
|
||||||
|
|
56
src/parse/psy_light.rs
Normal file
56
src/parse/psy_light.rs
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
use std::result::Result;
|
||||||
|
|
||||||
|
use nom::IResult;
|
||||||
|
|
||||||
|
use super::DataTree;
|
||||||
|
use super::basics::{ws_usize, ws_f32};
|
||||||
|
use super::psy::PsyParseError;
|
||||||
|
|
||||||
|
use light::SphereLight;
|
||||||
|
use math::Point;
|
||||||
|
use color::XYZ;
|
||||||
|
|
||||||
|
pub fn parse_sphere_light(tree: &DataTree) -> Result<SphereLight, PsyParseError> {
|
||||||
|
if let &DataTree::Internal { ref children, .. } = tree {
|
||||||
|
let mut radii = Vec::new();
|
||||||
|
let mut colors = Vec::new();
|
||||||
|
|
||||||
|
// Parse
|
||||||
|
for child in children.iter() {
|
||||||
|
match child {
|
||||||
|
// Radius
|
||||||
|
&DataTree::Leaf { type_name, contents } if type_name == "Radius" => {
|
||||||
|
if let IResult::Done(_, radius) = ws_f32(contents.as_bytes()) {
|
||||||
|
radii.push(radius);
|
||||||
|
} else {
|
||||||
|
// Found radius, but its contents is not in the right format
|
||||||
|
return Err(PsyParseError::UnknownError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Color
|
||||||
|
&DataTree::Leaf { type_name, contents } if type_name == "Color" => {
|
||||||
|
if let IResult::Done(_, color) = closure!(tuple!(ws_f32,
|
||||||
|
ws_f32,
|
||||||
|
ws_f32))(contents.as_bytes()) {
|
||||||
|
// TODO: handle color space conversions properly.
|
||||||
|
// Probably will need a special color type with its
|
||||||
|
// own parser...?
|
||||||
|
colors.push(XYZ::new(color.0, color.1, color.2));
|
||||||
|
} else {
|
||||||
|
// Found color, but its contents is not in the right format
|
||||||
|
return Err(PsyParseError::UnknownError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(SphereLight::new(radii, colors));
|
||||||
|
} else {
|
||||||
|
return Err(PsyParseError::UnknownError);
|
||||||
|
}
|
||||||
|
}
|
|
@ -115,6 +115,8 @@ impl<'a> Tracer<'a> {
|
||||||
&Object::Surface(ref surface) => {
|
&Object::Surface(ref surface) => {
|
||||||
surface.intersect_rays(rays, wrays, &mut self.isects, self.xform_stack.top());
|
surface.intersect_rays(rays, wrays, &mut self.isects, self.xform_stack.top());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&Object::Light(_) => unimplemented!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user