Renderer/src/hittable.rs

58 lines
1.3 KiB
Rust
Raw Normal View History

2022-04-27 18:27:07 +02:00
use super::Point3;
use super::Ray;
use super::Vec3;
pub struct HitRecord {
p: Point3,
normal: Vec3,
t: f64,
}
pub struct Sphere {
center: Point3,
radius: f64,
}
pub trait Hittable {
fn hit(&self, r: Ray, t_min: f64, t_max: f64, rec: &mut HitRecord) -> bool;
}
impl Sphere {
fn new(cen: Point3, r: f64) -> Self {
Sphere {
center: cen,
radius: r,
}
}
}
impl Hittable for Sphere {
fn hit(&self, r: Ray, t_min: f64, t_max: f64, rec: &mut HitRecord) -> bool {
let oc = r.origin() - self.center;
let a = r.direction().length_squared(); // gleiches Ergebnis wie Skalarprodukt
let b = 2.0 * Vec3::dot(oc, r.direction());
let c = oc.length_squared() - self.radius * self.radius;
let discriminant = b * b - 4.0 * a * c;
if discriminant < 0.0 {
return false;
}
let sqrtd = discriminant.sqrt();
let root = (-b / 2.0 - sqrtd) / a;
if root < t_min || t_max < root {
let root2 = (-b / 2.0 + sqrtd) / a;
if root2 < t_min || t_max < root {
return false;
}
}
rec.t = root;
rec.p = r.at(rec.t);
rec.normal = (rec.p - self.center) / self.radius;
return true;
}
}