diff options
Diffstat (limited to 'src/camera/film.rs')
-rw-r--r-- | src/camera/film.rs | 92 |
1 files changed, 63 insertions, 29 deletions
diff --git a/src/camera/film.rs b/src/camera/film.rs index 6661529..1d87399 100644 --- a/src/camera/film.rs +++ b/src/camera/film.rs @@ -1,67 +1,101 @@ -use crate::vector::*; +use crate::core::*; use crate::Float; -use crate::bound; -use crate::spectrum::Spectrum; - -use bound::{Bound2i, Bound2f}; -use super::filter::Filter; -use std::rc::Rc; #[derive(Clone)] pub struct Pixel { - pub rgb: [Float; 3], + rgb: Spectrum, + samples: u32, } pub struct Film { - pub resolution: Vector2i, + size: Vector2i, drawingBound: Bound2i, pixels: Vec<Pixel>, - filter: Rc<Filter>, } pub struct FilmTile { - pub bounds: Bound2i, - filter: Rc<Filter>, + bounds: Bound2i, + size: Vector2i, + + pixels: Vec<Pixel>, } +//const HalfPixel = Vector2f::new(0.5); + impl Pixel { fn new() -> Pixel { - Pixel { rgb: [0.0, 0.0, 0.0] } + Pixel { + rgb: Default::default(), + samples: 0, + } + } + + fn add(&mut self, c: &Spectrum, weight: Float) { + self.rgb += &(c * weight); + self.samples += 1; + } +} + +impl std::ops::AddAssign<&Self> for Pixel { + fn add_assign(&mut self, op: &Self) { + self.rgb += &op.rgb; + self.samples += op.samples; } } impl Film { - pub fn new(resolution: Vector2i, filter: Rc<Filter>) -> Film { - let area = resolution.x * resolution.y; + pub fn new(size: Vector2i) -> Film { + let area = size.x * size.y; Film { - resolution, - drawingBound: Bound2i::new(&Vector2::new(0), &resolution), + size, + drawingBound: Bound2i::new(&Vector2i::new(0), &size), pixels: vec![Pixel::new(); area as usize], - filter, } } pub fn get_tile(&self, bound: &Bound2i) -> FilmTile { - // Used to calculate descrete coordinates into continues - let halfpixel = Vector2f::new_xy(0.5, 0.5); - let fbound = Bound2f::from(bound); + FilmTile::new( + bound, + ) + + } - let p0 = Vector2i::from((fbound.min - halfpixel - self.filter.radius).ceil()); - let p1 = Vector2i::from((fbound.min - halfpixel + self.filter.radius).floor()); + pub fn commit_tile(&mut self, tile: &FilmTile) { + let offset = tile.bounds.min; - let tilebound = bound::intersect(&Bound2i::new(&p0, &p1), &self.drawingBound); + for y in 0 ..= tile.size.y { + let rowindex = (offset.y + y) * self.size.x; + let prowindex = y * tile.size.x; - FilmTile { - bounds: tilebound, - filter: self.filter.clone(), + for x in 0 ..= tile.size.x { + let index = offset.x + x + rowindex; + let pindex: i32 = x + prowindex; + + self.pixels[index as usize] += &tile.pixels[pindex as usize]; + } } } } impl FilmTile { - fn add_sample(point: &Vector2f, c: Spectrum) { - + fn new(bounds: &Bound2i) -> FilmTile { + FilmTile { + bounds: bounds.clone(), + pixels: vec![Pixel::new(); bounds.area() as usize], + size: bounds.diagonal(), + } + } + + pub fn add_sample(&mut self, point: &Vector2f, c: Spectrum) { + let point = Vector2i::from(point.floor()); + // Subtract the offset + let point = point - self.bounds.min; + + let index = point.x + point.y * self.size.x; + + let pixel = self.pixels.get_mut(index as usize).unwrap(); + pixel.add(&c, 1.0); } } |