Lazily committing a bunch of stuff.
Includes: - More scene parsing code. Making good progress! - Making the rendering code actually use the Scene and Assembly types. - Bare beginnings of a Tracer type.
This commit is contained in:
parent
38d33ed144
commit
e96798ab6b
|
@ -2,7 +2,8 @@ use std::collections::HashMap;
|
||||||
|
|
||||||
use math::Matrix4x4;
|
use math::Matrix4x4;
|
||||||
use bvh::BVH;
|
use bvh::BVH;
|
||||||
use surface::Surface;
|
use surface::{Surface, SurfaceIntersection};
|
||||||
|
use ray::Ray;
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -23,6 +24,38 @@ pub struct Assembly {
|
||||||
object_accel: BVH,
|
object_accel: BVH,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Assembly {
|
||||||
|
pub fn new() -> Assembly {
|
||||||
|
Assembly {
|
||||||
|
instances: Vec::new(),
|
||||||
|
xforms: Vec::new(),
|
||||||
|
objects: Vec::new(),
|
||||||
|
object_map: HashMap::new(),
|
||||||
|
assemblies: Vec::new(),
|
||||||
|
assembly_map: HashMap::new(),
|
||||||
|
object_accel: BVH::new_empty(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: this is just temporary. Remove this and move tracing functionality
|
||||||
|
// into the tracer.
|
||||||
|
pub fn intersect_rays(&self, rays: &mut [Ray], isects: &mut [SurfaceIntersection]) {
|
||||||
|
for obj in self.objects.iter() {
|
||||||
|
match obj {
|
||||||
|
&Object::Surface(ref surface) => {
|
||||||
|
surface.intersect_rays(rays, isects);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn add_object(&mut self, name: &str, obj: Object) {
|
||||||
|
self.object_map.insert(name.to_string(), self.objects.len());
|
||||||
|
self.objects.push(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Object {
|
pub enum Object {
|
||||||
|
|
14
src/bvh.rs
14
src/bvh.rs
|
@ -28,15 +28,19 @@ enum BVHNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BVH {
|
impl BVH {
|
||||||
pub fn from_objects<'a, T, F>(objects: &mut [T], objects_per_leaf: usize, bounder: F) -> BVH
|
pub fn new_empty() -> BVH {
|
||||||
where F: 'a + Fn(&T) -> &'a [BBox]
|
BVH {
|
||||||
{
|
|
||||||
let mut bvh = BVH {
|
|
||||||
nodes: Vec::new(),
|
nodes: Vec::new(),
|
||||||
bounds: Vec::new(),
|
bounds: Vec::new(),
|
||||||
depth: 0,
|
depth: 0,
|
||||||
bounds_cache: Vec::new(),
|
bounds_cache: Vec::new(),
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_objects<'a, T, F>(objects: &mut [T], objects_per_leaf: usize, bounder: F) -> BVH
|
||||||
|
where F: 'a + Fn(&T) -> &'a [BBox]
|
||||||
|
{
|
||||||
|
let mut bvh = BVH::new_empty();
|
||||||
|
|
||||||
bvh.recursive_build(0, 0, objects_per_leaf, objects, &bounder);
|
bvh.recursive_build(0, 0, objects_per_leaf, objects, &bounder);
|
||||||
bvh.bounds_cache.clear();
|
bvh.bounds_cache.clear();
|
||||||
|
|
16
src/main.rs
16
src/main.rs
|
@ -12,6 +12,7 @@ mod bbox;
|
||||||
mod camera;
|
mod camera;
|
||||||
mod parse;
|
mod parse;
|
||||||
mod renderer;
|
mod renderer;
|
||||||
|
mod tracer;
|
||||||
mod image;
|
mod image;
|
||||||
mod triangle;
|
mod triangle;
|
||||||
mod surface;
|
mod surface;
|
||||||
|
@ -30,6 +31,8 @@ use docopt::Docopt;
|
||||||
use math::{Point, Matrix4x4};
|
use math::{Point, Matrix4x4};
|
||||||
use ray::Ray;
|
use ray::Ray;
|
||||||
use camera::Camera;
|
use camera::Camera;
|
||||||
|
use scene::Scene;
|
||||||
|
use assembly::{Assembly, Object};
|
||||||
use renderer::Renderer;
|
use renderer::Renderer;
|
||||||
use surface::triangle_mesh::TriangleMesh;
|
use surface::triangle_mesh::TriangleMesh;
|
||||||
use parse::DataTree;
|
use parse::DataTree;
|
||||||
|
@ -128,12 +131,21 @@ fn main() {
|
||||||
vec![20.0],
|
vec![20.0],
|
||||||
vec![1026.0]);
|
vec![1026.0]);
|
||||||
|
|
||||||
|
let mut assembly = Assembly::new();
|
||||||
|
assembly.add_object("yar", Object::Surface(Box::new(mesh)));
|
||||||
|
|
||||||
|
let scene = Scene {
|
||||||
|
name: None,
|
||||||
|
background_color: (0.0, 0.0, 0.0),
|
||||||
|
camera: cam,
|
||||||
|
root: assembly,
|
||||||
|
};
|
||||||
|
|
||||||
let r = Renderer {
|
let r = Renderer {
|
||||||
output_file: args.arg_imgpath.clone(),
|
output_file: args.arg_imgpath.clone(),
|
||||||
resolution: (512, 512),
|
resolution: (512, 512),
|
||||||
spp: samples_per_pixel as usize,
|
spp: samples_per_pixel as usize,
|
||||||
camera: cam,
|
scene: scene,
|
||||||
scene: mesh,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
r.render();
|
r.render();
|
||||||
|
|
|
@ -42,6 +42,34 @@ impl<'a> DataTree<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn type_name(&'a self) -> &'a str {
|
||||||
|
match self {
|
||||||
|
&DataTree::Internal{type_name, ..} => type_name,
|
||||||
|
&DataTree::Leaf{type_name, ..} => type_name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_internal(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
&DataTree::Internal{..} => true,
|
||||||
|
&DataTree::Leaf{..} => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_leaf(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
&DataTree::Internal{..} => false,
|
||||||
|
&DataTree::Leaf{..} => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn leaf_contents(&'a self) -> Option<&'a str> {
|
||||||
|
match self {
|
||||||
|
&DataTree::Internal{..} => None,
|
||||||
|
&DataTree::Leaf{contents, ..} => Some(contents),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_first_child_with_type_name(&'a self, type_name: &str) -> Option<&'a DataTree> {
|
pub fn get_first_child_with_type_name(&'a self, type_name: &str) -> Option<&'a DataTree> {
|
||||||
if let &DataTree::Internal { ref children, .. } = self {
|
if let &DataTree::Internal { ref children, .. } = self {
|
||||||
for child in children.iter() {
|
for child in children.iter() {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
mod data_tree;
|
mod data_tree;
|
||||||
mod psy;
|
mod psy;
|
||||||
|
mod psy_assembly;
|
||||||
pub mod basics;
|
pub mod basics;
|
||||||
|
|
||||||
pub use self::data_tree::DataTree;
|
pub use self::data_tree::DataTree;
|
||||||
|
|
252
src/parse/psy.rs
252
src/parse/psy.rs
|
@ -5,9 +5,16 @@ use std::result::Result;
|
||||||
use nom;
|
use nom;
|
||||||
use nom::IResult;
|
use nom::IResult;
|
||||||
|
|
||||||
use renderer::Renderer;
|
|
||||||
use super::DataTree;
|
use super::DataTree;
|
||||||
use super::basics::ws_u32;
|
use super::basics::{ws_u32, ws_f32};
|
||||||
|
use super::psy_assembly::parse_assembly;
|
||||||
|
|
||||||
|
use math::Matrix4x4;
|
||||||
|
use camera::Camera;
|
||||||
|
use renderer::Renderer;
|
||||||
|
use scene::Scene;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// Takes in a DataTree representing a Scene node and returns
|
/// Takes in a DataTree representing a Scene node and returns
|
||||||
|
@ -31,8 +38,59 @@ pub fn parse_frame(tree: &DataTree) -> Result<Renderer, ()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse output info
|
// Parse output info
|
||||||
let output_info = if let &DataTree::Internal{ref children, ..} =
|
let output_info = try!(parse_output_info(tree.get_first_child_with_type_name("Output")
|
||||||
tree.get_first_child_with_type_name("Output").unwrap() {
|
.unwrap()));
|
||||||
|
|
||||||
|
// Parse render settings
|
||||||
|
let render_settings = try!(parse_render_settings(tree.get_first_child_with_type_name("Rende\
|
||||||
|
rSett\
|
||||||
|
ings")
|
||||||
|
.unwrap()));
|
||||||
|
|
||||||
|
// Parse camera
|
||||||
|
let camera = try!(parse_camera(tree.get_first_child_with_type_name("Camera").unwrap()));
|
||||||
|
|
||||||
|
// Parse world
|
||||||
|
let world = try!(parse_world(tree.get_first_child_with_type_name("World").unwrap()));
|
||||||
|
|
||||||
|
// Parse root scene assembly
|
||||||
|
let assembly = try!(parse_assembly(tree.get_first_child_with_type_name("Assembly").unwrap()));
|
||||||
|
|
||||||
|
// Put scene together
|
||||||
|
let scene_name = if let &DataTree::Internal{ident, ..} = tree {
|
||||||
|
if let Some(name) = ident {
|
||||||
|
Some(name.to_string())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
let scene = Scene {
|
||||||
|
name: scene_name,
|
||||||
|
background_color: world,
|
||||||
|
camera: camera,
|
||||||
|
root: assembly,
|
||||||
|
};
|
||||||
|
|
||||||
|
// // Put renderer together
|
||||||
|
// let renderer = Renderer {
|
||||||
|
// output_file: output_info.0.clone(),
|
||||||
|
// resolution: (render_settings.0.0 as usize, render_settings.0.1 as usize),
|
||||||
|
// spp: render_settings.1,
|
||||||
|
// scene: scene,
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return Ok(renderer);
|
||||||
|
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fn parse_output_info(tree: &DataTree) -> Result<(String), ()> {
|
||||||
|
if let &DataTree::Internal{ref children, ..} = tree {
|
||||||
let mut found_path = false;
|
let mut found_path = false;
|
||||||
let mut path = String::new();
|
let mut path = String::new();
|
||||||
|
|
||||||
|
@ -44,37 +102,25 @@ pub fn parse_frame(tree: &DataTree) -> Result<Renderer, ()> {
|
||||||
path = contents.to_string();
|
path = contents.to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
&DataTree::Leaf { type_name, contents } if type_name == "FileFormat" => {
|
|
||||||
// TODO
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
&DataTree::Leaf { type_name, contents } if type_name == "ColorSpace" => {
|
|
||||||
// TODO
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
&DataTree::Leaf { type_name, contents } if type_name == "Dither" => {
|
|
||||||
// TODO
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if found_path {
|
if found_path {
|
||||||
(path)
|
return Ok((path));
|
||||||
} else {
|
} else {
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(());
|
return Err(());
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Parse render settings
|
|
||||||
let render_settings = if let &DataTree::Internal{ref children, ..} =
|
|
||||||
tree.get_first_child_with_type_name("RenderSettings").unwrap() {
|
|
||||||
|
fn parse_render_settings(tree: &DataTree) -> Result<((u32, u32), u32, u32), ()> {
|
||||||
|
if let &DataTree::Internal{ref children, ..} = tree {
|
||||||
let mut found_res = false;
|
let mut found_res = false;
|
||||||
let mut found_spp = false;
|
let mut found_spp = false;
|
||||||
let mut res = (0, 0);
|
let mut res = (0, 0);
|
||||||
|
@ -95,6 +141,7 @@ pub fn parse_frame(tree: &DataTree) -> Result<Renderer, ()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SamplesPerPixel
|
||||||
&DataTree::Leaf { type_name, contents } if type_name == "SamplesPerPixel" => {
|
&DataTree::Leaf { type_name, contents } if type_name == "SamplesPerPixel" => {
|
||||||
if let IResult::Done(_, n) = ws_u32(contents.as_bytes()) {
|
if let IResult::Done(_, n) = ws_u32(contents.as_bytes()) {
|
||||||
found_spp = true;
|
found_spp = true;
|
||||||
|
@ -105,6 +152,7 @@ pub fn parse_frame(tree: &DataTree) -> Result<Renderer, ()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Seed
|
||||||
&DataTree::Leaf { type_name, contents } if type_name == "Seed" => {
|
&DataTree::Leaf { type_name, contents } if type_name == "Seed" => {
|
||||||
if let IResult::Done(_, n) = ws_u32(contents.as_bytes()) {
|
if let IResult::Done(_, n) = ws_u32(contents.as_bytes()) {
|
||||||
seed = n;
|
seed = n;
|
||||||
|
@ -119,19 +167,169 @@ pub fn parse_frame(tree: &DataTree) -> Result<Renderer, ()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if found_res && found_spp {
|
if found_res && found_spp {
|
||||||
(res, spp)
|
return Ok((res, spp, seed));
|
||||||
} else {
|
} else {
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(());
|
return Err(());
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Parse camera
|
|
||||||
|
|
||||||
// Parse world
|
|
||||||
|
|
||||||
// Parse root scene assembly
|
|
||||||
|
|
||||||
|
fn parse_camera(tree: &DataTree) -> Result<Camera, ()> {
|
||||||
|
if let &DataTree::Internal{ref children, ..} = tree {
|
||||||
|
let mut mats = Vec::new();
|
||||||
|
let mut fovs = Vec::new();
|
||||||
|
let mut focus_distances = Vec::new();
|
||||||
|
let mut aperture_radii = Vec::new();
|
||||||
|
|
||||||
|
// Parse
|
||||||
|
for child in children.iter() {
|
||||||
|
match child {
|
||||||
|
// Fov
|
||||||
|
&DataTree::Leaf { type_name, contents } if type_name == "Fov" => {
|
||||||
|
if let IResult::Done(_, fov) = ws_f32(contents.as_bytes()) {
|
||||||
|
fovs.push(fov * (3.1415926536 / 180.0));
|
||||||
|
} else {
|
||||||
|
// Found Fov, but its contents is not in the right format
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FocalDistance
|
||||||
|
&DataTree::Leaf { type_name, contents } if type_name == "FocalDistance" => {
|
||||||
|
if let IResult::Done(_, fd) = ws_f32(contents.as_bytes()) {
|
||||||
|
focus_distances.push(fd);
|
||||||
|
} else {
|
||||||
|
// Found FocalDistance, but its contents is not in the right format
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ApertureRadius
|
||||||
|
&DataTree::Leaf { type_name, contents } if type_name == "ApertureRadius" => {
|
||||||
|
if let IResult::Done(_, ar) = ws_f32(contents.as_bytes()) {
|
||||||
|
aperture_radii.push(ar);
|
||||||
|
} else {
|
||||||
|
// Found ApertureRadius, but its contents is not in the right format
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transform
|
||||||
|
&DataTree::Leaf { type_name, contents } if type_name == "Transform" => {
|
||||||
|
if let Ok(mat) = parse_matrix(contents) {
|
||||||
|
mats.push(mat);
|
||||||
|
} else {
|
||||||
|
// Found Transform, but its contents is not in the right format
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(Camera::new(mats, fovs, aperture_radii, focus_distances));
|
||||||
|
} else {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fn parse_world(tree: &DataTree) -> Result<(f32, f32, f32), ()> {
|
||||||
|
if tree.is_internal() {
|
||||||
|
let mut found_background_color = false;
|
||||||
|
let mut background_color = (0.0, 0.0, 0.0);
|
||||||
|
|
||||||
|
// Parse background shader
|
||||||
|
let bgs = {
|
||||||
|
if tree.count_children_with_type_name("BackgroundShader") != 1 {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
tree.get_first_child_with_type_name("BackgroundShader").unwrap()
|
||||||
|
};
|
||||||
|
let bgs_type = {
|
||||||
|
if bgs.count_children_with_type_name("Type") != 1 {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
if let &DataTree::Leaf{contents, ..} = tree.get_first_child_with_type_name("Type")
|
||||||
|
.unwrap() {
|
||||||
|
contents.trim()
|
||||||
|
} else {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
match bgs_type {
|
||||||
|
"Color" => {
|
||||||
|
if let Some(&DataTree::Leaf{contents, ..}) =
|
||||||
|
bgs.get_first_child_with_type_name("Color") {
|
||||||
|
if let IResult::Done(_, color) = closure!(tuple!(ws_f32,
|
||||||
|
ws_f32,
|
||||||
|
ws_f32))(contents.trim()
|
||||||
|
.as_bytes()) {
|
||||||
|
found_background_color = true;
|
||||||
|
background_color = color;
|
||||||
|
} else {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => return Err(()),
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(background_color);
|
||||||
|
} else {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fn parse_matrix(contents: &str) -> Result<Matrix4x4, ()> {
|
||||||
|
if let IResult::Done(_, ns) = closure!(terminated!(tuple!(ws_f32,
|
||||||
|
ws_f32,
|
||||||
|
ws_f32,
|
||||||
|
ws_f32,
|
||||||
|
ws_f32,
|
||||||
|
ws_f32,
|
||||||
|
ws_f32,
|
||||||
|
ws_f32,
|
||||||
|
ws_f32,
|
||||||
|
ws_f32,
|
||||||
|
ws_f32,
|
||||||
|
ws_f32,
|
||||||
|
ws_f32,
|
||||||
|
ws_f32,
|
||||||
|
ws_f32,
|
||||||
|
ws_f32),
|
||||||
|
nom::eof))(contents.as_bytes()) {
|
||||||
|
return Ok(Matrix4x4::new_from_values(ns.0,
|
||||||
|
ns.1,
|
||||||
|
ns.2,
|
||||||
|
ns.3,
|
||||||
|
ns.4,
|
||||||
|
ns.5,
|
||||||
|
ns.6,
|
||||||
|
ns.7,
|
||||||
|
ns.8,
|
||||||
|
ns.9,
|
||||||
|
ns.10,
|
||||||
|
ns.11,
|
||||||
|
ns.12,
|
||||||
|
ns.13,
|
||||||
|
ns.14,
|
||||||
|
ns.15));
|
||||||
|
} else {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
18
src/parse/psy_assembly.rs
Normal file
18
src/parse/psy_assembly.rs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
use std::result::Result;
|
||||||
|
|
||||||
|
use nom;
|
||||||
|
use nom::IResult;
|
||||||
|
|
||||||
|
use super::DataTree;
|
||||||
|
use super::basics::{ws_u32, ws_f32};
|
||||||
|
|
||||||
|
use math::Matrix4x4;
|
||||||
|
use camera::Camera;
|
||||||
|
use renderer::Renderer;
|
||||||
|
use assembly::Assembly;
|
||||||
|
|
||||||
|
pub fn parse_assembly(tree: &DataTree) -> Result<Assembly, ()> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
|
@ -10,12 +10,12 @@ use surface;
|
||||||
use surface::Surface;
|
use surface::Surface;
|
||||||
use scene::Scene;
|
use scene::Scene;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Renderer {
|
pub struct Renderer {
|
||||||
pub output_file: String,
|
pub output_file: String,
|
||||||
pub resolution: (usize, usize),
|
pub resolution: (usize, usize),
|
||||||
pub spp: usize,
|
pub spp: usize,
|
||||||
pub camera: Camera,
|
pub scene: Scene,
|
||||||
pub scene: surface::triangle_mesh::TriangleMesh,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Renderer {
|
impl Renderer {
|
||||||
|
@ -39,7 +39,7 @@ impl Renderer {
|
||||||
let mut ray = {
|
let mut ray = {
|
||||||
let filter_x = fast_logit(halton::sample(3, offset + si as u32), 1.5);
|
let filter_x = fast_logit(halton::sample(3, offset + si as u32), 1.5);
|
||||||
let filter_y = fast_logit(halton::sample(4, offset + si as u32), 1.5);
|
let filter_y = fast_logit(halton::sample(4, offset + si as u32), 1.5);
|
||||||
self.camera.generate_ray((x as f32 + filter_x) * cmpx - 0.5,
|
self.scene.camera.generate_ray((x as f32 + filter_x) * cmpx - 0.5,
|
||||||
(y as f32 + filter_y) * cmpy - 0.5,
|
(y as f32 + filter_y) * cmpy - 0.5,
|
||||||
halton::sample(0, offset + si as u32),
|
halton::sample(0, offset + si as u32),
|
||||||
halton::sample(1, offset + si as u32),
|
halton::sample(1, offset + si as u32),
|
||||||
|
@ -51,7 +51,7 @@ impl Renderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test rays against scene
|
// Test rays against scene
|
||||||
self.scene.intersect_rays(&mut rays, &mut isects);
|
self.scene.root.intersect_rays(&mut rays, &mut isects);
|
||||||
|
|
||||||
// Calculate color based on ray hits
|
// Calculate color based on ray hits
|
||||||
let mut r = 0.0;
|
let mut r = 0.0;
|
||||||
|
|
|
@ -4,8 +4,8 @@ use assembly::Assembly;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Scene {
|
pub struct Scene {
|
||||||
name: String,
|
pub name: Option<String>,
|
||||||
background_color: (f32, f32, f32),
|
pub background_color: (f32, f32, f32),
|
||||||
camera: Camera,
|
pub camera: Camera,
|
||||||
root: Assembly,
|
pub root: Assembly,
|
||||||
}
|
}
|
||||||
|
|
10
src/tracer.rs
Normal file
10
src/tracer.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
use math::Matrix4x4;
|
||||||
|
use ray::Ray;
|
||||||
|
use surface::SurfaceIntersection;
|
||||||
|
|
||||||
|
pub struct Tracer<'a> {
|
||||||
|
xform_stack: Vec<Matrix4x4>,
|
||||||
|
world_rays: &'a [Ray],
|
||||||
|
intersections: &'a mut [SurfaceIntersection],
|
||||||
|
rays: Vec<Ray>,
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user