From 1b708049a9663c6eb9319af940f0a52e107db563 Mon Sep 17 00:00:00 2001 From: STP Date: Sun, 12 Nov 2023 05:11:11 -0500 Subject: [PATCH] fixed lifetimes --- Cargo.lock | 319 ++++++++++++++++++++++++++++++++++++++++++++--- Cargo.toml | 2 + src/main.rs | 1 + src/primitive.rs | 217 ++++++++++++++++++++++++-------- 4 files changed, 471 insertions(+), 68 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aa52c5b..5b85bad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -99,6 +99,12 @@ version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +[[package]] +name = "approx" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08abcc3b4e9339e33a3d0a5ed15d84a687350c05689d825e0f6655eef9e76a94" + [[package]] name = "approx" version = "0.5.1" @@ -108,6 +114,19 @@ dependencies = [ "num-traits", ] +[[package]] +name = "arc" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4543528550ff5d3fa676742778c61387b2b6db24ab72628ff951a5b1b0f470fe" +dependencies = [ + "cocoa", + "failure", + "lazy_static", + "objc", + "palette", +] + [[package]] name = "arrayref" version = "0.3.7" @@ -129,6 +148,15 @@ dependencies = [ "libloading 0.7.4", ] +[[package]] +name = "autocfg" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" +dependencies = [ + "autocfg 1.1.0", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -270,6 +298,28 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "cocoa" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b44bd25bd275e9d74a5dff8ca55f2fb66c9ad5e12170d58697701df21a56e0e" +dependencies = [ + "bitflags 1.3.2", + "block", + "core-graphics 0.14.0", + "libc", + "objc", +] + [[package]] name = "codespan-reporting" version = "0.11.1" @@ -292,22 +342,50 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf43edc576402991846b093a7ca18a3477e0ef9c588cde84964b5d3e43016642" +[[package]] +name = "core-foundation" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d" +dependencies = [ + "core-foundation-sys 0.6.2", + "libc", +] + [[package]] name = "core-foundation" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" dependencies = [ - "core-foundation-sys", + "core-foundation-sys 0.8.4", "libc", ] +[[package]] +name = "core-foundation-sys" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" + [[package]] name = "core-foundation-sys" version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +[[package]] +name = "core-graphics" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e54c4ab33705fa1fc8af375bb7929d68e1c1546c1ecef408966d8c3e49a1d84a" +dependencies = [ + "bitflags 1.3.2", + "core-foundation 0.6.4", + "foreign-types 0.3.2", + "libc", +] + [[package]] name = "core-graphics" version = "0.22.3" @@ -315,7 +393,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" dependencies = [ "bitflags 1.3.2", - "core-foundation", + "core-foundation 0.9.3", "core-graphics-types", "foreign-types 0.3.2", "libc", @@ -328,7 +406,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bb142d41022986c1d8ff29103a1411c8a3dfad3552f87a4f8dc50d61d4f4e33" dependencies = [ "bitflags 1.3.2", - "core-foundation", + "core-foundation 0.9.3", "libc", ] @@ -402,6 +480,28 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "failure" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" +dependencies = [ + "backtrace", + "failure_derive", +] + +[[package]] +name = "failure_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "synstructure", +] + [[package]] name = "fdeflate" version = "0.3.1" @@ -475,6 +575,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + [[package]] name = "futures-core" version = "0.3.29" @@ -784,7 +890,7 @@ version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ - "autocfg", + "autocfg 1.1.0", "scopeguard", ] @@ -809,7 +915,7 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7574c1cf36da4798ab73da5b215bbf444f50718207754cb522201d78d1cd0ff2" dependencies = [ - "autocfg", + "autocfg 1.1.0", "rawpointer", ] @@ -834,7 +940,7 @@ version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" dependencies = [ - "autocfg", + "autocfg 1.1.0", ] [[package]] @@ -906,7 +1012,7 @@ version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "307ed9b18cc2423f29e83f84fd23a8e73628727990181f18641a8b5dc2ab1caa" dependencies = [ - "approx", + "approx 0.5.1", "matrixmultiply", "nalgebra-macros", "num-complex", @@ -983,7 +1089,7 @@ version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" dependencies = [ - "autocfg", + "autocfg 1.1.0", "bitflags 1.3.2", "cfg-if", "libc", @@ -1015,7 +1121,7 @@ version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" dependencies = [ - "autocfg", + "autocfg 1.1.0", "num-traits", ] @@ -1025,7 +1131,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" dependencies = [ - "autocfg", + "autocfg 1.1.0", "num-integer", "num-traits", ] @@ -1036,7 +1142,7 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ - "autocfg", + "autocfg 1.1.0", ] [[package]] @@ -1159,6 +1265,18 @@ dependencies = [ "ttf-parser", ] +[[package]] +name = "palette" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0514191b8ea7d7ee7e8982067929a6f0139d93584f82562d5e5e0e6ac738950" +dependencies = [ + "approx 0.1.1", + "num-traits", + "phf", + "phf_codegen", +] + [[package]] name = "parking_lot" version = "0.12.1" @@ -1194,6 +1312,44 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +[[package]] +name = "phf" +version = "0.7.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3da44b85f8e8dfaec21adae67f95d93244b2ecf6ad2a692320598dcc8e6dd18" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_codegen" +version = "0.7.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b03e85129e324ad4166b06b2c7491ae27fe3ec353af72e72cd1654c7225d517e" +dependencies = [ + "phf_generator", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.7.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_shared" +version = "0.7.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0" +dependencies = [ + "siphasher", +] + [[package]] name = "pkg-config" version = "0.3.27" @@ -1259,6 +1415,112 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" +dependencies = [ + "autocfg 0.1.8", + "libc", + "rand_chacha", + "rand_core 0.4.2", + "rand_hc", + "rand_isaac", + "rand_jitter", + "rand_os", + "rand_pcg", + "rand_xorshift", + "winapi", +] + +[[package]] +name = "rand_chacha" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" +dependencies = [ + "autocfg 0.1.8", + "rand_core 0.3.1", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + +[[package]] +name = "rand_hc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rand_isaac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rand_jitter" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" +dependencies = [ + "libc", + "rand_core 0.4.2", + "winapi", +] + +[[package]] +name = "rand_os" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" +dependencies = [ + "cloudabi", + "fuchsia-cprng", + "libc", + "rand_core 0.4.2", + "rdrand", + "winapi", +] + +[[package]] +name = "rand_pcg" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" +dependencies = [ + "autocfg 0.1.8", + "rand_core 0.4.2", +] + +[[package]] +name = "rand_xorshift" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" +dependencies = [ + "rand_core 0.3.1", +] + [[package]] name = "range-alloc" version = "0.1.3" @@ -1277,6 +1539,15 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", +] + [[package]] name = "redox_syscall" version = "0.3.5" @@ -1341,10 +1612,12 @@ name = "rust-opengl" version = "0.1.0" dependencies = [ "anyhow", + "arc", "bytemuck", "cfg-if", "env_logger", "image", + "lazy_static", "log", "nalgebra", "pollster", @@ -1418,7 +1691,7 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "061507c94fc6ab4ba1c9a0305018408e312e17c041eb63bef8aa726fa33aceae" dependencies = [ - "approx", + "approx 0.5.1", "num-complex", "num-traits", "paste", @@ -1431,6 +1704,12 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +[[package]] +name = "siphasher" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac" + [[package]] name = "slotmap" version = "1.0.6" @@ -1518,6 +1797,18 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "unicode-xid", +] + [[package]] name = "termcolor" version = "1.3.0" @@ -2095,8 +2386,8 @@ dependencies = [ "android-activity", "bitflags 1.3.2", "cfg_aliases", - "core-foundation", - "core-graphics", + "core-foundation 0.9.3", + "core-graphics 0.22.3", "dispatch", "instant", "libc", diff --git a/Cargo.toml b/Cargo.toml index 1af3f7e..f1449ce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,3 +20,5 @@ bytemuck = { version = "1.12", features = [ "derive" ] } anyhow = "1.0" nalgebra = "0.32.3" roots = "0.0.8" +lazy_static = "1.4.0" +arc = "0.0.1" diff --git a/src/main.rs b/src/main.rs index 5eb215e..1538cfe 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,6 +13,7 @@ mod texture; mod vertex; const EPSILON: f32 = 1e-7; +const INFINITY: f32 = 1e7; fn main() { pollster::block_on(run()); diff --git a/src/primitive.rs b/src/primitive.rs index eb08d87..3a48ff0 100644 --- a/src/primitive.rs +++ b/src/primitive.rs @@ -1,7 +1,13 @@ use crate::ray::Ray; -use crate::EPSILON; +use crate::{EPSILON, INFINITY}; +use lazy_static::lazy_static; use nalgebra::{distance, Matrix4, Point3, Vector3}; use roots::{find_roots_quadratic, Roots}; + +lazy_static! { + static ref MAGENTA_MATERIAL: Material = Material::magenta(); +} + // MATERIAL ----------------------------------------------------------------- struct Material { kd: Vector3, @@ -54,21 +60,21 @@ impl BoundingBox { } } // PRIMITIVE TRAIT ----------------------------------------------------------------- -trait Primitive { +trait Primitive<'a> { fn intersect_ray(&self, ray: &Ray) -> Option; - fn get_material(self) -> Material; + fn get_material(self) -> &'a Material; } // SPHERE ----------------------------------------------------------------- -struct Sphere { +struct Sphere<'a> { position: Point3, radius: f32, - material: Material, + material: &'a Material, bounding_box: BoundingBox, } -impl Sphere { - fn new(position: Point3, radius: f32, material: Material) -> Self { +impl<'a> Sphere<'a> { + fn new(position: Point3, radius: f32, material: &'a Material) -> Self { let radius_vec = Vector3::new(radius, radius, radius); let bln = position - radius_vec; let trf = position + radius_vec; @@ -82,23 +88,11 @@ impl Sphere { } fn unit() -> Self { - let position = Point3::new(0.0, 0.0, 0.0); - let radius = 1.0; - let radius_vec = Vector3::new(radius, radius, radius); - let material = Material::magenta(); - let bln = position - radius_vec; - let trf = position + radius_vec; - let bounding_box = BoundingBox { bln, trf }; - Sphere { - position, - radius, - material, - bounding_box, - } + Sphere::new(Point3::new(0.0, 0.0, 0.0), 1.0, &MAGENTA_MATERIAL) } } -impl Primitive for Sphere { +impl<'a> Primitive<'a> for Sphere<'a> { fn intersect_ray(&self, ray: &Ray) -> Option { let pos = &ray.a; let dir = &ray.b; @@ -134,23 +128,27 @@ impl Primitive for Sphere { }) } - fn get_material(self) -> Material { + fn get_material(self) -> &'a Material { self.material } } // CIRCLE ----------------------------------------------------------------- -struct Circle { +struct Circle<'a> { position: Point3, radius: f32, normal: Vector3, - material: Material, + material: &'a Material, bounding_box: BoundingBox, } -impl Circle { - fn new(position: Point3, radius: f32, normal: Vector3, material: Material) -> Self { - let normal = normal.normalize(); +impl<'a> Circle<'a> { + fn new( + position: Point3, + radius: f32, + normal: Vector3, + material: &'a Material, + ) -> Self { let radius_vec = Vector3::new(radius, radius, radius); let bln = position - radius_vec; let trf = position + radius_vec; @@ -158,7 +156,7 @@ impl Circle { Circle { position, radius, - normal, + normal: normal.normalize(), material, bounding_box, } @@ -168,7 +166,7 @@ impl Circle { let position = Point3::new(0.0, 0.0, 0.0); let normal = Vector3::new(0.0, 1.0, 0.0); let radius = 1.0; - let material = Material::magenta(); + let material = &MAGENTA_MATERIAL; let bln = Point3::new(-radius, 0.0, -EPSILON); let trf = Point3::new(radius, 0.0, EPSILON); @@ -184,11 +182,14 @@ impl Circle { } } -impl Primitive for Circle { +impl<'a> Primitive<'a> for Circle<'a> { fn intersect_ray(&self, ray: &Ray) -> Option { let constant = self.position.coords.dot(&self.normal); let denominator = ray.b.dot(&self.normal); let t = (constant - ray.a.coords.dot(&self.normal)) / denominator; + if t > INFINITY { + return None; + }; let intersect = ray.at_t(t); let distance = distance(&intersect, &self.position); match distance > self.radius { @@ -202,35 +203,62 @@ impl Primitive for Circle { } } - fn get_material(self) -> Material { + fn get_material(self) -> &'a Material { self.material } } // CYLINDER ----------------------------------------------------------------- -struct Cylinder {} +struct Cylinder<'a> { + radius: f32, + base: f32, + height: f32, + base_circle: &'a Circle<'a>, + height_circle: &'a Circle<'a>, + material: &'a Material, +} -impl Cylinder {} +impl<'a> Cylinder<'a> {} -impl Primitive for Cylinder { +impl<'a> Primitive<'a> for Cylinder<'a> { fn intersect_ray(&self, ray: &Ray) -> Option { todo!() } - fn get_material(self) -> Material { + fn get_material(self) -> &'a Material { todo!() } } // CONE ----------------------------------------------------------------- -struct Cone { +struct Cone<'a> { radius: f32, - height: f32, base: f32, - circle: Circle, + height: f32, + circle: &'a Circle<'a>, + material: &'a Material, } -impl Cone { +impl<'a> Cone<'a> { + fn new(radius: f32, height: f32, base: f32, material: &'a Material) -> Self { + let circle = Arc::new(Circle::new( + Point3::new(0.0, -base, 0.0), + radius, + Vector3::new(0.0, 1.0, 0.0), + &material, + )); + Cone { + radius, + base, + height, + circle: Arc::clone(&circle), + material, + } + } + fn unit() -> Self { + Cone::new(1.0, 2.0, -1.0, &MAGENTA_MATERIAL) + } + fn get_normal(&self, intersect: Point3) -> Vector3 { let r = self.radius; let h = self.height; @@ -240,7 +268,7 @@ impl Cone { } } -impl Primitive for Cone { +impl<'a> Primitive<'a> for Cone<'a> { fn intersect_ray(&self, ray: &Ray) -> Option { let point = &ray.a; let dir = &ray.b; @@ -300,46 +328,127 @@ impl Primitive for Cone { }; } - fn get_material(self) -> Material { - todo!() + fn get_material(self) -> &'a Material { + self.material + } +} + +// RECTANGLE ----------------------------------------------------------------- +struct Rectangle<'a> { + position: Point3, + normal: Vector3, + width_direction: Vector3, + material: &'a Material, + width: f32, + height: f32, +} + +impl Rectangle<'_> { + fn new( + position: Point3, + normal: Vector3, + width_direction: Vector3, + width: f32, + height: f32, + material: &Material, + ) -> Self { + Rectangle { + position, + normal: normal.normalize(), + width_direction: width_direction.normalize(), + width, + height, + material, + } + } + fn unit() -> Self { + Rectangle::new( + Point3::new(0.0, 0.0, 0.0), + Vector3::new(0.0, 1.0, 0.0), + Vector3::new(1.0, 0.0, 0.0), + 2.0, + 2.0, + &Material::magenta(), + ) + } +} + +impl<'a> Primitive<'a> for Rectangle<'a> { + fn intersect_ray(&self, ray: &Ray) -> Option { + let constant = self.position.coords.dot(&self.normal); + let denominator = ray.b.dot(&self.normal); + let t = (constant - ray.a.coords.dot(&self.normal)) / denominator; + if t > INFINITY { + return None; + } + + let intersect = ray.at_t(t); + let height_direction = self.width_direction.cross(&self.normal); + let (w2, h2) = (self.width / 2.0, self.height / 2.0); + let r1 = w2 * self.width_direction; + let r2 = h2 * height_direction; + let pi = intersect - self.position; + let pi_dot_r1 = pi.dot(&r1); + let pi_dot_r2 = pi.dot(&r2); + + if pi_dot_r1 >= -w2 && pi_dot_r1 <= w2 && pi_dot_r2 >= -h2 && pi_dot_r2 <= h2 { + return Some(Intersection { + point: intersect, + normal: self.normal, + }); + } + None + } + + fn get_material(self) -> &'a Material { + self.material } } // BOX ----------------------------------------------------------------- -struct Box {} -impl Box {} -impl Primitive for Box { +struct Box<'a> { + material: &'a Material, +} + +impl Box<'_> {} +impl<'a> Primitive<'a> for Box<'a> { fn intersect_ray(&self, ray: &Ray) -> Option { todo!() } - fn get_material(self) -> Material { + fn get_material(self) -> &'a Material { todo!() } } // TRIANGLE ----------------------------------------------------------------- -struct Triangle {} -impl Triangle {} -impl Primitive for Triangle { +struct Triangle<'a> { + material: &'a Material, +} + +impl Triangle<'_> {} + +impl<'a> Primitive<'a> for Triangle<'a> { fn intersect_ray(&self, ray: &Ray) -> Option { todo!() } - fn get_material(self) -> Material { + fn get_material(self) -> &'a Material { todo!() } } // MESH ----------------------------------------------------------------- -struct Mesh {} -impl Mesh {} -impl Primitive for Mesh { +struct Mesh<'a> { + material: &'a Material, +} +impl Mesh<'_> {} +impl<'a> Primitive<'a> for Mesh<'a> { fn intersect_ray(&self, ray: &Ray) -> Option { todo!() } - fn get_material(self) -> Material { + fn get_material(self) -> &'a Material { todo!() } }