Skip to content

Commit

Permalink
cornell box for real!
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristopherBiscardi committed Sep 2, 2023
1 parent 073b605 commit 1c3ea7a
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 20 deletions.
32 changes: 22 additions & 10 deletions examples/cornell-box.rs
Expand Up @@ -61,16 +61,28 @@ fn main() -> io::Result<()> {
white.clone(),
)));

world.push(Shapes::QuadBox(QuadBox::new(
DVec3::new(130., 0., 65.),
DVec3::new(295., 165., 230.),
white.clone(),
)));
world.push(Shapes::QuadBox(QuadBox::new(
DVec3::new(265., 0., 295.),
DVec3::new(430., 330., 460.),
white,
)));
world.push(Shapes::Translate {
offset: DVec3::new(265., 0., 295.),
object: Box::new(Shapes::new_rotate_y(
15.,
Shapes::QuadBox(QuadBox::new(
DVec3::new(0., 0., 0.),
DVec3::new(165., 330., 165.),
white.clone(),
)),
)),
});
world.push(Shapes::Translate {
offset: DVec3::new(130., 0., 65.),
object: Box::new(Shapes::new_rotate_y(
-18.,
Shapes::QuadBox(QuadBox::new(
DVec3::new(0., 0., 0.),
DVec3::new(165., 165., 165.),
white,
)),
)),
});

let camera = Camera::init()
.image_width(800)
Expand Down
106 changes: 96 additions & 10 deletions src/shapes.rs
@@ -1,4 +1,6 @@
use crate::hittable::Hittable;
use glam::DVec3;

use crate::{hittable::Hittable, ray::Ray};

pub mod quad;
pub mod quad_box;
Expand All @@ -13,10 +15,34 @@ pub enum Shapes {
Sphere(sphere::Sphere),
Quad(quad::Quad),
QuadBox(quad_box::QuadBox),
Translate {
offset: DVec3,
object: Box<Shapes>,
},
RotateY {
sin_theta: f64,
cos_theta: f64,
object: Box<Shapes>,
},
// RoundedBox(rounded_box::RoundedBox),
// Box(a_box::Box),
// Cylinder(cylinder::Cylinder),
}
impl Shapes {
pub fn new_rotate_y(
angle: f64,
object: Shapes,
) -> Self {
let radians = angle.to_radians();
let sin_theta = radians.sin();
let cos_theta = radians.cos();
Self::RotateY {
sin_theta,
cos_theta,
object: Box::new(object),
}
}
}

impl Hittable for Shapes {
fn hit(
Expand All @@ -33,15 +59,75 @@ impl Hittable for Shapes {
}
Shapes::QuadBox(object) => {
object.hit(ray, interval)
} // Shapes::RoundedBox(object) => {
// object.hit(ray, interval)
// }
// Shapes::Box(object) => {
// object.hit(ray, interval)
// }
// Shapes::Cylinder(object) => {
// object.hit(ray, interval)
// }
}
Shapes::Translate { offset, object } => {
// Move the ray backwards by the offset
let offset_ray = Ray {
origin: ray.origin - *offset,
direction: ray.direction,
time: ray.time,
};
// Determine where (if any) an intersection occurs along the offset ray
let Some(mut hit_record) =
object.hit(&offset_ray, interval)
else {
return None;
};
// Move the intersection point forwards by the offset
hit_record.point += *offset;
Some(hit_record)
}
Shapes::RotateY {
sin_theta,
cos_theta,
object,
} => {
// Change the ray from world space to object space
let mut origin = ray.origin.clone();
let mut direction = ray.direction.clone();

origin.x = cos_theta * ray.origin.x
- sin_theta * ray.origin.z;
origin.z = sin_theta * ray.origin.x
+ cos_theta * ray.origin.z;

direction.x = cos_theta * ray.direction.x
- sin_theta * ray.direction.z;
direction.z = sin_theta * ray.direction.x
+ cos_theta * ray.direction.z;

let rotated_r = Ray {
origin,
direction,
time: ray.time,
};

// Determine where (if any) an intersection occurs in object space
let Some(mut hit_record) =
object.hit(&rotated_r, interval)
else {
return None;
};

// Change the intersection point from object space to world space
let mut p = hit_record.point;
p.x = cos_theta * hit_record.point.x
+ sin_theta * hit_record.point.z;
p.z = -sin_theta * hit_record.point.x
+ cos_theta * hit_record.point.z;

// Change the normal from object space to world space
let mut normal = hit_record.normal;
normal.x = cos_theta * hit_record.normal.x
+ sin_theta * hit_record.normal.z;
normal.z = -sin_theta * hit_record.normal.x
+ cos_theta * hit_record.normal.z;

hit_record.point = p;
hit_record.normal = normal;

Some(hit_record)
}
}
}
}

0 comments on commit 1c3ea7a

Please sign in to comment.