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)]
|
||||
pub struct Assembly {
|
||||
// Instance list
|
||||
instances: Vec<Instance>,
|
||||
xforms: Vec<Matrix4x4>,
|
||||
pub instances: Vec<Instance>,
|
||||
pub xforms: Vec<Matrix4x4>,
|
||||
|
||||
// Object list
|
||||
objects: Vec<Object>,
|
||||
pub objects: Vec<Object>,
|
||||
object_map: HashMap<String, usize>, // map Name -> Index
|
||||
|
||||
// Assembly list
|
||||
assemblies: Vec<Assembly>,
|
||||
pub assemblies: Vec<Assembly>,
|
||||
assembly_map: HashMap<String, usize>, // map Name -> Index
|
||||
|
||||
// Object accel
|
||||
object_accel: BVH,
|
||||
pub object_accel: BVH,
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -64,7 +53,7 @@ pub enum Object {
|
|||
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
enum Instance {
|
||||
pub enum Instance {
|
||||
Object {
|
||||
data_index: usize,
|
||||
transform_indices: (usize, usize),
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
use std::path::Path;
|
||||
|
||||
use tracer::Tracer;
|
||||
use camera::Camera;
|
||||
use halton;
|
||||
use math::fast_logit;
|
||||
|
@ -21,7 +22,7 @@ pub struct Renderer {
|
|||
impl Renderer {
|
||||
pub fn render(&self) {
|
||||
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);
|
||||
|
||||
// Render image of ray-traced triangle
|
||||
|
@ -34,7 +35,6 @@ impl Renderer {
|
|||
|
||||
// Generate rays
|
||||
rays.clear();
|
||||
isects.clear();
|
||||
for si in 0..self.spp {
|
||||
let mut ray = {
|
||||
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;
|
||||
rays.push(ray);
|
||||
isects.push(surface::SurfaceIntersection::Miss);
|
||||
}
|
||||
|
||||
// Test rays against scene
|
||||
self.scene.root.intersect_rays(&mut rays, &mut isects);
|
||||
let isects = tracer.trace(&rays);
|
||||
|
||||
// Calculate color based on ray hits
|
||||
let mut r = 0.0;
|
||||
|
|
|
@ -8,7 +8,7 @@ use ray::Ray;
|
|||
use math::{Point, Normal, Matrix4x4};
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum SurfaceIntersection {
|
||||
Miss,
|
||||
Occlude,
|
||||
|
|
|
@ -1,10 +1,63 @@
|
|||
use std::iter;
|
||||
use std::slice;
|
||||
|
||||
use math::Matrix4x4;
|
||||
use assembly::{Assembly, Object};
|
||||
use ray::Ray;
|
||||
use surface::SurfaceIntersection;
|
||||
|
||||
pub struct Tracer<'a> {
|
||||
root: &'a Assembly,
|
||||
rays: Vec<Ray>, // Should only be used from trace(), not any other methods
|
||||
xform_stack: Vec<Matrix4x4>,
|
||||
world_rays: &'a [Ray],
|
||||
intersections: &'a mut [SurfaceIntersection],
|
||||
rays: Vec<Ray>,
|
||||
isects: Vec<SurfaceIntersection>,
|
||||
}
|
||||
|
||||
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