Moved ray tracing responsibilities to the Tracer.
This is still pretty WIP, but it at least gets the functionality back to where it was before.
This commit is contained in:
parent
e96798ab6b
commit
f6891173eb
|
@ -9,19 +9,19 @@ use ray::Ray;
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Assembly {
|
pub struct Assembly {
|
||||||
// Instance list
|
// Instance list
|
||||||
instances: Vec<Instance>,
|
pub instances: Vec<Instance>,
|
||||||
xforms: Vec<Matrix4x4>,
|
pub xforms: Vec<Matrix4x4>,
|
||||||
|
|
||||||
// Object list
|
// Object list
|
||||||
objects: Vec<Object>,
|
pub objects: Vec<Object>,
|
||||||
object_map: HashMap<String, usize>, // map Name -> Index
|
object_map: HashMap<String, usize>, // map Name -> Index
|
||||||
|
|
||||||
// Assembly list
|
// Assembly list
|
||||||
assemblies: Vec<Assembly>,
|
pub assemblies: Vec<Assembly>,
|
||||||
assembly_map: HashMap<String, usize>, // map Name -> Index
|
assembly_map: HashMap<String, usize>, // map Name -> Index
|
||||||
|
|
||||||
// Object accel
|
// Object accel
|
||||||
object_accel: BVH,
|
pub object_accel: BVH,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Assembly {
|
impl Assembly {
|
||||||
|
@ -37,17 +37,6 @@ impl Assembly {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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) {
|
pub fn add_object(&mut self, name: &str, obj: Object) {
|
||||||
|
@ -64,7 +53,7 @@ pub enum Object {
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
enum Instance {
|
pub enum Instance {
|
||||||
Object {
|
Object {
|
||||||
data_index: usize,
|
data_index: usize,
|
||||||
transform_indices: (usize, usize),
|
transform_indices: (usize, usize),
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
|
use tracer::Tracer;
|
||||||
use camera::Camera;
|
use camera::Camera;
|
||||||
use halton;
|
use halton;
|
||||||
use math::fast_logit;
|
use math::fast_logit;
|
||||||
|
@ -21,7 +22,7 @@ pub struct Renderer {
|
||||||
impl Renderer {
|
impl Renderer {
|
||||||
pub fn render(&self) {
|
pub fn render(&self) {
|
||||||
let mut rays = Vec::new();
|
let mut rays = Vec::new();
|
||||||
let mut isects = Vec::new();
|
let mut tracer = Tracer::from_assembly(&self.scene.root);
|
||||||
let mut img = Image::new(self.resolution.0, self.resolution.1);
|
let mut img = Image::new(self.resolution.0, self.resolution.1);
|
||||||
|
|
||||||
// Render image of ray-traced triangle
|
// Render image of ray-traced triangle
|
||||||
|
@ -34,7 +35,6 @@ impl Renderer {
|
||||||
|
|
||||||
// Generate rays
|
// Generate rays
|
||||||
rays.clear();
|
rays.clear();
|
||||||
isects.clear();
|
|
||||||
for si in 0..self.spp {
|
for si in 0..self.spp {
|
||||||
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);
|
||||||
|
@ -47,11 +47,10 @@ impl Renderer {
|
||||||
};
|
};
|
||||||
ray.id = si as u32;
|
ray.id = si as u32;
|
||||||
rays.push(ray);
|
rays.push(ray);
|
||||||
isects.push(surface::SurfaceIntersection::Miss);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test rays against scene
|
// Test rays against scene
|
||||||
self.scene.root.intersect_rays(&mut rays, &mut isects);
|
let isects = tracer.trace(&rays);
|
||||||
|
|
||||||
// Calculate color based on ray hits
|
// Calculate color based on ray hits
|
||||||
let mut r = 0.0;
|
let mut r = 0.0;
|
||||||
|
|
|
@ -8,7 +8,7 @@ use ray::Ray;
|
||||||
use math::{Point, Normal, Matrix4x4};
|
use math::{Point, Normal, Matrix4x4};
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum SurfaceIntersection {
|
pub enum SurfaceIntersection {
|
||||||
Miss,
|
Miss,
|
||||||
Occlude,
|
Occlude,
|
||||||
|
|
|
@ -1,10 +1,63 @@
|
||||||
|
use std::iter;
|
||||||
|
use std::slice;
|
||||||
|
|
||||||
use math::Matrix4x4;
|
use math::Matrix4x4;
|
||||||
|
use assembly::{Assembly, Object};
|
||||||
use ray::Ray;
|
use ray::Ray;
|
||||||
use surface::SurfaceIntersection;
|
use surface::SurfaceIntersection;
|
||||||
|
|
||||||
pub struct Tracer<'a> {
|
pub struct Tracer<'a> {
|
||||||
|
root: &'a Assembly,
|
||||||
|
rays: Vec<Ray>, // Should only be used from trace(), not any other methods
|
||||||
xform_stack: Vec<Matrix4x4>,
|
xform_stack: Vec<Matrix4x4>,
|
||||||
world_rays: &'a [Ray],
|
isects: Vec<SurfaceIntersection>,
|
||||||
intersections: &'a mut [SurfaceIntersection],
|
}
|
||||||
rays: Vec<Ray>,
|
|
||||||
|
impl<'a> Tracer<'a> {
|
||||||
|
pub fn from_assembly(assembly: &'a Assembly) -> Tracer<'a> {
|
||||||
|
Tracer {
|
||||||
|
root: assembly,
|
||||||
|
xform_stack: Vec::new(),
|
||||||
|
rays: Vec::new(),
|
||||||
|
isects: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn trace<'b>(&'b mut self, wrays: &[Ray]) -> &'b [SurfaceIntersection] {
|
||||||
|
// Ready the rays
|
||||||
|
self.rays.clear();
|
||||||
|
self.rays.reserve(wrays.len());
|
||||||
|
self.rays.extend(wrays.iter());
|
||||||
|
|
||||||
|
// Ready the isects
|
||||||
|
self.isects.clear();
|
||||||
|
self.isects.reserve(wrays.len());
|
||||||
|
self.isects.extend(iter::repeat(SurfaceIntersection::Miss).take(wrays.len()));
|
||||||
|
|
||||||
|
// Start tracing
|
||||||
|
let ray_refs = unsafe {
|
||||||
|
// IMPORTANT NOTE:
|
||||||
|
// We're creating an unsafe non-lifetime-bound slice of self.rays
|
||||||
|
// here so that we can pass it to trace_assembly() without
|
||||||
|
// conflicting with self.
|
||||||
|
// Because of this, it is absolutely CRITICAL that self.rays
|
||||||
|
// NOT be used in any other methods. The rays should only be
|
||||||
|
// accessed in other methods via the mutable slice passed directly
|
||||||
|
// to them in their function parameters.
|
||||||
|
slice::from_raw_parts_mut(self.rays.as_mut_ptr(), self.rays.len())
|
||||||
|
};
|
||||||
|
self.trace_assembly(self.root, wrays, ray_refs);
|
||||||
|
|
||||||
|
return &self.isects;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn trace_assembly<'b>(&'b mut self, assembly: &Assembly, wrays: &[Ray], rays: &mut [Ray]) {
|
||||||
|
for obj in assembly.objects.iter() {
|
||||||
|
match obj {
|
||||||
|
&Object::Surface(ref surface) => {
|
||||||
|
surface.intersect_rays(rays, &mut self.isects);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user