ft: 6.5: hitlist
This commit is contained in:
BIN
output.png
BIN
output.png
Binary file not shown.
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 26 KiB |
27
src/main.rs
27
src/main.rs
@@ -9,26 +9,14 @@ use std::cmp::max;
|
|||||||
|
|
||||||
use crate::objects::hit::Hit;
|
use crate::objects::hit::Hit;
|
||||||
use crate::objects::sphere::Sphere;
|
use crate::objects::sphere::Sphere;
|
||||||
use crate::objects::traits::{Hittable, Normal};
|
use crate::objects::traits::Hittable;
|
||||||
use crate::ray::Ray;
|
use crate::ray::Ray;
|
||||||
use crate::vec3::{Colour, Vec3};
|
use crate::vec3::{Colour, Vec3};
|
||||||
use log::info;
|
use log::info;
|
||||||
use pretty_env_logger;
|
use pretty_env_logger;
|
||||||
|
|
||||||
fn ray_colour<T>(hittables: &Vec<T>, r: &Ray) -> Colour
|
fn ray_colour<T: Hittable>(hittables: &Vec<T>, r: &Ray) -> Colour {
|
||||||
where
|
let closest = Hit::hit_list(hittables, r);
|
||||||
T: Hittable + Normal,
|
|
||||||
{
|
|
||||||
let mut closest: Option<Hit> = None;
|
|
||||||
for hittable in hittables {
|
|
||||||
if let Some(hit) = hittable.hit(r) {
|
|
||||||
// hit happens in front of camera and is closer than closest
|
|
||||||
if *hit.t() > 0. && (closest.is_none() || closest.as_ref().unwrap().t() > hit.t()) {
|
|
||||||
closest = Some(hit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(hit) = closest {
|
if let Some(hit) = closest {
|
||||||
let n = hit.n();
|
let n = hit.n();
|
||||||
return 0.5 * Colour::new(n.x() + 1., n.y() + 1., n.z() + 1.);
|
return 0.5 * Colour::new(n.x() + 1., n.y() + 1., n.z() + 1.);
|
||||||
@@ -42,12 +30,13 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// use structs so rust-analyzer can provide lsp
|
|
||||||
let s = Sphere::new(Vec3::new(0., 0., -1.), 0.5);
|
|
||||||
let objects = vec![s];
|
|
||||||
|
|
||||||
pretty_env_logger::init();
|
pretty_env_logger::init();
|
||||||
|
|
||||||
|
// setup objects
|
||||||
|
let mut objects = vec![Sphere::new(Vec3::new(0., 0., -1.), 0.5)];
|
||||||
|
objects.push(Sphere::new(Vec3::new(0., 0., -0.1), 0.01));
|
||||||
|
objects.push(Sphere::new(Vec3::new(0., -100.5, -1.), 100.));
|
||||||
|
|
||||||
let aspect_ratio = 16. / 9.;
|
let aspect_ratio = 16. / 9.;
|
||||||
let image_width = 400;
|
let image_width = 400;
|
||||||
let image_height = max(1, (image_width as f32 / aspect_ratio) as u32);
|
let image_height = max(1, (image_width as f32 / aspect_ratio) as u32);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use crate::vec3::Vec3;
|
use crate::{objects::traits::Hittable, ray::Ray, vec3::Vec3};
|
||||||
|
|
||||||
pub struct Hit {
|
pub struct Hit {
|
||||||
t: f32,
|
t: f32,
|
||||||
@@ -22,4 +22,17 @@ impl Hit {
|
|||||||
pub fn n(&self) -> &Vec3 {
|
pub fn n(&self) -> &Vec3 {
|
||||||
&self.n
|
&self.n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn hit_list<T: Hittable>(hittables: &Vec<T>, r: &Ray) -> Option<Hit> {
|
||||||
|
let mut closest: Option<Hit> = None;
|
||||||
|
for hittable in hittables {
|
||||||
|
if let Some(hit) = hittable.hit(r) {
|
||||||
|
// hit happens in front of camera and is closer than closest
|
||||||
|
if *hit.t() > 0. && (closest.is_none() || closest.as_ref().unwrap().t() > hit.t()) {
|
||||||
|
closest = Some(hit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return closest;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use core::f32::math::sqrt;
|
use core::f32::math::sqrt;
|
||||||
|
|
||||||
use crate::objects::hit::Hit;
|
use crate::objects::hit::Hit;
|
||||||
use crate::objects::traits::{Hittable, Normal};
|
use crate::objects::traits::Hittable;
|
||||||
use crate::Vec3;
|
use crate::Vec3;
|
||||||
|
|
||||||
pub struct Sphere {
|
pub struct Sphere {
|
||||||
@@ -34,9 +34,7 @@ impl Hittable for Sphere {
|
|||||||
Some(Hit::new(t, p, self.normal_at(&p)))
|
Some(Hit::new(t, p, self.normal_at(&p)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl Normal for Sphere {
|
|
||||||
fn normal_at(&self, p: &Vec3) -> Vec3 {
|
fn normal_at(&self, p: &Vec3) -> Vec3 {
|
||||||
(*p - self.center).get_unit()
|
(*p - self.center).get_unit()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,5 @@ use crate::Vec3;
|
|||||||
|
|
||||||
pub trait Hittable {
|
pub trait Hittable {
|
||||||
fn hit(&self, r: &Ray) -> Option<Hit>;
|
fn hit(&self, r: &Ray) -> Option<Hit>;
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Normal {
|
|
||||||
fn normal_at(&self, p: &Vec3) -> Vec3;
|
fn normal_at(&self, p: &Vec3) -> Vec3;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user