use std::cell::OnceCell; use crate::{ examples::ExampleSceneEnum, triangle_bvh::{BVHMaterial, Triangle, TriangleBVH}, }; use super::ExampleScene; use ray_tracing_core::{light::AreaLight, prelude::*, scene::Scene}; use ray_tracing_material::{diffuse::DiffuseMaterial, mirror::Mirror}; pub struct BasicCornell { scene: OnceCell>, } impl BasicCornell { pub fn new() -> Self { BasicCornell { scene: OnceCell::new(), } } } impl Default for BasicCornell { fn default() -> Self { Self::new() } } impl ExampleScene for BasicCornell { fn get_scene(&self) -> ExampleSceneEnum { let s = self.scene.get_or_init(|| { let side_length = 1.5; let light_size = 0.5; let light_offset = 0.01; let box_size = 0.3; TriangleBVH::new( vec![ Pos3::new(side_length, side_length, side_length), Pos3::new(side_length, side_length, -side_length), Pos3::new(side_length, -side_length, side_length), Pos3::new(side_length, -side_length, -side_length), Pos3::new(-side_length, side_length, side_length), Pos3::new(-side_length, side_length, -side_length), Pos3::new(-side_length, -side_length, side_length), Pos3::new(-side_length, -side_length, -side_length), Pos3::new(light_size, side_length - light_offset, light_size), Pos3::new(light_size, side_length - light_offset, -light_size), Pos3::new(-light_size, side_length - light_offset, light_size), Pos3::new(-light_size, side_length - light_offset, -light_size), Pos3::new(box_size, -side_length, 0.0), Pos3::new(0.0, -side_length, -box_size), Pos3::new(-box_size, -side_length, 0.0), Pos3::new(0.0, -side_length, box_size), Pos3::new(0.0, box_size - side_length, 0.0), ], vec![ Triangle::new([0, 1, 2], 0), Triangle::new([1, 3, 2], 0), Triangle::new([0, 4, 1], 0), Triangle::new([1, 4, 5], 0), Triangle::new([2, 3, 6], 0), Triangle::new([3, 7, 6], 0), Triangle::new([0, 2, 4], 1), Triangle::new([6, 4, 2], 1), Triangle::new([1, 5, 3], 2), Triangle::new([7, 3, 5], 2), Triangle::new([8, 10, 9], 3), Triangle::new([11, 9, 10], 3), Triangle::new([12, 13, 16], 4), Triangle::new([13, 14, 16], 4), Triangle::new([14, 15, 16], 4), Triangle::new([15, 12, 16], 4), ], vec![ BVHMaterial { material: Some(Box::new(DiffuseMaterial::new(Color::new(0.8, 0.8, 0.8)))), light: None, }, BVHMaterial { material: Some(Box::new(DiffuseMaterial::new(Color::new(0.9, 0.0, 0.0)))), light: None, }, BVHMaterial { material: Some(Box::new(DiffuseMaterial::new(Color::new(0.0, 0.9, 0.0)))), light: None, }, BVHMaterial { material: None, light: Some(Box::new(AreaLight::new(Color::white() * 18.0))), }, BVHMaterial { material: Some(Box::new(Mirror::new(Color::new(1.0, 1.0, 1.0)))), light: None, }, ], ) }); ExampleSceneEnum::TriangleBVH(s.clone()) } fn get_camera_pos(&self) -> Pos3 { Pos3::new(-6.0, 0.0, 0.0) } fn get_camera_look_at(&self) -> Pos3 { Pos3::new(0.0, 0.0, 0.0) } fn get_camera_up(&self) -> Dir3 { Dir3::up() } fn get_horizontal_fov(&self) -> Float { Float::to_radians(90.0) } }