summaryrefslogtreecommitdiff
path: root/racer-tracer/src/geometry
diff options
context:
space:
mode:
authorSakarias Johansson <sakarias.johansson@goodbyekansas.com>2023-01-08 17:51:44 +0100
committerSakarias Johansson <sakarias.johansson@goodbyekansas.com>2023-01-08 17:51:44 +0100
commit899f81eed6c221dce22333ad03704b12d7634a54 (patch)
treee9ea6b377bada412629341e666ae5d2eb929420a /racer-tracer/src/geometry
parent928b4191bf5a0d27da6d680ccaade7f94860359e (diff)
downloadracer-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.rs68
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())
+ }
+}