From de898f0b0aa34e8162e8a6d501196e07aa728fb3 Mon Sep 17 00:00:00 2001 From: Bill Thiede Date: Wed, 21 Jul 2021 20:42:08 -0700 Subject: [PATCH] Add builder pattern to a few core types. Add a From<[3;Float]> impl for Color to make things nicer. --- rtchallenge/Cargo.lock | 87 +++++++++++++++++++++++++++++++++++- rtchallenge/Cargo.toml | 1 + rtchallenge/src/lights.rs | 6 ++- rtchallenge/src/materials.rs | 7 ++- rtchallenge/src/shapes.rs | 22 ++++++++- rtchallenge/src/tuples.rs | 17 ++++++- 6 files changed, 135 insertions(+), 5 deletions(-) diff --git a/rtchallenge/Cargo.lock b/rtchallenge/Cargo.lock index 798d80e..cb4f4e8 100644 --- a/rtchallenge/Cargo.lock +++ b/rtchallenge/Cargo.lock @@ -130,7 +130,7 @@ dependencies = [ "ansi_term", "atty", "bitflags", - "strsim", + "strsim 0.8.0", "textwrap", "unicode-width", "vec_map", @@ -259,6 +259,41 @@ dependencies = [ "memchr", ] +[[package]] +name = "darling" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f2c43f534ea4b0b049015d00269734195e6d3f0f6635cb692251aca6f9f8b3c" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e91455b86830a1c21799d94524df0845183fa55bafd9aa137b01c7d1065fa36" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29b5acf0dea37a7f66f7b25d2c5e93fd46f8f6968b1a5d7a3e02e97768afc95a" +dependencies = [ + "darling_core", + "quote", + "syn", +] + [[package]] name = "deflate" version = "0.8.6" @@ -269,6 +304,37 @@ dependencies = [ "byteorder", ] +[[package]] +name = "derive_builder" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d13202debe11181040ae9063d739fa32cfcaaebe2275fe387703460ae2365b30" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66e616858f6187ed828df7c64a6d71720d83767a7f19740b2d1b6fe6327b36e5" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "derive_builder_macro" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58a94ace95092c5acb1e97a7e846b310cfbd499652f72297da7493f618a98d73" +dependencies = [ + "derive_builder_core", + "syn", +] + [[package]] name = "either" version = "1.6.1" @@ -308,6 +374,12 @@ dependencies = [ "backtrace", ] +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "getrandom" version = "0.2.3" @@ -349,6 +421,12 @@ dependencies = [ "libc", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "itertools" version = "0.9.0" @@ -662,6 +740,7 @@ dependencies = [ "anyhow", "core_affinity", "criterion", + "derive_builder", "enum-utils", "num_cpus", "png", @@ -773,6 +852,12 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "structopt" version = "0.3.22" diff --git a/rtchallenge/Cargo.toml b/rtchallenge/Cargo.toml index 2c03228..c7586a1 100644 --- a/rtchallenge/Cargo.toml +++ b/rtchallenge/Cargo.toml @@ -15,6 +15,7 @@ float-as-double = [] anyhow = "1.0.41" core_affinity = "0.5.10" criterion = "0.3.4" +derive_builder = "0.10.2" enum-utils = "0.1.2" num_cpus = "1.13.0" png = "0.16.8" diff --git a/rtchallenge/src/lights.rs b/rtchallenge/src/lights.rs index fe02f0a..b023565 100644 --- a/rtchallenge/src/lights.rs +++ b/rtchallenge/src/lights.rs @@ -1,8 +1,12 @@ +use derive_builder::Builder; + use crate::tuples::{Color, Tuple}; -#[derive(Clone, Debug, PartialEq)] +#[derive(Builder, Clone, Debug, Default, PartialEq)] +#[builder(default)] pub struct PointLight { pub position: Tuple, + #[builder(setter(into))] pub intensity: Color, } diff --git a/rtchallenge/src/materials.rs b/rtchallenge/src/materials.rs index e25aa31..cc29add 100644 --- a/rtchallenge/src/materials.rs +++ b/rtchallenge/src/materials.rs @@ -1,11 +1,16 @@ +use derive_builder::Builder; + use crate::{ lights::PointLight, tuples::Color, tuples::{dot, reflect, Tuple}, Float, BLACK, WHITE, }; -#[derive(Debug, PartialEq, Clone)] + +#[derive(Builder, Debug, PartialEq, Clone)] +#[builder(default)] pub struct Material { + #[builder(setter(into))] pub color: Color, pub ambient: Float, pub diffuse: Float, diff --git a/rtchallenge/src/shapes.rs b/rtchallenge/src/shapes.rs index b526164..bb9bc69 100644 --- a/rtchallenge/src/shapes.rs +++ b/rtchallenge/src/shapes.rs @@ -1,5 +1,7 @@ use std::sync::{Arc, Mutex}; +use derive_builder::Builder; + use crate::{ intersections::Intersections, materials::Material, matrices::Matrix4x4, rays::Ray, tuples::Tuple, @@ -20,6 +22,12 @@ pub enum Geometry { Plane, } +impl Default for Geometry { + fn default() -> Geometry { + Geometry::Sphere + } +} + impl PartialEq for Geometry { fn eq(&self, rhs: &Geometry) -> bool { use Geometry::*; @@ -35,7 +43,8 @@ impl PartialEq for Geometry { /// Shape represents visible objects. A signal instance of Shape can generically represent one of /// many different shapes based on the value of it's geometry field. Users chose the shape by /// calling the appropriate constructor, i.e. [Shape::sphere]. -#[derive(Debug, Clone, PartialEq)] +#[derive(Builder, Debug, Clone, PartialEq)] +#[builder(default)] pub struct Shape { transform: Matrix4x4, inverse_transform: Matrix4x4, @@ -43,6 +52,17 @@ pub struct Shape { geometry: Geometry, } +impl Default for Shape { + fn default() -> Shape { + Shape { + transform: Matrix4x4::identity(), + inverse_transform: Matrix4x4::identity(), + material: Material::default(), + geometry: Geometry::default(), + } + } +} + impl Shape { /// Create a test shape useful for debugging. /// diff --git a/rtchallenge/src/tuples.rs b/rtchallenge/src/tuples.rs index 1ce63a2..04f7f5f 100644 --- a/rtchallenge/src/tuples.rs +++ b/rtchallenge/src/tuples.rs @@ -161,17 +161,29 @@ pub fn cross(a: Tuple, b: Tuple) -> Tuple { ) } -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, Default)] pub struct Color { pub red: Float, pub green: Float, pub blue: Float, } + impl Color { pub const fn new(red: Float, green: Float, blue: Float) -> Color { Color { red, green, blue } } } + +impl From<[Float; 3]> for Color { + fn from(rgb: [Float; 3]) -> Self { + Color { + red: rgb[0], + green: rgb[1], + blue: rgb[2], + } + } +} + impl PartialEq for Color { fn eq(&self, rhs: &Color) -> bool { ((self.red - rhs.red).abs() < EPSILON) @@ -179,6 +191,7 @@ impl PartialEq for Color { && ((self.blue - rhs.blue).abs() < EPSILON) } } + impl Add for Color { type Output = Self; fn add(self, other: Self) -> Self { @@ -222,6 +235,7 @@ impl Mul for Float { } } } + impl Mul for Color { type Output = Color; fn mul(self, rhs: Color) -> Self::Output { @@ -243,6 +257,7 @@ impl Neg for Color { } } } + impl Sub for Color { type Output = Self; fn sub(self, other: Self) -> Self {