camera & spheres: add feature tag disable_inverse_cache
This commit is contained in:
parent
538b8ad364
commit
2eeeb2013b
@ -6,6 +6,9 @@ edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[features]
|
||||
disable_inverse_cache = []
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.41"
|
||||
criterion = "0.3.4"
|
||||
|
||||
@ -112,6 +112,7 @@ impl Camera {
|
||||
/// Tuple::vector(2_f32.sqrt() / 2., 0., -2_f32.sqrt() / 2.)
|
||||
/// );
|
||||
/// ```
|
||||
#[cfg(not(feature = "disable_inverse_cache"))]
|
||||
pub fn ray_for_pixel(&self, px: usize, py: usize) -> Ray {
|
||||
// The offset from the edge of the canvas to the pixel's corner.
|
||||
let xoffset = (px as f32 + 0.5) * self.pixel_size;
|
||||
@ -124,16 +125,35 @@ impl Camera {
|
||||
|
||||
// Using the camera matrix, transofmrm the canvas point and the origin,
|
||||
// and then compute the ray's direction vector.
|
||||
// (Remember that the canves is at z>=-1).
|
||||
// (Remember that the canvas is at z>=-1).
|
||||
let pixel = self.inverse_transform * Tuple::point(world_x, world_y, -1.);
|
||||
let origin = self.inverse_transform * Tuple::point(0., 0., 0.);
|
||||
let direction = (pixel - origin).normalize();
|
||||
|
||||
Ray::new(origin, direction)
|
||||
}
|
||||
#[cfg(feature = "disable_inverse_cache")]
|
||||
pub fn ray_for_pixel(&self, px: usize, py: usize) -> Ray {
|
||||
// The offset from the edge of the canvas to the pixel's corner.
|
||||
let xoffset = (px as f32 + 0.5) * self.pixel_size;
|
||||
let yoffset = (py as f32 + 0.5) * self.pixel_size;
|
||||
|
||||
// The untransformed coordinates of the pixle in world space.
|
||||
// (Remember that the camera looks toward -z, so +x is to the left.)
|
||||
let world_x = self.half_width - xoffset;
|
||||
let world_y = self.half_height - yoffset;
|
||||
|
||||
// Using the camera matrix, transofmrm the canvas point and the origin,
|
||||
// and then compute the ray's direction vector.
|
||||
// (Remember that the canvas is at z>=-1).
|
||||
let pixel = self.transform.inverse() * Tuple::point(world_x, world_y, -1.);
|
||||
let origin = self.transform.inverse() * Tuple::point(0., 0., 0.);
|
||||
let direction = (pixel - origin).normalize();
|
||||
|
||||
Ray::new(origin, direction)
|
||||
}
|
||||
|
||||
/// Use camera to render an image of the given world.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use std::f32::consts::PI;
|
||||
@ -160,7 +180,28 @@ impl Camera {
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn render_parallel(&self, w: &World) -> Canvas {
|
||||
fn render_parallel_one_tread_per_core(&self, w: &World) -> Canvas {
|
||||
let image_mu = Mutex::new(Canvas::new(self.hsize, self.vsize, BLACK));
|
||||
|
||||
(0..self.vsize).into_par_iter().for_each(|y| {
|
||||
let mut row_image = Canvas::new(self.hsize, 1, BLACK);
|
||||
for x in 0..self.hsize {
|
||||
let ray = self.ray_for_pixel(x, y);
|
||||
let color = w.color_at(&ray);
|
||||
row_image.set(x, 0, color);
|
||||
}
|
||||
// TODO(wathiede): create a row based setter for memcpying the row as a whole.
|
||||
let mut image = image_mu.lock().expect("failed to lock image mutex");
|
||||
for x in 0..self.hsize {
|
||||
image.set(x, y, row_image.get(x, 0));
|
||||
}
|
||||
});
|
||||
image_mu
|
||||
.into_inner()
|
||||
.expect("failed to get image out of mutex")
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
fn render_parallel_rayon(&self, w: &World) -> Canvas {
|
||||
let image_mu = Mutex::new(Canvas::new(self.hsize, self.vsize, BLACK));
|
||||
|
||||
(0..self.vsize).into_par_iter().for_each(|y| {
|
||||
|
||||
@ -105,6 +105,7 @@ impl Sphere {
|
||||
/// let n = s.normal_at(Tuple::point(0., 2_f32.sqrt()/2., -2_f32.sqrt()/2.));
|
||||
/// assert_eq!(n, Tuple::vector(0., 0.97014, -0.24254));
|
||||
/// ```
|
||||
#[cfg(not(feature = "disable_inverse_cache"))]
|
||||
pub fn normal_at(&self, world_point: Tuple) -> Tuple {
|
||||
let object_point = self.inverse_transform * world_point;
|
||||
let object_normal = object_point - Tuple::point(0., 0., 0.);
|
||||
@ -112,6 +113,14 @@ impl Sphere {
|
||||
world_normal.w = 0.;
|
||||
world_normal.normalize()
|
||||
}
|
||||
#[cfg(feature = "disable_inverse_cache")]
|
||||
pub fn normal_at(&self, world_point: Tuple) -> Tuple {
|
||||
let object_point = self.transform.inverse() * world_point;
|
||||
let object_normal = object_point - Tuple::point(0., 0., 0.);
|
||||
let mut world_normal = self.transform.inverse().transpose() * object_normal;
|
||||
world_normal.w = 0.;
|
||||
world_normal.normalize()
|
||||
}
|
||||
|
||||
pub fn transform(&self) -> Matrix4x4 {
|
||||
self.transform
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user