From c3d37f47585b3e9b3cb558a25ec4c78a3dbf7506 Mon Sep 17 00:00:00 2001 From: djairoh Date: Sat, 2 May 2026 12:57:45 +0200 Subject: [PATCH] ft: added cube --- scenes/scene.json | 12 +++++------ src/main.rs | 1 - src/objects.rs | 1 + src/objects/cube.rs | 49 +++++++++++++++++++++++++++++++++++++++++++++ src/objects/quad.rs | 33 ++++++++++++++++-------------- src/scenes/scene.rs | 28 +++++++++++++++++++++++--- 6 files changed, 99 insertions(+), 25 deletions(-) create mode 100644 src/objects/cube.rs diff --git a/scenes/scene.json b/scenes/scene.json index 0dc79ed..7a99474 100644 --- a/scenes/scene.json +++ b/scenes/scene.json @@ -5,8 +5,8 @@ "anti_alias_rate": 1, "max_depth": 50, "fov": 50.0, - "look_from": [0, 2, 10], - "look_at": [0.0, 0.0, -1.0 ], + "look_from": [15, 4, 10], + "look_at": [10.0, 2.0, 0.0], "vup": [0.0, 1.0, 0.0], "defocus_angle": 0, "focus_dist": 15.68 @@ -14,20 +14,20 @@ "materials": [ { "type": "lambertian", "albedo": [0.2, 0.2, 0.2], "prob": 0.8 }, { "type": "lambertian", "albedo": [0.9, 0.9, 0.0], "prob": 1.0, "fuzz": 0.1 }, - { "type": "dielectric", "refraction_index": 1.5}, - { "type": "metal", "albedo": [0.8, 0.6, 0.2], "prob": 1.0, "fuzz": 1.0 } + { "type": "dielectric", "refraction_index": 1.5} ], "objects": [ { "type": "sphere", "center": [0.0, 0.0, -1.2], "radius": 0.5, "material": { "type": "metal", "albedo": [0.7, 0.4, 0.2], "prob": 1.0, "fuzz": 0.1 }}, { "type": "sphere", "center": [-1, 0, -1], "radius": 0.4, "material": 2}, - { "type": "sphere", "center": [1, 0, -1], "radius": 0.5, "material": 3}, + { "type": "sphere", "center": [1, 0, -1], "radius": 0.5, "material": { "type": "metal", "albedo": [0.8, 0.6, 0.2], "prob": 1.0, "fuzz": 1.0 }}, { "type": "triangle", "p1": [-4, 0, -4], "p2": [0, 0, -4], "p3": [-2, 2, -4], "material": 1}, { "type": "triangle", "p1": [0, 0, -4], "p2": [4, 0, -4], "p3": [2, 2, -4], "material": 1}, { "type": "triangle", "p1": [-2, 2, -4], "p2": [2, 2, -4], "p3": [0, 4, -4], "material": 1}, { "type": "quad", "p1": [-20, -1, -20], "p2": [20, -1, -20], "p3": [20, 20, -20], "p4": [-20, 20, -20], "material": 0}, { "type": "quad", "p1": [-20, -1, 20], "p2": [-20, -1, -20], "p3": [-20, 20, -20], "p4": [-20, 20, 20], "material": 0}, + { "type": "quad", "p1": [-20, -1, 20], "p2": [20, -1, 20], "p3": [20, -1, -20], "p4": [-20, -1, -20], "material": 0}, { "type": "quad", "p1": [20, -1, 20], "p2": [20, -1, -20], "p3": [20, 20, -20], "p4": [20, 20, 20], "material": 0}, - { "type": "quad", "p1": [-20, -1, 20], "p2": [20, -1, 20], "p3": [20, -1, -20], "p4": [-20, -1, -20], "material": 0} + { "type": "cube", "p1": [8, 0, 2], "p2": [12, 0, 2], "p3": [12, 4, 2], "p4": [8, 4, 2], "p5": [8, 0, -2], "p6": [12, 0, -2], "p7": [12, 4, -2], "p8": [8, 4, -2], "material": 1} ] } diff --git a/src/main.rs b/src/main.rs index 0575b7a..a0fec5d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,7 +18,6 @@ use crate::ray::Ray; use crate::scenes::scene::Scene; use crate::vec3::Vec3; use dotenv::dotenv; -use log::warn; use rand::RngExt; // TODO: implement scene serialization diff --git a/src/objects.rs b/src/objects.rs index c3057c4..40f7466 100644 --- a/src/objects.rs +++ b/src/objects.rs @@ -3,4 +3,5 @@ pub mod materials; pub mod sphere; pub mod triangle; pub mod quad; +pub mod cube; pub mod traits; diff --git a/src/objects/cube.rs b/src/objects/cube.rs new file mode 100644 index 0000000..9c9de0f --- /dev/null +++ b/src/objects/cube.rs @@ -0,0 +1,49 @@ +use std::sync::Arc; + +use crate::{ + objects::{materials::traits::Material, quad::Quad, traits::Hittable}, + ray::Ray, + vec3::Vec3, +}; + +use super::hit::Hit; + +#[derive(Debug)] +pub struct Cube { + faces: Vec>, + material: Arc, +} + +impl Cube { + pub fn new( + p1: Vec3, + p2: Vec3, + p3: Vec3, + p4: Vec3, + p5: Vec3, + p6: Vec3, + p7: Vec3, + p8: Vec3, + material: Arc, + ) -> Self { + let faces: Vec> = vec![ + Arc::new(Quad::new(p1, p2, p3, p4, material.clone())), + Arc::new(Quad::new(p1, p5, p6, p2, material.clone())), + Arc::new(Quad::new(p2, p6, p7, p3, material.clone())), + Arc::new(Quad::new(p5, p8, p4, p1, material.clone())), + Arc::new(Quad::new(p5, p6, p7, p8, material.clone())), + Arc::new(Quad::new(p4, p3, p7, p8, material.clone())), + ]; + Self { faces, material } + } +} + +impl Hittable for Cube { + fn hit(&self, r: &Ray) -> Option { + Hit::hit_list(&self.faces, r) + } + + fn normal_at(&self, p: &Vec3) -> Vec3 { + todo!() + } +} diff --git a/src/objects/quad.rs b/src/objects/quad.rs index dc1b1f1..ea53fd9 100644 --- a/src/objects/quad.rs +++ b/src/objects/quad.rs @@ -35,7 +35,23 @@ impl Quad { out.push(Sphere::new(self.p3, 1., self.material.clone())); out.push(Sphere::new(self.p4, 1., self.material.clone())); return out; + } + pub fn hit( + p1: Vec3, + p2: Vec3, + p3: Vec3, + p4: Vec3, + material: Arc, + normal: Vec3, + r: &Ray, + ) -> Option { + let isct1 = Triangle::hit(p1, p2, p4, material.clone(), normal, r); + let isct2 = Triangle::hit(p2, p3, p4, material.clone(), normal, r); + if isct1.is_some() { + return isct1; + } + return isct2; } } @@ -53,28 +69,15 @@ impl Debug for Quad { impl Hittable for Quad { fn hit(&self, r: &Ray) -> Option { - let isct1 = Triangle::hit( + Quad::hit( self.p1, - self.p2, - self.p4, - self.material.clone(), - self.normal, - r, - ); - let isct2 = Triangle::hit( self.p2, self.p3, self.p4, self.material.clone(), self.normal, r, - ); - if isct1.is_some() { - return isct1; - } - if isct2.is_some() { - } - return isct2; + ) } fn normal_at(&self, _p: &Vec3) -> Vec3 { diff --git a/src/scenes/scene.rs b/src/scenes/scene.rs index d310ad1..0d1f8c5 100644 --- a/src/scenes/scene.rs +++ b/src/scenes/scene.rs @@ -1,13 +1,13 @@ use std::fmt::Debug; use std::sync::Arc; -use serde_json::error::Error; use log::warn; use serde::Deserialize; use crate::{ camera::Camera, objects::{ + cube::Cube, materials::{ dielectric::Dielectric, lambertian::{Lambertian, Metal}, @@ -113,8 +113,6 @@ impl RawMaterial { } } - - #[derive(Deserialize)] struct RawSphere { pub center: Vec3, @@ -139,12 +137,26 @@ struct RawQuad { pub material: RawMaterial, } +#[derive(Deserialize)] +struct RawCube { + pub p1: Vec3, + pub p2: Vec3, + pub p3: Vec3, + pub p4: Vec3, + pub p5: Vec3, + pub p6: Vec3, + pub p7: Vec3, + pub p8: Vec3, + pub material: RawMaterial, +} + #[derive(Deserialize)] #[serde(tag = "type", rename_all = "lowercase")] enum HittableDef { Sphere(RawSphere), Triangle(RawTriangle), Quad(RawQuad), + Cube(RawCube), } impl HittableDef { @@ -175,6 +187,16 @@ impl HittableDef { None } } + HittableDef::Cube(c) => { + let material = c.material.into_arc(materials); + if let Some(m) = material { + Some(Arc::new(Cube::new( + c.p1, c.p2, c.p3, c.p4, c.p5, c.p6, c.p7, c.p8, m, + ))) + } else { + None + } + } } } }