diff options
| author | Sakarias Johansson <sakarias.johansson@goodbyekansas.com> | 2023-01-08 17:51:44 +0100 |
|---|---|---|
| committer | Sakarias Johansson <sakarias.johansson@goodbyekansas.com> | 2023-01-08 17:51:44 +0100 |
| commit | 899f81eed6c221dce22333ad03704b12d7634a54 (patch) | |
| tree | e9ea6b377bada412629341e666ae5d2eb929420a /racer-tracer/src/geometry | |
| parent | 928b4191bf5a0d27da6d680ccaade7f94860359e (diff) | |
| download | racer-tracer-899f81eed6c221dce22333ad03704b12d7634a54.tar.gz racer-tracer-899f81eed6c221dce22333ad03704b12d7634a54.tar.xz racer-tracer-899f81eed6c221dce22333ad03704b12d7634a54.zip | |
🌍 Add Geometry
- Created a trait for all geometry that has to implement a hit
function. Depending on if the ray hits or not it returns an option
with the color.
- Add support for multiple samples per pixel
Current issues:
- Using cooperative multitasking which isn't that
helpful in this situation since it's like running without async but
without overhead. Should switch to rayon.
- All data gets copied once per job. Will decide later what to
do (copy or put locks and share data between jobs).
Diffstat (limited to 'racer-tracer/src/geometry')
| -rw-r--r-- | racer-tracer/src/geometry/sphere.rs | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/racer-tracer/src/geometry/sphere.rs b/racer-tracer/src/geometry/sphere.rs new file mode 100644 index 0000000..6a0ab9c --- /dev/null +++ b/racer-tracer/src/geometry/sphere.rs @@ -0,0 +1,68 @@ +use std::option::Option; + +use crate::geometry::{HitRecord, Hittable}; +use crate::ray::Ray; +use crate::vec3::Vec3; + +pub struct Sphere { + pos: Vec3, + radius: f64, + material: Vec3, // Just a color for now. +} + +impl Sphere { + pub fn new(pos: Vec3, radius: f64, material: Vec3) -> Self { + Self { + pos, + radius, + material, + } + } +} + +impl Clone for Sphere { + fn clone(&self) -> Self { + Self { + pos: self.pos, + radius: self.radius, + material: self.material, + } + } +} + +impl Hittable for Sphere { + fn hit(&self, ray: &Ray, t_min: f64, t_max: f64) -> Option<HitRecord> { + let oc = ray.origin() - self.pos; + 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 = discriminant.sqrt(); + + // Find the nearest root that lies in acceptable range. + let mut root = (-half_b - sqrtd) / a; + if root < t_min || t_max < root { + root = (-half_b + sqrtd) / a; + + if root < t_min || t_max < root { + return None; + } + } + + let point = ray.at(root); + let outward_normal = (point - self.pos) / self.radius; + + let mut hit_record = HitRecord::new(point, root, self.material); + hit_record.set_face_normal(ray, outward_normal); + Some(hit_record) + } + + fn clone_box(&self) -> Box<dyn Hittable> { + Box::new(self.clone()) + } +} |
