Continuing cleanup of builder and parser. Removing light factory, creating issues with function signatures and unnecessary resources for light creation
This commit is contained in:
parent
0c04eeb0f9
commit
c659ea0f44
11 changed files with 321 additions and 287 deletions
|
|
@ -2,8 +2,8 @@ use crate::cameras::realistic::RealisticCameraHost;
|
||||||
use crate::core::image::ImageMetadata;
|
use crate::core::image::ImageMetadata;
|
||||||
use crate::core::image::{Image, ImageIO};
|
use crate::core::image::{Image, ImageIO};
|
||||||
use crate::globals::get_options;
|
use crate::globals::get_options;
|
||||||
|
use crate::utils::read_float_file;
|
||||||
use crate::utils::{Arena, FileLoc, ParameterDictionary};
|
use crate::utils::{Arena, FileLoc, ParameterDictionary};
|
||||||
use crate::utils::{Upload, read_float_file};
|
|
||||||
use anyhow::{Result, anyhow};
|
use anyhow::{Result, anyhow};
|
||||||
use shared::Ptr;
|
use shared::Ptr;
|
||||||
use shared::cameras::*;
|
use shared::cameras::*;
|
||||||
|
|
|
||||||
|
|
@ -49,15 +49,20 @@ impl IndexMut<usize> for TransformSet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
struct PendingAreaLight {
|
||||||
|
name: String,
|
||||||
|
params: ParsedParameterVector,
|
||||||
|
loc: FileLoc,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone)]
|
#[derive(Default, Debug, Clone)]
|
||||||
struct GraphicsState {
|
struct GraphicsState {
|
||||||
pub current_inside_medium: String,
|
pub current_inside_medium: String,
|
||||||
pub current_outside_medium: String,
|
pub current_outside_medium: String,
|
||||||
pub current_material_name: String,
|
pub current_material_name: String,
|
||||||
pub current_material_index: Option<usize>,
|
pub current_material_index: Option<usize>,
|
||||||
pub area_light_name: String,
|
pub pending_area_light: Option<PendingAreaLight>,
|
||||||
pub area_light_params: ParsedParameterVector,
|
|
||||||
pub area_light_loc: FileLoc,
|
|
||||||
pub shape_attributes: ParsedParameterVector,
|
pub shape_attributes: ParsedParameterVector,
|
||||||
pub light_attributes: ParsedParameterVector,
|
pub light_attributes: ParsedParameterVector,
|
||||||
pub material_attributes: ParsedParameterVector,
|
pub material_attributes: ParsedParameterVector,
|
||||||
|
|
@ -191,7 +196,7 @@ impl BasicSceneBuilder {
|
||||||
|
|
||||||
fn make_params(
|
fn make_params(
|
||||||
&self,
|
&self,
|
||||||
params: &ParsedParameterVector,
|
params: ParsedParameterVector,
|
||||||
loc: &FileLoc,
|
loc: &FileLoc,
|
||||||
) -> Result<ParameterDictionary, ParserError> {
|
) -> Result<ParameterDictionary, ParserError> {
|
||||||
ParameterDictionary::new(params.clone(), self.graphics_state.color_space.clone())
|
ParameterDictionary::new(params.clone(), self.graphics_state.color_space.clone())
|
||||||
|
|
@ -333,7 +338,7 @@ impl ParserTarget for BasicSceneBuilder {
|
||||||
fn camera(
|
fn camera(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
params: &ParsedParameterVector,
|
params: ParsedParameterVector,
|
||||||
loc: FileLoc,
|
loc: FileLoc,
|
||||||
) -> Result<(), ParserError> {
|
) -> Result<(), ParserError> {
|
||||||
self.verify_options("Camera", &loc)?;
|
self.verify_options("Camera", &loc)?;
|
||||||
|
|
@ -357,7 +362,7 @@ impl ParserTarget for BasicSceneBuilder {
|
||||||
CameraTransform::from_world(animated_world_from_cam, rendering_space);
|
CameraTransform::from_world(animated_world_from_cam, rendering_space);
|
||||||
self.render_from_world = camera_from_world.t[0];
|
self.render_from_world = camera_from_world.t[0];
|
||||||
|
|
||||||
let parameters = self.make_params(¶ms.clone(), &loc)?;
|
let parameters = self.make_params(params, &loc)?;
|
||||||
|
|
||||||
self.current_camera = Some(CameraSceneEntity {
|
self.current_camera = Some(CameraSceneEntity {
|
||||||
base: SceneEntity {
|
base: SceneEntity {
|
||||||
|
|
@ -405,7 +410,7 @@ impl ParserTarget for BasicSceneBuilder {
|
||||||
fn pixel_filter(
|
fn pixel_filter(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
params: &ParsedParameterVector,
|
params: ParsedParameterVector,
|
||||||
loc: FileLoc,
|
loc: FileLoc,
|
||||||
) -> Result<(), ParserError> {
|
) -> Result<(), ParserError> {
|
||||||
self.verify_options("PixelFilter", &loc)?;
|
self.verify_options("PixelFilter", &loc)?;
|
||||||
|
|
@ -421,12 +426,12 @@ impl ParserTarget for BasicSceneBuilder {
|
||||||
fn film(
|
fn film(
|
||||||
&mut self,
|
&mut self,
|
||||||
type_name: &str,
|
type_name: &str,
|
||||||
params: &ParsedParameterVector,
|
params: ParsedParameterVector,
|
||||||
loc: FileLoc,
|
loc: FileLoc,
|
||||||
) -> Result<(), ParserError> {
|
) -> Result<(), ParserError> {
|
||||||
self.verify_options("Film", &loc)?;
|
self.verify_options("Film", &loc)?;
|
||||||
let parameters = self.make_params(params, &loc)?;
|
let parameters = self.make_params(params, &loc)?;
|
||||||
self.current_filter = Some(SceneEntity {
|
self.current_film = Some(SceneEntity {
|
||||||
name: type_name.to_string(),
|
name: type_name.to_string(),
|
||||||
loc,
|
loc,
|
||||||
parameters,
|
parameters,
|
||||||
|
|
@ -437,7 +442,7 @@ impl ParserTarget for BasicSceneBuilder {
|
||||||
fn accelerator(
|
fn accelerator(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
params: &ParsedParameterVector,
|
params: ParsedParameterVector,
|
||||||
loc: FileLoc,
|
loc: FileLoc,
|
||||||
) -> Result<(), ParserError> {
|
) -> Result<(), ParserError> {
|
||||||
self.verify_options("Accelerator", &loc)?;
|
self.verify_options("Accelerator", &loc)?;
|
||||||
|
|
@ -453,7 +458,7 @@ impl ParserTarget for BasicSceneBuilder {
|
||||||
fn integrator(
|
fn integrator(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
params: &ParsedParameterVector,
|
params: ParsedParameterVector,
|
||||||
loc: FileLoc,
|
loc: FileLoc,
|
||||||
) -> Result<(), ParserError> {
|
) -> Result<(), ParserError> {
|
||||||
self.verify_options("Integrator", &loc)?;
|
self.verify_options("Integrator", &loc)?;
|
||||||
|
|
@ -469,7 +474,7 @@ impl ParserTarget for BasicSceneBuilder {
|
||||||
fn make_named_medium(
|
fn make_named_medium(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
params: &ParsedParameterVector,
|
params: ParsedParameterVector,
|
||||||
loc: FileLoc,
|
loc: FileLoc,
|
||||||
) -> Result<(), ParserError> {
|
) -> Result<(), ParserError> {
|
||||||
self.verify_world("MakeNamedMaterial", &loc)?;
|
self.verify_world("MakeNamedMaterial", &loc)?;
|
||||||
|
|
@ -509,11 +514,11 @@ impl ParserTarget for BasicSceneBuilder {
|
||||||
fn sampler(
|
fn sampler(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
params: &ParsedParameterVector,
|
params: ParsedParameterVector,
|
||||||
loc: FileLoc,
|
loc: FileLoc,
|
||||||
) -> Result<(), ParserError> {
|
) -> Result<(), ParserError> {
|
||||||
self.verify_options("Sampler", &loc)?;
|
self.verify_options("Sampler", &loc)?;
|
||||||
let parameters = self.make_params(¶ms.clone(), &loc)?;
|
let parameters = self.make_params(params, &loc)?;
|
||||||
self.current_sampler = Some(SceneEntity {
|
self.current_sampler = Some(SceneEntity {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
loc,
|
loc,
|
||||||
|
|
@ -631,7 +636,7 @@ impl ParserTarget for BasicSceneBuilder {
|
||||||
orig_name: &str,
|
orig_name: &str,
|
||||||
type_name: &str,
|
type_name: &str,
|
||||||
tex_name: &str,
|
tex_name: &str,
|
||||||
params: &ParsedParameterVector,
|
params: ParsedParameterVector,
|
||||||
loc: FileLoc,
|
loc: FileLoc,
|
||||||
arena: Arc<Arena>,
|
arena: Arc<Arena>,
|
||||||
) -> Result<(), ParserError> {
|
) -> Result<(), ParserError> {
|
||||||
|
|
@ -693,7 +698,7 @@ impl ParserTarget for BasicSceneBuilder {
|
||||||
fn material(
|
fn material(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
params: &ParsedParameterVector,
|
params: ParsedParameterVector,
|
||||||
loc: FileLoc,
|
loc: FileLoc,
|
||||||
) -> Result<(), ParserError> {
|
) -> Result<(), ParserError> {
|
||||||
self.verify_world("material", &loc);
|
self.verify_world("material", &loc);
|
||||||
|
|
@ -708,7 +713,7 @@ impl ParserTarget for BasicSceneBuilder {
|
||||||
fn make_named_material(
|
fn make_named_material(
|
||||||
&mut self,
|
&mut self,
|
||||||
_name: &str,
|
_name: &str,
|
||||||
_params: &ParsedParameterVector,
|
_params: ParsedParameterVector,
|
||||||
_loc: FileLoc,
|
_loc: FileLoc,
|
||||||
) -> Result<(), ParserError> {
|
) -> Result<(), ParserError> {
|
||||||
todo!()
|
todo!()
|
||||||
|
|
@ -720,28 +725,114 @@ impl ParserTarget for BasicSceneBuilder {
|
||||||
|
|
||||||
fn light_source(
|
fn light_source(
|
||||||
&mut self,
|
&mut self,
|
||||||
_name: &str,
|
name: &str,
|
||||||
_params: &ParsedParameterVector,
|
params: ParsedParameterVector,
|
||||||
_loc: FileLoc,
|
loc: FileLoc,
|
||||||
) -> Result<(), ParserError> {
|
) -> Result<(), ParserError> {
|
||||||
|
self.verify_world("LightSource", &loc)?;
|
||||||
|
let dict = ParameterDictionary::from_array(
|
||||||
|
params.clone(),
|
||||||
|
&self.graphics_state.medium_attributes,
|
||||||
|
self.graphics_state.color_space.clone()
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let render_from_light = AnimatedTransform::new(
|
||||||
|
&self.graphics_state.ctm.t[0],
|
||||||
|
self.graphics_state.transform_start_time,
|
||||||
|
&self.graphics_state.ctm.t[1],
|
||||||
|
self.graphics_state.transform_end_time,
|
||||||
|
);
|
||||||
|
|
||||||
|
let entity = LightSceneEntity {
|
||||||
|
transformed_base: TransformedSceneEntity {
|
||||||
|
base: SceneEntity {
|
||||||
|
name: name.to_string(),
|
||||||
|
loc,
|
||||||
|
parameters: dict,
|
||||||
|
},
|
||||||
|
render_from_object: render_from_light,
|
||||||
|
},
|
||||||
|
medium: self.graphics_state.current_outside_medium.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
self.scene.add_light(entity);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn area_light_source(
|
fn area_light_source(
|
||||||
&mut self,
|
&mut self,
|
||||||
_name: &str,
|
name: &str,
|
||||||
_params: &ParsedParameterVector,
|
params: ParsedParameterVector,
|
||||||
_loc: FileLoc,
|
loc: FileLoc,
|
||||||
) -> Result<(), ParserError> {
|
) -> Result<(), ParserError> {
|
||||||
|
self.verify_world("AreaLightSource", &loc)?;
|
||||||
|
self.graphics_state.pending_area_light = Some(PendingAreaLight {
|
||||||
|
name: name.to_string(),
|
||||||
|
params: params.clone(),
|
||||||
|
loc,
|
||||||
|
});
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shape(
|
fn shape(
|
||||||
&mut self,
|
&mut self,
|
||||||
_name: &str,
|
name: &str,
|
||||||
_params: &ParsedParameterVector,
|
params: ParsedParameterVector,
|
||||||
_loc: FileLoc,
|
loc: FileLoc,
|
||||||
) -> Result<(), ParserError> {
|
) -> Result<(), ParserError> {
|
||||||
|
self.verify_world("Shape", &loc)?;
|
||||||
|
|
||||||
|
let dict = ParameterDictionary::from_array(
|
||||||
|
params.clone(),
|
||||||
|
&self.graphics_state.shape_attributes,
|
||||||
|
self.graphics_state.color_space.clone()
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let render_from_object = self.graphics_state.ctm[0];
|
||||||
|
let object_from_render = render_from_object.inverse();
|
||||||
|
|
||||||
|
let light_index = if let Some(ref al) = self.graphics_state.pending_area_light {
|
||||||
|
let al_dict = self.make_params(al.params.clone(), &al.loc)?;
|
||||||
|
let light_entity = SceneEntity {
|
||||||
|
name: al.name.clone(),
|
||||||
|
loc: al.loc.clone(),
|
||||||
|
parameters: al_dict
|
||||||
|
};
|
||||||
|
Some(self.scene.add_area_light(light_entity))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let material = if !self.graphics_state.current_material_name.is_empty() {
|
||||||
|
MaterialRef::Name(self.graphics_state.current_material_name.clone())
|
||||||
|
} else if let Some(idx) = self.graphics_state.current_material_index {
|
||||||
|
MaterialRef::Index(idx)
|
||||||
|
} else {
|
||||||
|
MaterialRef::None
|
||||||
|
};
|
||||||
|
|
||||||
|
let entity = ShapeSceneEntity {
|
||||||
|
base: SceneEntity {
|
||||||
|
name: name.to_string(),
|
||||||
|
loc,
|
||||||
|
parameters: dict
|
||||||
|
},
|
||||||
|
render_from_object: Arc::new(render_from_object),
|
||||||
|
object_from_render: Arc::new(object_from_render),
|
||||||
|
reverse_orientation: self.graphics_state.reverse_orientation,
|
||||||
|
material,
|
||||||
|
light_index,
|
||||||
|
inside_medium: self.graphics_state.current_inside_medium.clone(),
|
||||||
|
outside_medium: self.graphics_state.current_outside_medium.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
if self.active_instance_definition.is_some() {
|
||||||
|
self.active_instance_definition.as_mut().unwrap().shapes.push(entity)
|
||||||
|
} else {
|
||||||
|
self.scene.add_shape(entity);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn object_begin(&mut self, _name: &str, _loc: FileLoc) -> Result<(), ParserError> {
|
fn object_begin(&mut self, _name: &str, _loc: FileLoc) -> Result<(), ParserError> {
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ use crate::core::camera::CameraFactory;
|
||||||
use crate::core::film::FilmFactory;
|
use crate::core::film::FilmFactory;
|
||||||
use crate::core::filter::FilterFactory;
|
use crate::core::filter::FilterFactory;
|
||||||
use crate::core::image::{Image, io::ImageIO};
|
use crate::core::image::{Image, io::ImageIO};
|
||||||
|
use crate::core::light::LightFactory;
|
||||||
use crate::core::material::MaterialFactory;
|
use crate::core::material::MaterialFactory;
|
||||||
use crate::core::primitive::{CreateGeometricPrimitive, CreateSimplePrimitive};
|
use crate::core::primitive::{CreateGeometricPrimitive, CreateSimplePrimitive};
|
||||||
use crate::core::sampler::SamplerFactory;
|
use crate::core::sampler::SamplerFactory;
|
||||||
|
|
@ -16,7 +17,7 @@ use crate::{Arena, FileLoc};
|
||||||
use anyhow::{Result, anyhow};
|
use anyhow::{Result, anyhow};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use shared::core::camera::Camera;
|
use shared::core::camera::{CameraTransform, Camera};
|
||||||
use shared::core::color::LINEAR;
|
use shared::core::color::LINEAR;
|
||||||
use shared::core::film::Film;
|
use shared::core::film::Film;
|
||||||
use shared::core::filter::Filter;
|
use shared::core::filter::Filter;
|
||||||
|
|
@ -313,6 +314,14 @@ impl BasicScene {
|
||||||
state.area_lights.len() - 1
|
state.area_lights.len() - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_light(&self, light: LightSceneEntity) {
|
||||||
|
self.light_state.lock().lights.push(light);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_shape(&self, shape: ShapeSceneEntity) {
|
||||||
|
self.shapes.lock().push(shape);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn add_shapes(&self, new_shapes: Vec<ShapeSceneEntity>) {
|
pub fn add_shapes(&self, new_shapes: Vec<ShapeSceneEntity>) {
|
||||||
self.shapes.lock().extend(new_shapes);
|
self.shapes.lock().extend(new_shapes);
|
||||||
}
|
}
|
||||||
|
|
@ -489,6 +498,32 @@ impl BasicScene {
|
||||||
Ok((named_materials, materials))
|
Ok((named_materials, materials))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn create_lights(
|
||||||
|
&self,
|
||||||
|
camera_transform: &CameraTransform,
|
||||||
|
arena: &mut Arena,
|
||||||
|
) -> Result<Vec<Light>> {
|
||||||
|
let state = self.light_state.lock();
|
||||||
|
|
||||||
|
state.lights.par_iter().map(|entity| {
|
||||||
|
let render_from_light = entity.transformed_base.render_from_object.start_transform;
|
||||||
|
let medium = self.get_medium(
|
||||||
|
&entity.medium,
|
||||||
|
&entity.transformed_base.base.loc,
|
||||||
|
);
|
||||||
|
|
||||||
|
Light::create(
|
||||||
|
&entity.transformed_base.base.name,
|
||||||
|
&entity.transformed_base.base.parameters,
|
||||||
|
render_from_light,
|
||||||
|
camera_transform,
|
||||||
|
medium.map(|m| *m),
|
||||||
|
&entity.transformed_base.base.loc,
|
||||||
|
arena,
|
||||||
|
)
|
||||||
|
}).collect()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn create_aggregate(
|
pub fn create_aggregate(
|
||||||
&self,
|
&self,
|
||||||
textures: &NamedTextures,
|
textures: &NamedTextures,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use super::{SceneEntity, TextureSceneEntity};
|
use super::{SceneEntity, TextureSceneEntity, LightSceneEntity};
|
||||||
use crate::core::image::Image;
|
use crate::core::image::Image;
|
||||||
use crate::core::texture::{FloatTexture, SpectrumTexture};
|
use crate::core::texture::{FloatTexture, SpectrumTexture};
|
||||||
use crate::utils::parallel::AsyncJob;
|
use crate::utils::parallel::AsyncJob;
|
||||||
|
|
@ -29,7 +29,7 @@ pub struct MaterialState {
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct LightState {
|
pub struct LightState {
|
||||||
pub light_jobs: Vec<AsyncJob<Light>>,
|
pub lights: Vec<LightSceneEntity>,
|
||||||
pub area_lights: Vec<SceneEntity>,
|
pub area_lights: Vec<SceneEntity>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ use crate::utils::{Arena, FileLoc, ParameterDictionary, Upload, resolve_filename
|
||||||
use anyhow::{Result, anyhow};
|
use anyhow::{Result, anyhow};
|
||||||
use shared::core::geometry::Point2i;
|
use shared::core::geometry::Point2i;
|
||||||
use shared::core::light::{Light, LightBase, LightType};
|
use shared::core::light::{Light, LightBase, LightType};
|
||||||
use shared::core::medium::{Medium, MediumInterface};
|
use shared::core::medium::Medium;
|
||||||
use shared::core::shape::{Shape, ShapeTrait};
|
use shared::core::shape::{Shape, ShapeTrait};
|
||||||
use shared::core::spectrum::Spectrum;
|
use shared::core::spectrum::Spectrum;
|
||||||
use shared::core::texture::GPUFloatTexture;
|
use shared::core::texture::GPUFloatTexture;
|
||||||
|
|
@ -18,89 +18,6 @@ use shared::spectra::RGBColorSpace;
|
||||||
use shared::utils::{Ptr, Transform};
|
use shared::utils::{Ptr, Transform};
|
||||||
use shared::{Float, PI};
|
use shared::{Float, PI};
|
||||||
|
|
||||||
pub trait CreateDiffuseLight {
|
|
||||||
fn new(
|
|
||||||
render_from_light: Transform,
|
|
||||||
medium_interface: MediumInterface,
|
|
||||||
le: Spectrum,
|
|
||||||
scale: Float,
|
|
||||||
shape: Ptr<Shape>,
|
|
||||||
alpha: Ptr<GPUFloatTexture>,
|
|
||||||
image: Ptr<Image>,
|
|
||||||
colorspace: Ptr<RGBColorSpace>,
|
|
||||||
two_sided: bool,
|
|
||||||
) -> Self;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CreateDiffuseLight for DiffuseAreaLight {
|
|
||||||
fn new(
|
|
||||||
render_from_light: Transform,
|
|
||||||
medium_interface: MediumInterface,
|
|
||||||
le: Spectrum,
|
|
||||||
scale: Float,
|
|
||||||
shape: Ptr<Shape>,
|
|
||||||
alpha: Ptr<GPUFloatTexture>,
|
|
||||||
image: Ptr<Image>,
|
|
||||||
colorspace: Ptr<RGBColorSpace>,
|
|
||||||
two_sided: bool,
|
|
||||||
) -> Self {
|
|
||||||
let is_constant_zero = match &*alpha {
|
|
||||||
GPUFloatTexture::Constant(tex) => tex.evaluate(&TextureEvalContext::default()) == 0.0,
|
|
||||||
_ => false,
|
|
||||||
};
|
|
||||||
|
|
||||||
let (light_type, stored_alpha) = if is_constant_zero {
|
|
||||||
(LightType::DeltaPosition, None)
|
|
||||||
} else {
|
|
||||||
(LightType::Area, Some(alpha))
|
|
||||||
};
|
|
||||||
|
|
||||||
let base = LightBase::new(light_type, render_from_light, medium_interface);
|
|
||||||
|
|
||||||
let lemit = lookup_spectrum(&le);
|
|
||||||
|
|
||||||
if !image.is_null() {
|
|
||||||
let desc = image
|
|
||||||
.get_channel_desc(&["R", "G", "B"])
|
|
||||||
.expect("Image used for DiffuseAreaLight doesn't have R, G, B channels");
|
|
||||||
|
|
||||||
assert_eq!(3, desc.size(), "Image channel description size mismatch");
|
|
||||||
assert!(
|
|
||||||
desc.is_identity(),
|
|
||||||
"Image channel description is not identity"
|
|
||||||
);
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
!colorspace.is_null(),
|
|
||||||
"Image provided but ColorSpace is missing"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let is_triangle_or_bilinear =
|
|
||||||
matches!(*shape, Shape::Triangle(_) | Shape::BilinearPatch(_));
|
|
||||||
if render_from_light.has_scale(None) && !is_triangle_or_bilinear {
|
|
||||||
println!(
|
|
||||||
"Scaling detected in rendering to light space transformation! \
|
|
||||||
The system has numerous assumptions, implicit and explicit, \
|
|
||||||
that this transform will have no scale factors in it. \
|
|
||||||
Proceed at your own risk; your image may have errors."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Self {
|
|
||||||
base,
|
|
||||||
area: shape.area(),
|
|
||||||
image: Ptr::from(image.device()),
|
|
||||||
colorspace,
|
|
||||||
shape,
|
|
||||||
alpha: stored_alpha.expect("Could not retrieve texture"),
|
|
||||||
lemit: Ptr::from(&lemit.device()),
|
|
||||||
two_sided,
|
|
||||||
scale,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CreateLight for DiffuseAreaLight {
|
impl CreateLight for DiffuseAreaLight {
|
||||||
fn create(
|
fn create(
|
||||||
render_from_light: Transform,
|
render_from_light: Transform,
|
||||||
|
|
@ -186,17 +103,61 @@ impl CreateLight for DiffuseAreaLight {
|
||||||
scale *= phi_v / k_e;
|
scale *= phi_v / k_e;
|
||||||
}
|
}
|
||||||
|
|
||||||
let specific = DiffuseAreaLight::new(
|
let alpha_ptr = alpha.upload(arena);
|
||||||
render_from_light,
|
let is_constant_zero = match &*alpha_ptr {
|
||||||
medium.into(),
|
GPUFloatTexture::Constant(tex) => tex.evaluate(&TextureEvalContext::default()) == 0.0,
|
||||||
*l_for_scale,
|
_ => false,
|
||||||
|
};
|
||||||
|
|
||||||
|
let (light_type, stored_alpha) = if is_constant_zero {
|
||||||
|
(LightType::DeltaPosition, None)
|
||||||
|
} else {
|
||||||
|
(LightType::Area, Some(alpha))
|
||||||
|
};
|
||||||
|
|
||||||
|
let base = LightBase::new(light_type, render_from_light, medium.into());
|
||||||
|
if let Some(ref img) = image {
|
||||||
|
let desc = img
|
||||||
|
.get_channel_desc(&["R", "G", "B"])
|
||||||
|
.expect("Image used for DiffuseAreaLight doesn't have R, G, B channels");
|
||||||
|
assert_eq!(3, desc.size());
|
||||||
|
assert!(desc.is_identity());
|
||||||
|
assert!(
|
||||||
|
image_color_space.is_some(),
|
||||||
|
"Image provided but ColorSpace is missing"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let is_triangle_or_bilinear =
|
||||||
|
matches!(*shape, Shape::Triangle(_) | Shape::BilinearPatch(_));
|
||||||
|
if render_from_light.has_scale(None) && !is_triangle_or_bilinear {
|
||||||
|
println!(
|
||||||
|
"Scaling detected in rendering to light space transformation! \
|
||||||
|
Proceed at your own risk; your image may have errors."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let shape_ptr = shape.upload(arena);
|
||||||
|
let image_ptr = image
|
||||||
|
.as_ref()
|
||||||
|
.map(|img| arena.alloc(*img.device()))
|
||||||
|
.unwrap_or(Ptr::null());
|
||||||
|
let colorspace_ptr = image_color_space
|
||||||
|
.map(|cs| cs.upload(arena))
|
||||||
|
.unwrap_or(Ptr::null());
|
||||||
|
let lemit_ptr = arena.alloc(lookup_spectrum(l_for_scale).device());
|
||||||
|
|
||||||
|
let specific = DiffuseAreaLight {
|
||||||
|
base,
|
||||||
|
area: shape.area(),
|
||||||
|
shape: shape_ptr,
|
||||||
|
alpha: alpha_ptr,
|
||||||
|
image: image_ptr,
|
||||||
|
colorspace: colorspace_ptr,
|
||||||
|
lemit: lemit_ptr,
|
||||||
|
two_sided,
|
||||||
scale,
|
scale,
|
||||||
shape.upload(arena),
|
};
|
||||||
alpha.upload(arena),
|
|
||||||
Ptr::from(&image.unwrap()),
|
|
||||||
image_color_space.upload(arena),
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(Light::DiffuseArea(specific))
|
Ok(Light::DiffuseArea(specific))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,11 @@ use crate::core::light::{CreateLight, lookup_spectrum};
|
||||||
use crate::core::spectrum::spectrum_to_photometric;
|
use crate::core::spectrum::spectrum_to_photometric;
|
||||||
use crate::core::texture::FloatTexture;
|
use crate::core::texture::FloatTexture;
|
||||||
use crate::utils::sampling::PiecewiseConstant2D;
|
use crate::utils::sampling::PiecewiseConstant2D;
|
||||||
use crate::utils::{Arena, FileLoc, ParameterDictionary, resolve_filename};
|
use crate::utils::{Arena, FileLoc, ParameterDictionary, Upload, resolve_filename};
|
||||||
use anyhow::{Result, anyhow};
|
use anyhow::{Result, anyhow};
|
||||||
use shared::core::geometry::Point2i;
|
use shared::core::geometry::Point2i;
|
||||||
use shared::core::light::{Light, LightBase, LightType};
|
use shared::core::light::{Light, LightBase, LightType};
|
||||||
use shared::core::medium::{Medium, MediumInterface};
|
use shared::core::medium::Medium;
|
||||||
use shared::core::shape::Shape;
|
use shared::core::shape::Shape;
|
||||||
use shared::core::spectrum::Spectrum;
|
use shared::core::spectrum::Spectrum;
|
||||||
use shared::core::texture::SpectrumType;
|
use shared::core::texture::SpectrumType;
|
||||||
|
|
@ -18,42 +18,6 @@ use shared::spectra::RGBColorSpace;
|
||||||
use shared::utils::{Ptr, Transform};
|
use shared::utils::{Ptr, Transform};
|
||||||
use shared::{Float, PI};
|
use shared::{Float, PI};
|
||||||
|
|
||||||
pub trait CreateGoniometricLight {
|
|
||||||
fn new(
|
|
||||||
render_from_light: Transform,
|
|
||||||
medium_interface: MediumInterface,
|
|
||||||
le: Spectrum,
|
|
||||||
scale: Float,
|
|
||||||
image: Ptr<Image>,
|
|
||||||
) -> Self;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CreateGoniometricLight for GoniometricLight {
|
|
||||||
fn new(
|
|
||||||
render_from_light: Transform,
|
|
||||||
medium_interface: MediumInterface,
|
|
||||||
le: Spectrum,
|
|
||||||
scale: Float,
|
|
||||||
image: Ptr<Image>,
|
|
||||||
) -> Self {
|
|
||||||
let base = LightBase::new(
|
|
||||||
LightType::DeltaPosition,
|
|
||||||
render_from_light,
|
|
||||||
medium_interface,
|
|
||||||
);
|
|
||||||
|
|
||||||
let iemit = lookup_spectrum(&le);
|
|
||||||
let distrib = PiecewiseConstant2D::from_image(&image);
|
|
||||||
Self {
|
|
||||||
base,
|
|
||||||
iemit: Ptr::from(&iemit.device()),
|
|
||||||
scale,
|
|
||||||
image: Ptr::from(image.device()),
|
|
||||||
distrib: Ptr::from(&distrib.device),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CreateLight for GoniometricLight {
|
impl CreateLight for GoniometricLight {
|
||||||
fn create(
|
fn create(
|
||||||
render_from_light: Transform,
|
render_from_light: Transform,
|
||||||
|
|
@ -63,7 +27,7 @@ impl CreateLight for GoniometricLight {
|
||||||
_shape: &Shape,
|
_shape: &Shape,
|
||||||
_alpha_text: &FloatTexture,
|
_alpha_text: &FloatTexture,
|
||||||
colorspace: Option<&RGBColorSpace>,
|
colorspace: Option<&RGBColorSpace>,
|
||||||
_arena: &Arena,
|
arena: &Arena,
|
||||||
) -> Result<Light> {
|
) -> Result<Light> {
|
||||||
let i = params
|
let i = params
|
||||||
.get_one_spectrum(
|
.get_one_spectrum(
|
||||||
|
|
@ -116,8 +80,30 @@ impl CreateLight for GoniometricLight {
|
||||||
.expect("Could not create transform for GoniometricLight");
|
.expect("Could not create transform for GoniometricLight");
|
||||||
let final_render_from_light = render_from_light * t;
|
let final_render_from_light = render_from_light * t;
|
||||||
|
|
||||||
let specific =
|
let base = LightBase::new(
|
||||||
GoniometricLight::new(final_render_from_light, medium.into(), i, scale, image);
|
LightType::DeltaPosition,
|
||||||
|
final_render_from_light,
|
||||||
|
medium.into(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let iemit = lookup_spectrum(&i);
|
||||||
|
|
||||||
|
let image_ptr = if !image.is_null() {
|
||||||
|
let distrib = PiecewiseConstant2D::from_image(&image);
|
||||||
|
let distrib_ptr = distrib.upload(arena);
|
||||||
|
let img_ptr = image.upload(arena);
|
||||||
|
(img_ptr, distrib_ptr)
|
||||||
|
} else {
|
||||||
|
(Ptr::null(), Ptr::null())
|
||||||
|
};
|
||||||
|
|
||||||
|
let specific = GoniometricLight {
|
||||||
|
base,
|
||||||
|
iemit: arena.alloc(iemit.device()),
|
||||||
|
scale,
|
||||||
|
image: image_ptr.0,
|
||||||
|
distrib: image_ptr.1,
|
||||||
|
};
|
||||||
|
|
||||||
Ok(Light::Goniometric(specific))
|
Ok(Light::Goniometric(specific))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,9 @@ pub mod projection;
|
||||||
pub mod sampler;
|
pub mod sampler;
|
||||||
pub mod spot;
|
pub mod spot;
|
||||||
|
|
||||||
pub use diffuse::CreateDiffuseLight;
|
|
||||||
pub use distant::CreateDistantLight;
|
pub use distant::CreateDistantLight;
|
||||||
pub use goniometric::CreateGoniometricLight;
|
|
||||||
pub use infinite::{
|
pub use infinite::{
|
||||||
CreateImageInfiniteLight, CreatePortalInfiniteLight, CreateUniformInfiniteLight,
|
CreateImageInfiniteLight, CreatePortalInfiniteLight, CreateUniformInfiniteLight,
|
||||||
};
|
};
|
||||||
pub use point::CreatePointLight;
|
pub use point::CreatePointLight;
|
||||||
pub use projection::CreateProjectionLight;
|
|
||||||
pub use spot::CreateSpotLight;
|
pub use spot::CreateSpotLight;
|
||||||
|
|
|
||||||
|
|
@ -10,88 +10,14 @@ use shared::core::geometry::{
|
||||||
Bounds2f, Point2f, Point2i, Point3f, Vector3f, VectorLike, cos_theta,
|
Bounds2f, Point2f, Point2i, Point3f, Vector3f, VectorLike, cos_theta,
|
||||||
};
|
};
|
||||||
use shared::core::light::{Light, LightBase, LightType};
|
use shared::core::light::{Light, LightBase, LightType};
|
||||||
use shared::core::medium::{Medium, MediumInterface};
|
use shared::core::medium::Medium;
|
||||||
use shared::core::shape::Shape;
|
use shared::core::shape::Shape;
|
||||||
use shared::core::spectrum::Spectrum;
|
use shared::core::spectrum::Spectrum;
|
||||||
use shared::lights::ProjectionLight;
|
use shared::lights::ProjectionLight;
|
||||||
use shared::spectra::RGBColorSpace;
|
use shared::spectra::RGBColorSpace;
|
||||||
|
use shared::utils::Transform;
|
||||||
use shared::utils::math::{radians, square};
|
use shared::utils::math::{radians, square};
|
||||||
use shared::utils::{Ptr, Transform};
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
pub trait CreateProjectionLight {
|
|
||||||
fn new(
|
|
||||||
render_from_light: Transform,
|
|
||||||
medium_interface: MediumInterface,
|
|
||||||
scale: Float,
|
|
||||||
image: Arc<Image>,
|
|
||||||
image_color_space: Ptr<RGBColorSpace>,
|
|
||||||
fov: Float,
|
|
||||||
) -> Self;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CreateProjectionLight for ProjectionLight {
|
|
||||||
fn new(
|
|
||||||
render_from_light: Transform,
|
|
||||||
medium_interface: MediumInterface,
|
|
||||||
scale: Float,
|
|
||||||
image: Arc<Image>,
|
|
||||||
image_color_space: Ptr<RGBColorSpace>,
|
|
||||||
fov: Float,
|
|
||||||
) -> Self {
|
|
||||||
let base = LightBase::new(
|
|
||||||
LightType::DeltaPosition,
|
|
||||||
render_from_light,
|
|
||||||
medium_interface,
|
|
||||||
);
|
|
||||||
|
|
||||||
let opposite = (radians(fov) / 2.0).tan();
|
|
||||||
let res = image.resolution();
|
|
||||||
let aspect = res.x() as Float / res.y() as Float;
|
|
||||||
let aspect_ratio = if aspect > 1.0 { aspect } else { 1.0 / aspect };
|
|
||||||
let a = 4.0 * square(opposite) * aspect_ratio;
|
|
||||||
let screen_bounds = if aspect > 1.0 {
|
|
||||||
Bounds2f::from_points(Point2f::new(-aspect, -1.0), Point2f::new(aspect, 1.0))
|
|
||||||
} else {
|
|
||||||
Bounds2f::from_points(
|
|
||||||
Point2f::new(-1.0, -1.0 / aspect),
|
|
||||||
Point2f::new(1.0, 1.0 / aspect),
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
let hither = 1e-3;
|
|
||||||
let screen_from_light = Transform::perspective(fov, hither, 1e30).unwrap();
|
|
||||||
let light_from_screen = screen_from_light.inverse();
|
|
||||||
|
|
||||||
let dwda = |p: Point2f| {
|
|
||||||
let w =
|
|
||||||
Vector3f::from(light_from_screen.apply_to_point(Point3f::new(p.x(), p.y(), 0.0)));
|
|
||||||
cos_theta(w.normalize()).powi(3)
|
|
||||||
};
|
|
||||||
|
|
||||||
let d = image.get_sampling_distribution(dwda, screen_bounds);
|
|
||||||
let distrib = PiecewiseConstant2D::from_slice(
|
|
||||||
d.as_slice(),
|
|
||||||
d.x_size() as usize,
|
|
||||||
d.y_size() as usize,
|
|
||||||
screen_bounds,
|
|
||||||
);
|
|
||||||
|
|
||||||
Self {
|
|
||||||
base,
|
|
||||||
image: Ptr::from(image.device()),
|
|
||||||
image_color_space,
|
|
||||||
distrib: Ptr::from(&distrib.device),
|
|
||||||
screen_bounds,
|
|
||||||
screen_from_light,
|
|
||||||
light_from_screen,
|
|
||||||
scale,
|
|
||||||
hither,
|
|
||||||
a,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CreateLight for ProjectionLight {
|
impl CreateLight for ProjectionLight {
|
||||||
fn create(
|
fn create(
|
||||||
|
|
@ -155,15 +81,53 @@ impl CreateLight for ProjectionLight {
|
||||||
let flip = Transform::scale(1., -1., 1.);
|
let flip = Transform::scale(1., -1., 1.);
|
||||||
let render_from_light_flip = render_from_light * flip;
|
let render_from_light_flip = render_from_light * flip;
|
||||||
|
|
||||||
let specific = ProjectionLight::new(
|
let base = LightBase::new(LightType::DeltaPosition, render_from_light, medium.into());
|
||||||
render_from_light_flip,
|
|
||||||
medium.into(),
|
let opposite = (radians(fov) / 2.0).tan();
|
||||||
scale,
|
let res = image.resolution();
|
||||||
Arc::new(image),
|
let aspect = res.x() as Float / res.y() as Float;
|
||||||
colorspace.upload(arena),
|
let aspect_ratio = if aspect > 1.0 { aspect } else { 1.0 / aspect };
|
||||||
fov,
|
let a = 4.0 * square(opposite) * aspect_ratio;
|
||||||
|
let screen_bounds = if aspect > 1.0 {
|
||||||
|
Bounds2f::from_points(Point2f::new(-aspect, -1.0), Point2f::new(aspect, 1.0))
|
||||||
|
} else {
|
||||||
|
Bounds2f::from_points(
|
||||||
|
Point2f::new(-1.0, -1.0 / aspect),
|
||||||
|
Point2f::new(1.0, 1.0 / aspect),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
let hither = 1e-3;
|
||||||
|
let screen_from_light = Transform::perspective(fov, hither, 1e30).unwrap();
|
||||||
|
let light_from_screen = screen_from_light.inverse();
|
||||||
|
|
||||||
|
let dwda = |p: Point2f| {
|
||||||
|
let w =
|
||||||
|
Vector3f::from(light_from_screen.apply_to_point(Point3f::new(p.x(), p.y(), 0.0)));
|
||||||
|
cos_theta(w.normalize()).powi(3)
|
||||||
|
};
|
||||||
|
|
||||||
|
let d = image.get_sampling_distribution(dwda, screen_bounds);
|
||||||
|
let distrib = PiecewiseConstant2D::from_slice(
|
||||||
|
d.as_slice(),
|
||||||
|
d.x_size() as usize,
|
||||||
|
d.y_size() as usize,
|
||||||
|
screen_bounds,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let specific = ProjectionLight {
|
||||||
|
base,
|
||||||
|
image: image.upload(arena),
|
||||||
|
image_color_space: colorspace.upload(arena),
|
||||||
|
distrib: distrib.upload(arena),
|
||||||
|
screen_bounds,
|
||||||
|
screen_from_light,
|
||||||
|
light_from_screen,
|
||||||
|
scale,
|
||||||
|
hither,
|
||||||
|
a,
|
||||||
|
};
|
||||||
|
|
||||||
Ok(Light::Projection(specific))
|
Ok(Light::Projection(specific))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ impl CreateShape for TriangleShape {
|
||||||
if vertex_indices.is_empty() {
|
if vertex_indices.is_empty() {
|
||||||
if p.len() == 3 {
|
if p.len() == 3 {
|
||||||
} else {
|
} else {
|
||||||
return bail!("Vertex indices \"indices\" must be provided with triangle mesh.");
|
bail!("Vertex indices \"indices\" must be provided with triangle mesh.");
|
||||||
}
|
}
|
||||||
} else if vertex_indices.len() % 3 != 0 {
|
} else if vertex_indices.len() % 3 != 0 {
|
||||||
let excess = vertex_indices.len() % 3;
|
let excess = vertex_indices.len() % 3;
|
||||||
|
|
@ -43,7 +43,7 @@ impl CreateShape for TriangleShape {
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.is_empty() {
|
if p.is_empty() {
|
||||||
return bail!("Vertex positions \"P\" must be provided with triangle mesh.");
|
bail!("Vertex positions \"P\" must be provided with triangle mesh.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if !uvs.is_empty() && uvs.len() != p.len() {
|
if !uvs.is_empty() && uvs.len() != p.len() {
|
||||||
|
|
@ -64,7 +64,7 @@ impl CreateShape for TriangleShape {
|
||||||
for (_, &index) in vertex_indices.iter().enumerate() {
|
for (_, &index) in vertex_indices.iter().enumerate() {
|
||||||
// Check for negative indices (if keeping i32) or out of bounds
|
// Check for negative indices (if keeping i32) or out of bounds
|
||||||
if index < 0 || index as usize >= p.len() {
|
if index < 0 || index as usize >= p.len() {
|
||||||
return bail!(
|
bail!(
|
||||||
"TriangleMesh has out-of-bounds vertex index {} ({} \"P\" values were given). Discarding this mesh.",
|
"TriangleMesh has out-of-bounds vertex index {} ({} \"P\" values were given). Discarding this mesh.",
|
||||||
index,
|
index,
|
||||||
p.len()
|
p.len()
|
||||||
|
|
|
||||||
|
|
@ -138,7 +138,7 @@ pub mod vulkan {
|
||||||
fn inner() -> &'static VulkanAllocatorInner {
|
fn inner() -> &'static VulkanAllocatorInner {
|
||||||
VK_ALLOCATOR
|
VK_ALLOCATOR
|
||||||
.get()
|
.get()
|
||||||
.expect("Vulkan not initialized — call init_vulkan() before Arena::default()")
|
.expect("Vulkan not initialized — call init_vulkan() before arena creation")
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for VulkanAllocator {
|
impl Default for VulkanAllocator {
|
||||||
|
|
|
||||||
|
|
@ -66,37 +66,37 @@ pub trait ParserTarget {
|
||||||
fn pixel_filter(
|
fn pixel_filter(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
params: &ParsedParameterVector,
|
params: ParsedParameterVector,
|
||||||
loc: FileLoc,
|
loc: FileLoc,
|
||||||
) -> Result<(), ParserError>;
|
) -> Result<(), ParserError>;
|
||||||
fn film(
|
fn film(
|
||||||
&mut self,
|
&mut self,
|
||||||
type_name: &str,
|
type_name: &str,
|
||||||
params: &ParsedParameterVector,
|
params: ParsedParameterVector,
|
||||||
loc: FileLoc,
|
loc: FileLoc,
|
||||||
) -> Result<(), ParserError>;
|
) -> Result<(), ParserError>;
|
||||||
fn accelerator(
|
fn accelerator(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
params: &ParsedParameterVector,
|
params: ParsedParameterVector,
|
||||||
loc: FileLoc,
|
loc: FileLoc,
|
||||||
) -> Result<(), ParserError>;
|
) -> Result<(), ParserError>;
|
||||||
fn integrator(
|
fn integrator(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
params: &ParsedParameterVector,
|
params: ParsedParameterVector,
|
||||||
loc: FileLoc,
|
loc: FileLoc,
|
||||||
) -> Result<(), ParserError>;
|
) -> Result<(), ParserError>;
|
||||||
fn camera(
|
fn camera(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
params: &ParsedParameterVector,
|
params: ParsedParameterVector,
|
||||||
loc: FileLoc,
|
loc: FileLoc,
|
||||||
) -> Result<(), ParserError>;
|
) -> Result<(), ParserError>;
|
||||||
fn make_named_medium(
|
fn make_named_medium(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
params: &ParsedParameterVector,
|
params: ParsedParameterVector,
|
||||||
loc: FileLoc,
|
loc: FileLoc,
|
||||||
) -> Result<(), ParserError>;
|
) -> Result<(), ParserError>;
|
||||||
fn medium_interface(
|
fn medium_interface(
|
||||||
|
|
@ -108,7 +108,7 @@ pub trait ParserTarget {
|
||||||
fn sampler(
|
fn sampler(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
params: &ParsedParameterVector,
|
params: ParsedParameterVector,
|
||||||
loc: FileLoc,
|
loc: FileLoc,
|
||||||
) -> Result<(), ParserError>;
|
) -> Result<(), ParserError>;
|
||||||
|
|
||||||
|
|
@ -127,20 +127,20 @@ pub trait ParserTarget {
|
||||||
name: &str,
|
name: &str,
|
||||||
type_name: &str,
|
type_name: &str,
|
||||||
tex_name: &str,
|
tex_name: &str,
|
||||||
params: &ParsedParameterVector,
|
params: ParsedParameterVector,
|
||||||
loc: FileLoc,
|
loc: FileLoc,
|
||||||
arena: Arc<Arena>,
|
arena: Arc<Arena>,
|
||||||
) -> Result<(), ParserError>;
|
) -> Result<(), ParserError>;
|
||||||
fn material(
|
fn material(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
params: &ParsedParameterVector,
|
params: ParsedParameterVector,
|
||||||
loc: FileLoc,
|
loc: FileLoc,
|
||||||
) -> Result<(), ParserError>;
|
) -> Result<(), ParserError>;
|
||||||
fn make_named_material(
|
fn make_named_material(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
params: &ParsedParameterVector,
|
params: ParsedParameterVector,
|
||||||
loc: FileLoc,
|
loc: FileLoc,
|
||||||
) -> Result<(), ParserError>;
|
) -> Result<(), ParserError>;
|
||||||
fn named_material(&mut self, name: &str, loc: FileLoc) -> Result<(), ParserError>;
|
fn named_material(&mut self, name: &str, loc: FileLoc) -> Result<(), ParserError>;
|
||||||
|
|
@ -148,20 +148,20 @@ pub trait ParserTarget {
|
||||||
fn light_source(
|
fn light_source(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
params: &ParsedParameterVector,
|
params: ParsedParameterVector,
|
||||||
loc: FileLoc,
|
loc: FileLoc,
|
||||||
) -> Result<(), ParserError>;
|
) -> Result<(), ParserError>;
|
||||||
fn area_light_source(
|
fn area_light_source(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
params: &ParsedParameterVector,
|
params: ParsedParameterVector,
|
||||||
loc: FileLoc,
|
loc: FileLoc,
|
||||||
) -> Result<(), ParserError>;
|
) -> Result<(), ParserError>;
|
||||||
|
|
||||||
fn shape(
|
fn shape(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
params: &ParsedParameterVector,
|
params: ParsedParameterVector,
|
||||||
loc: FileLoc,
|
loc: FileLoc,
|
||||||
) -> Result<(), ParserError>;
|
) -> Result<(), ParserError>;
|
||||||
fn reverse_orientation(&mut self, loc: FileLoc) -> Result<(), ParserError>;
|
fn reverse_orientation(&mut self, loc: FileLoc) -> Result<(), ParserError>;
|
||||||
|
|
@ -594,7 +594,7 @@ impl ParserTarget for FormattingParserTarget {
|
||||||
fn shape(
|
fn shape(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
params: &ParsedParameterVector,
|
params: ParsedParameterVector,
|
||||||
_loc: FileLoc,
|
_loc: FileLoc,
|
||||||
) -> Result<(), ParserError> {
|
) -> Result<(), ParserError> {
|
||||||
println!(
|
println!(
|
||||||
|
|
@ -609,7 +609,7 @@ impl ParserTarget for FormattingParserTarget {
|
||||||
fn material(
|
fn material(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
params: &ParsedParameterVector,
|
params: ParsedParameterVector,
|
||||||
_loc: FileLoc,
|
_loc: FileLoc,
|
||||||
) -> Result<(), ParserError> {
|
) -> Result<(), ParserError> {
|
||||||
println!(
|
println!(
|
||||||
|
|
@ -626,7 +626,7 @@ impl ParserTarget for FormattingParserTarget {
|
||||||
name: &str,
|
name: &str,
|
||||||
type_name: &str,
|
type_name: &str,
|
||||||
tex_name: &str,
|
tex_name: &str,
|
||||||
_params: &ParsedParameterVector,
|
_params: ParsedParameterVector,
|
||||||
_loc: FileLoc,
|
_loc: FileLoc,
|
||||||
_arena: Arc<Arena>,
|
_arena: Arc<Arena>,
|
||||||
) -> Result<(), ParserError> {
|
) -> Result<(), ParserError> {
|
||||||
|
|
@ -658,7 +658,7 @@ impl ParserTarget for FormattingParserTarget {
|
||||||
fn pixel_filter(
|
fn pixel_filter(
|
||||||
&mut self,
|
&mut self,
|
||||||
_n: &str,
|
_n: &str,
|
||||||
_p: &ParsedParameterVector,
|
_p: ParsedParameterVector,
|
||||||
_loc: FileLoc,
|
_loc: FileLoc,
|
||||||
) -> Result<(), ParserError> {
|
) -> Result<(), ParserError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -666,7 +666,7 @@ impl ParserTarget for FormattingParserTarget {
|
||||||
fn film(
|
fn film(
|
||||||
&mut self,
|
&mut self,
|
||||||
_t: &str,
|
_t: &str,
|
||||||
_p: &ParsedParameterVector,
|
_p: ParsedParameterVector,
|
||||||
_loc: FileLoc,
|
_loc: FileLoc,
|
||||||
) -> Result<(), ParserError> {
|
) -> Result<(), ParserError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -674,7 +674,7 @@ impl ParserTarget for FormattingParserTarget {
|
||||||
fn accelerator(
|
fn accelerator(
|
||||||
&mut self,
|
&mut self,
|
||||||
_n: &str,
|
_n: &str,
|
||||||
_p: &ParsedParameterVector,
|
_p: ParsedParameterVector,
|
||||||
_loc: FileLoc,
|
_loc: FileLoc,
|
||||||
) -> Result<(), ParserError> {
|
) -> Result<(), ParserError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -682,7 +682,7 @@ impl ParserTarget for FormattingParserTarget {
|
||||||
fn integrator(
|
fn integrator(
|
||||||
&mut self,
|
&mut self,
|
||||||
_n: &str,
|
_n: &str,
|
||||||
_p: &ParsedParameterVector,
|
_p: ParsedParameterVector,
|
||||||
_loc: FileLoc,
|
_loc: FileLoc,
|
||||||
) -> Result<(), ParserError> {
|
) -> Result<(), ParserError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -690,7 +690,7 @@ impl ParserTarget for FormattingParserTarget {
|
||||||
fn camera(
|
fn camera(
|
||||||
&mut self,
|
&mut self,
|
||||||
_n: &str,
|
_n: &str,
|
||||||
_p: &ParsedParameterVector,
|
_p: ParsedParameterVector,
|
||||||
_loc: FileLoc,
|
_loc: FileLoc,
|
||||||
) -> Result<(), ParserError> {
|
) -> Result<(), ParserError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -698,7 +698,7 @@ impl ParserTarget for FormattingParserTarget {
|
||||||
fn make_named_medium(
|
fn make_named_medium(
|
||||||
&mut self,
|
&mut self,
|
||||||
_n: &str,
|
_n: &str,
|
||||||
_p: &ParsedParameterVector,
|
_p: ParsedParameterVector,
|
||||||
_loc: FileLoc,
|
_loc: FileLoc,
|
||||||
) -> Result<(), ParserError> {
|
) -> Result<(), ParserError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -709,7 +709,7 @@ impl ParserTarget for FormattingParserTarget {
|
||||||
fn sampler(
|
fn sampler(
|
||||||
&mut self,
|
&mut self,
|
||||||
_n: &str,
|
_n: &str,
|
||||||
_p: &ParsedParameterVector,
|
_p: ParsedParameterVector,
|
||||||
_loc: FileLoc,
|
_loc: FileLoc,
|
||||||
) -> Result<(), ParserError> {
|
) -> Result<(), ParserError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -725,7 +725,7 @@ impl ParserTarget for FormattingParserTarget {
|
||||||
fn make_named_material(
|
fn make_named_material(
|
||||||
&mut self,
|
&mut self,
|
||||||
_n: &str,
|
_n: &str,
|
||||||
_p: &ParsedParameterVector,
|
_p: ParsedParameterVector,
|
||||||
_loc: FileLoc,
|
_loc: FileLoc,
|
||||||
) -> Result<(), ParserError> {
|
) -> Result<(), ParserError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -736,7 +736,7 @@ impl ParserTarget for FormattingParserTarget {
|
||||||
fn light_source(
|
fn light_source(
|
||||||
&mut self,
|
&mut self,
|
||||||
_n: &str,
|
_n: &str,
|
||||||
_p: &ParsedParameterVector,
|
_p: ParsedParameterVector,
|
||||||
_loc: FileLoc,
|
_loc: FileLoc,
|
||||||
) -> Result<(), ParserError> {
|
) -> Result<(), ParserError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -744,7 +744,7 @@ impl ParserTarget for FormattingParserTarget {
|
||||||
fn area_light_source(
|
fn area_light_source(
|
||||||
&mut self,
|
&mut self,
|
||||||
_n: &str,
|
_n: &str,
|
||||||
_p: &ParsedParameterVector,
|
_p: ParsedParameterVector,
|
||||||
_loc: FileLoc,
|
_loc: FileLoc,
|
||||||
) -> Result<(), ParserError> {
|
) -> Result<(), ParserError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -1093,7 +1093,7 @@ impl<'a> SceneParser<'a> {
|
||||||
.collect::<Result<_, _>>()?;
|
.collect::<Result<_, _>>()?;
|
||||||
self.target.look_at(
|
self.target.look_at(
|
||||||
v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8], token.loc,
|
v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8], token.loc,
|
||||||
);
|
)?;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(ParserError::Generic(
|
return Err(ParserError::Generic(
|
||||||
|
|
@ -1186,7 +1186,7 @@ impl<'a> SceneParser<'a> {
|
||||||
let ax = self.expect_float()?;
|
let ax = self.expect_float()?;
|
||||||
let ay = self.expect_float()?;
|
let ay = self.expect_float()?;
|
||||||
let az = self.expect_float()?;
|
let az = self.expect_float()?;
|
||||||
self.target.rotate(angle, ax, ay, az, token.loc);
|
self.target.rotate(angle, ax, ay, az, token.loc)?;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(ParserError::Generic(
|
return Err(ParserError::Generic(
|
||||||
|
|
@ -1203,7 +1203,7 @@ impl<'a> SceneParser<'a> {
|
||||||
let x = self.expect_float()?;
|
let x = self.expect_float()?;
|
||||||
let y = self.expect_float()?;
|
let y = self.expect_float()?;
|
||||||
let z = self.expect_float()?;
|
let z = self.expect_float()?;
|
||||||
self.target.scale(x, y, z, token.loc);
|
self.target.scale(x, y, z, token.loc)?;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(ParserError::Generic(
|
return Err(ParserError::Generic(
|
||||||
|
|
@ -1245,7 +1245,7 @@ impl<'a> SceneParser<'a> {
|
||||||
&name,
|
&name,
|
||||||
&type_name,
|
&type_name,
|
||||||
&tex_name,
|
&tex_name,
|
||||||
¶ms,
|
params,
|
||||||
token.loc,
|
token.loc,
|
||||||
arena.clone(),
|
arena.clone(),
|
||||||
)?;
|
)?;
|
||||||
|
|
@ -1310,7 +1310,7 @@ impl<'a> SceneParser<'a> {
|
||||||
F: FnMut(
|
F: FnMut(
|
||||||
&mut dyn ParserTarget,
|
&mut dyn ParserTarget,
|
||||||
&str,
|
&str,
|
||||||
&ParsedParameterVector,
|
ParsedParameterVector,
|
||||||
FileLoc,
|
FileLoc,
|
||||||
) -> Result<(), ParserError>,
|
) -> Result<(), ParserError>,
|
||||||
{
|
{
|
||||||
|
|
@ -1322,6 +1322,6 @@ impl<'a> SceneParser<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let params = self.parse_parameters()?;
|
let params = self.parse_parameters()?;
|
||||||
func(self.target, &type_name, ¶ms, type_token.loc)
|
func(self.target, &type_name, params, type_token.loc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue