Add light as associated type for scene and get something to draw with pbrt materials.
This commit is contained in:
parent
b54a2b16fe
commit
bb2089477e
13 changed files with 286 additions and 87 deletions
|
|
@ -7,8 +7,9 @@ use material::PbrtMaterial;
|
|||
use miette::{IntoDiagnostic, Result, bail, miette};
|
||||
use ray_tracing_core::{
|
||||
affine_transform::AffineTransform,
|
||||
color::Color,
|
||||
math::{Dir3, Pos3},
|
||||
prelude::Float,
|
||||
prelude::{Float, Rng},
|
||||
};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
|
|
@ -66,7 +67,7 @@ struct PbrtCamera {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Statement {
|
||||
enum Statement<R> {
|
||||
AttributeBegin,
|
||||
AttributeEnd,
|
||||
WorldBegin,
|
||||
|
|
@ -79,12 +80,12 @@ enum Statement {
|
|||
Unknown(String, Vec<Token>),
|
||||
Transform(AffineTransform),
|
||||
Texture(String, Arc<dyn PbrtTexture>),
|
||||
Material(Arc<dyn PbrtMaterial>),
|
||||
MakeNamedMaterial(String, Arc<dyn PbrtMaterial>),
|
||||
Material(Arc<dyn PbrtMaterial<R>>),
|
||||
MakeNamedMaterial(String, Arc<dyn PbrtMaterial<R>>),
|
||||
NamedMaterial(String),
|
||||
}
|
||||
|
||||
fn parse_look_at(iter: &mut Tokenizer) -> Result<Statement> {
|
||||
fn parse_look_at<R>(iter: &mut Tokenizer) -> Result<Statement<R>> {
|
||||
let eye = Pos3::new(iter.parse_next()?, iter.parse_next()?, iter.parse_next()?);
|
||||
let look_at = Pos3::new(iter.parse_next()?, iter.parse_next()?, iter.parse_next()?);
|
||||
let up = Dir3::new(iter.parse_next()?, iter.parse_next()?, iter.parse_next()?);
|
||||
|
|
@ -95,7 +96,7 @@ fn parse_look_at(iter: &mut Tokenizer) -> Result<Statement> {
|
|||
))
|
||||
}
|
||||
|
||||
fn parse_shape(iter: &mut Tokenizer) -> Result<Statement> {
|
||||
fn parse_shape<R>(iter: &mut Tokenizer) -> Result<Statement<R>> {
|
||||
let shape_type = iter
|
||||
.next_if_string_value()
|
||||
.ok_or(miette!("unable to get shape type"))??;
|
||||
|
|
@ -312,7 +313,7 @@ fn parse_shape(iter: &mut Tokenizer) -> Result<Statement> {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_camera(tokenizer: &mut Tokenizer) -> Result<Statement> {
|
||||
fn parse_camera<R>(tokenizer: &mut Tokenizer) -> Result<Statement<R>> {
|
||||
let camera_type = tokenizer
|
||||
.next_if_string_value()
|
||||
.ok_or(miette!("unable to get shape type"))??;
|
||||
|
|
@ -382,7 +383,7 @@ fn parse_camera(tokenizer: &mut Tokenizer) -> Result<Statement> {
|
|||
}
|
||||
|
||||
impl Lexer {
|
||||
fn next(&mut self, context: &PbrtContext) -> Option<Result<Statement>> {
|
||||
fn next<R: Rng>(&mut self, context: &PbrtContext<R>) -> Option<Result<Statement<R>>> {
|
||||
match self.input.next() {
|
||||
Some(Ok(Token::Identifier(s))) => match s.as_str() {
|
||||
"AttributeBegin" => Some(Ok(Statement::AttributeBegin)),
|
||||
|
|
@ -481,7 +482,7 @@ fn parse_transform(input: &mut Tokenizer) -> Result<AffineTransform> {
|
|||
.ok_or(miette!("Unable to invert transformation"))
|
||||
}
|
||||
|
||||
fn parse_translate(iter: &mut Tokenizer) -> Result<Statement> {
|
||||
fn parse_translate<R>(iter: &mut Tokenizer) -> Result<Statement<R>> {
|
||||
let pos = Pos3::new(iter.parse_next()?, iter.parse_next()?, iter.parse_next()?);
|
||||
|
||||
Ok(Statement::ConcatTransform(AffineTransform::translation(
|
||||
|
|
@ -489,7 +490,7 @@ fn parse_translate(iter: &mut Tokenizer) -> Result<Statement> {
|
|||
)))
|
||||
}
|
||||
|
||||
fn parse_scale(iter: &mut Tokenizer) -> Result<Statement> {
|
||||
fn parse_scale<R>(iter: &mut Tokenizer) -> Result<Statement<R>> {
|
||||
Ok(Statement::ConcatTransform(AffineTransform::scale(
|
||||
iter.parse_next()?,
|
||||
iter.parse_next()?,
|
||||
|
|
@ -497,7 +498,7 @@ fn parse_scale(iter: &mut Tokenizer) -> Result<Statement> {
|
|||
)))
|
||||
}
|
||||
|
||||
fn parse_rotate(iter: &mut Tokenizer) -> Result<Statement> {
|
||||
fn parse_rotate<R>(iter: &mut Tokenizer) -> Result<Statement<R>> {
|
||||
let angle = iter.parse_parameter()?;
|
||||
let dir = Dir3::new(
|
||||
iter.parse_parameter()?,
|
||||
|
|
@ -557,7 +558,7 @@ impl Parser {
|
|||
}
|
||||
|
||||
impl Parser {
|
||||
fn next(&mut self, context: &PbrtContext) -> Option<Result<Statement>> {
|
||||
fn next<R: Rng>(&mut self, context: &PbrtContext<R>) -> Option<Result<Statement<R>>> {
|
||||
if let Some(iter) = &mut self.inner {
|
||||
if let Some(statement) = iter.next(context) {
|
||||
return Some(statement);
|
||||
|
|
@ -579,16 +580,21 @@ impl Parser {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Pbrt {
|
||||
pub struct Pbrt<R: Rng> {
|
||||
pub settings: PbrtWorldSettings,
|
||||
pub scene: PbrtScene,
|
||||
pub scene: PbrtScene<R>,
|
||||
}
|
||||
|
||||
impl Pbrt {
|
||||
impl<R: Rng> Pbrt<R> {
|
||||
fn new(settings: PbrtWorldSettings) -> Self {
|
||||
Self {
|
||||
settings,
|
||||
scene: PbrtScene { shapes: Vec::new() },
|
||||
scene: PbrtScene {
|
||||
shapes: Vec::new(),
|
||||
infinite_light: Some(scene::PbrtInfiniteLight {
|
||||
color: Color::white(),
|
||||
}),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -601,14 +607,14 @@ pub struct PbrtWorldSettings {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PbrtContext {
|
||||
pub struct PbrtContext<R> {
|
||||
ctm: Vec<AffineTransform>,
|
||||
textures: HashMap<String, Arc<dyn PbrtTexture>>,
|
||||
material: Vec<Arc<dyn PbrtMaterial>>,
|
||||
materials: HashMap<String, Arc<dyn PbrtMaterial>>,
|
||||
material: Vec<Arc<dyn PbrtMaterial<R>>>,
|
||||
materials: HashMap<String, Arc<dyn PbrtMaterial<R>>>,
|
||||
}
|
||||
|
||||
impl PbrtContext {
|
||||
impl<R> PbrtContext<R> {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
ctm: vec![AffineTransform::identity()],
|
||||
|
|
@ -626,11 +632,11 @@ impl PbrtContext {
|
|||
self.textures.get(name)
|
||||
}
|
||||
|
||||
pub fn get_named_material(&self, name: &String) -> Option<&Arc<dyn PbrtMaterial>> {
|
||||
pub fn get_named_material(&self, name: &String) -> Option<&Arc<dyn PbrtMaterial<R>>> {
|
||||
self.materials.get(name)
|
||||
}
|
||||
|
||||
pub fn get_material(&self) -> Option<&Arc<dyn PbrtMaterial>> {
|
||||
pub fn get_material(&self) -> Option<&Arc<dyn PbrtMaterial<R>>> {
|
||||
self.material.last()
|
||||
}
|
||||
|
||||
|
|
@ -656,7 +662,9 @@ impl PbrtContext {
|
|||
}
|
||||
}
|
||||
|
||||
fn inner_parse_pbrt(path: impl AsRef<Path> + std::fmt::Debug) -> Result<Pbrt> {
|
||||
fn inner_parse_pbrt<R: Rng + std::fmt::Debug>(
|
||||
path: impl AsRef<Path> + std::fmt::Debug,
|
||||
) -> Result<Pbrt<R>> {
|
||||
// unwrap on context.last() ok because context is never empty
|
||||
let mut context = PbrtContext::new();
|
||||
|
||||
|
|
@ -792,6 +800,8 @@ fn inner_parse_pbrt(path: impl AsRef<Path> + std::fmt::Debug) -> Result<Pbrt> {
|
|||
Ok(pbrt)
|
||||
}
|
||||
|
||||
pub fn parse_pbrt_v4(path: impl AsRef<Path> + std::fmt::Debug) -> Result<Pbrt> {
|
||||
pub fn parse_pbrt_v4<R: Rng + std::fmt::Debug>(
|
||||
path: impl AsRef<Path> + std::fmt::Debug,
|
||||
) -> Result<Pbrt<R>> {
|
||||
inner_parse_pbrt(path)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue