Initial
This commit is contained in:
64
src/hittable.rs
Normal file
64
src/hittable.rs
Normal file
@ -0,0 +1,64 @@
|
||||
use crate::{Point3, Ray, Vec3};
|
||||
use crate::material::{Material};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct HitRecord<'material> {
|
||||
pub point: Point3,
|
||||
pub normal: Vec3,
|
||||
pub t: f64,
|
||||
pub front_face: bool,
|
||||
pub material: &'material Material
|
||||
}
|
||||
|
||||
pub trait Hittable {
|
||||
fn hit(&self, ray: &Ray, t_min: f64, t_max: f64) -> Option<HitRecord>;
|
||||
}
|
||||
pub struct Sphere {
|
||||
pub center: Point3,
|
||||
pub radius: f64,
|
||||
pub material: Material
|
||||
}
|
||||
impl Sphere {
|
||||
pub fn new(center: Point3, radius: f64, material: Material) -> Sphere {
|
||||
Sphere { center, radius, material }
|
||||
}
|
||||
}
|
||||
impl Default for Sphere {
|
||||
fn default() -> Self {
|
||||
Sphere {
|
||||
center: Point3::default(),
|
||||
radius: 0.0,
|
||||
material: Material::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Hittable for Sphere {
|
||||
fn hit(&self, ray: &Ray, t_min: f64, t_max: f64) -> Option<HitRecord> {
|
||||
let oc = &ray.origin() - &self.center;
|
||||
let a = ray.direction().length_squared();
|
||||
let half_b = oc.dot(&ray.direction());
|
||||
let c = oc.length_squared() - &self.radius * &self.radius;
|
||||
let discriminant = half_b * half_b - a * c;
|
||||
if discriminant < 0.0 { return None; }
|
||||
|
||||
let sqrtd = f64::sqrt(discriminant);
|
||||
let root = (-half_b - sqrtd) / a;
|
||||
if root < t_min || t_max < root {
|
||||
let root = (-half_b + sqrtd) / a;
|
||||
if root < t_min || t_max < root { return None; }
|
||||
}
|
||||
|
||||
let point = ray.at(root);
|
||||
let normal = (point - self.center) / self.radius;
|
||||
let front_face = ray.direction().dot(&normal) < 0.0;
|
||||
let normal = if front_face { normal } else { -normal };
|
||||
Some(HitRecord {
|
||||
point,
|
||||
normal,
|
||||
t: root,
|
||||
front_face,
|
||||
material: &self.material
|
||||
})
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user