From 7d32f05f6123dc12ab099cf337f9abe137750e43 Mon Sep 17 00:00:00 2001 From: Sakarias Johansson Date: Tue, 14 Mar 2023 15:39:45 +0100 Subject: =?UTF-8?q?=F0=9F=A7=B9=20Misc=20cleanup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Was pointless to have one event for render and one for cancel. Reduced it to one while fixing a minor bug. - Remove useless dereference and borrow. Not sure how it ended up like that. - Moved around some code. --- racer-tracer/src/image_action.rs | 96 ++---------------------- racer-tracer/src/image_action/png.rs | 64 ++++++++++++++++ racer-tracer/src/image_action/wait_for_signal.rs | 25 ++++++ racer-tracer/src/main.rs | 29 +++---- racer-tracer/src/render.rs | 45 +++++------ racer-tracer/src/scene.rs | 19 ++--- racer-tracer/src/vec3.rs | 2 +- 7 files changed, 134 insertions(+), 146 deletions(-) create mode 100644 racer-tracer/src/image_action/png.rs create mode 100644 racer-tracer/src/image_action/wait_for_signal.rs diff --git a/racer-tracer/src/image_action.rs b/racer-tracer/src/image_action.rs index 825c506..d6d212c 100644 --- a/racer-tracer/src/image_action.rs +++ b/racer-tracer/src/image_action.rs @@ -1,8 +1,12 @@ -use std::{path::PathBuf, sync::RwLock}; +pub mod png; +pub mod wait_for_signal; + +use std::sync::RwLock; -use sha2::{Digest, Sha256}; use synchronoise::SignalEvent; +use crate::image_action::{png::SavePng, wait_for_signal::WaitForSignal}; + use crate::{ config::{Config, ImageAction as CImageAction}, error::TracerError, @@ -20,92 +24,8 @@ pub trait ImageAction: Send + Sync { impl From<&CImageAction> for Box { fn from(image_action: &CImageAction) -> Self { match image_action { - CImageAction::WaitForSignal => Box::new(WaitForSignal::new()), - CImageAction::SavePng => Box::new(SavePng::new()), + CImageAction::WaitForSignal => Box::new(WaitForSignal {}), + CImageAction::SavePng => Box::new(SavePng {}), } } } - -pub struct SavePng {} - -impl SavePng { - pub fn new() -> Self { - Self {} - } -} - -impl ImageAction for SavePng { - fn action( - &self, - screen_buffer: &RwLock>, - _event: &SignalEvent, - config: &Config, - ) -> Result<(), TracerError> { - screen_buffer - .read() - .map_err(|e| TracerError::FailedToAcquireLock(e.to_string())) - .map(|buf| { - // Convert ARGB8 to RGBA8 - buf.iter() - .map(|v| { - let a: u32 = (v >> 24) & 0xff; - let r: u32 = (v >> 16) & 0xff; - let g: u32 = (v >> 8) & 0xff; - let b: u32 = v & 0xff; - - (r << 24) | (g << 16) | (b << 8) | a - }) - .flat_map(|val| val.to_be_bytes()) - .collect::>() - }) - .and_then(|buf| match &config.image_output_dir { - Some(image_dir) => { - println!("Saving image..."); - let mut sha = Sha256::new(); - - sha.update(buf.as_slice()); - - let mut file_path = PathBuf::from(image_dir); - file_path.push(format!("{:X}.png", sha.finalize())); - - img::save_buffer( - file_path.as_path(), - buf.as_slice(), - config.screen.width as u32, - config.screen.height as u32, - img::ColorType::Rgba8, - ) - .map_err(|e| { - let error = e.to_string(); - TracerError::ImageSave(error) - }) - .map(|_| { - println!("Saved image to: {}", file_path.to_string_lossy()); - }) - } - None => Ok(()), - }) - } -} - -pub struct WaitForSignal {} - -impl WaitForSignal { - pub fn new() -> Self { - Self {} - } -} - -impl ImageAction for WaitForSignal { - fn action( - &self, - _screen_buffer: &RwLock>, - event: &SignalEvent, - _config: &Config, - ) -> Result<(), TracerError> { - println!("Press R to resume."); - event.wait(); - event.reset(); - Ok(()) - } -} diff --git a/racer-tracer/src/image_action/png.rs b/racer-tracer/src/image_action/png.rs new file mode 100644 index 0000000..c43e863 --- /dev/null +++ b/racer-tracer/src/image_action/png.rs @@ -0,0 +1,64 @@ +use std::{path::PathBuf, sync::RwLock}; + +use sha2::{Digest, Sha256}; +use synchronoise::SignalEvent; + +use crate::{config::Config, error::TracerError}; + +use super::ImageAction; + +pub struct SavePng {} + +impl ImageAction for SavePng { + fn action( + &self, + screen_buffer: &RwLock>, + _event: &SignalEvent, + config: &Config, + ) -> Result<(), TracerError> { + screen_buffer + .read() + .map_err(|e| TracerError::FailedToAcquireLock(e.to_string())) + .map(|buf| { + // Convert ARGB8 to RGBA8 + buf.iter() + .map(|v| { + let a: u32 = (v >> 24) & 0xff; + let r: u32 = (v >> 16) & 0xff; + let g: u32 = (v >> 8) & 0xff; + let b: u32 = v & 0xff; + + (r << 24) | (g << 16) | (b << 8) | a + }) + .flat_map(|val| val.to_be_bytes()) + .collect::>() + }) + .and_then(|buf| match &config.image_output_dir { + Some(image_dir) => { + println!("Saving image..."); + let mut sha = Sha256::new(); + + sha.update(buf.as_slice()); + + let mut file_path = PathBuf::from(image_dir); + file_path.push(format!("{:X}.png", sha.finalize())); + + img::save_buffer( + file_path.as_path(), + buf.as_slice(), + config.screen.width as u32, + config.screen.height as u32, + img::ColorType::Rgba8, + ) + .map_err(|e| { + let error = e.to_string(); + TracerError::ImageSave(error) + }) + .map(|_| { + println!("Saved image to: {}", file_path.to_string_lossy()); + }) + } + None => Ok(()), + }) + } +} diff --git a/racer-tracer/src/image_action/wait_for_signal.rs b/racer-tracer/src/image_action/wait_for_signal.rs new file mode 100644 index 0000000..54480ac --- /dev/null +++ b/racer-tracer/src/image_action/wait_for_signal.rs @@ -0,0 +1,25 @@ +use std::sync::RwLock; + +use synchronoise::SignalEvent; + +use crate::{config::Config, error::TracerError}; + +use super::ImageAction; + +pub struct WaitForSignal {} + +impl ImageAction for WaitForSignal { + fn action( + &self, + _screen_buffer: &RwLock>, + event: &SignalEvent, + _config: &Config, + ) -> Result<(), TracerError> { + if !event.status() { + println!("Press R to resume."); + event.wait(); + } + event.reset(); + Ok(()) + } +} diff --git a/racer-tracer/src/main.rs b/racer-tracer/src/main.rs index 6648c81..0c65208 100644 --- a/racer-tracer/src/main.rs +++ b/racer-tracer/src/main.rs @@ -40,6 +40,7 @@ fn run(config: Config) -> Result<(), TracerError> { let screen_buffer: RwLock> = RwLock::new(vec![0; image.width * image.height]); let look_from = Vec3::new(13.0, 2.0, 3.0); let look_at = Vec3::new(0.0, 0.0, 0.0); + let camera_speed = 2.0; let camera = RwLock::new(Camera::new( look_from, look_at, @@ -50,13 +51,12 @@ fn run(config: Config) -> Result<(), TracerError> { 10.0, )); - let scene = Scene::try_new((&config.loader).into())?; + let scene = Scene::try_new(&config.loader)?; let mut window_res: Result<(), TracerError> = Ok(()); let mut render_res: Result<(), TracerError> = Ok(()); let render_image = SignalEvent::manual(false); - let cancel_render = SignalEvent::manual(false); let exit = SignalEvent::manual(false); let image_action: Box = (&config.image_action).into(); @@ -73,6 +73,7 @@ fn run(config: Config) -> Result<(), TracerError> { .then_some(|| ()) .map_or_else( || { + render_image.reset(); // Render preview render( &screen_buffer, @@ -85,6 +86,7 @@ fn run(config: Config) -> Result<(), TracerError> { ) }, |_| { + render_image.reset(); let render_time = Instant::now(); render( &screen_buffer, @@ -92,11 +94,10 @@ fn run(config: Config) -> Result<(), TracerError> { &image, &scene, &config.render, - Some(&cancel_render), + Some(&render_image), None, ) .and_then(|_| { - render_image.reset(); println!( "It took {} seconds to render the image.", Instant::now().duration_since(render_time).as_secs() @@ -134,15 +135,7 @@ fn run(config: Config) -> Result<(), TracerError> { std::thread::sleep(std::time::Duration::from_millis(10)); if window.is_key_released(Key::R) { - if render_image.status() { - // Signal cancel - cancel_render.signal(); - render_image.reset(); - } else { - // Signal render - render_image.signal(); - cancel_render.reset(); - } + render_image.signal(); } camera @@ -150,15 +143,15 @@ fn run(config: Config) -> Result<(), TracerError> { .map_err(|e| TracerError::FailedToAcquireLock(e.to_string())) .map(|mut cam| { if window.is_key_down(Key::W) { - cam.go_forward(-dt); + cam.go_forward(-dt * camera_speed); } else if window.is_key_down(Key::S) { - cam.go_forward(dt); + cam.go_forward(dt * camera_speed); } if window.is_key_down(Key::A) { - cam.go_right(-dt); + cam.go_right(-dt * camera_speed); } else if window.is_key_down(Key::D) { - cam.go_right(dt); + cam.go_right(dt * camera_speed); } })?; @@ -172,7 +165,7 @@ fn run(config: Config) -> Result<(), TracerError> { })? } exit.signal(); - cancel_render.signal(); + render_image.signal(); Ok(()) }); }); diff --git a/racer-tracer/src/render.rs b/racer-tracer/src/render.rs index fefafce..6926091 100644 --- a/racer-tracer/src/render.rs +++ b/racer-tracer/src/render.rs @@ -1,4 +1,4 @@ -use std::{borrow::Borrow, sync::RwLock, time::Duration}; +use std::{sync::RwLock, time::Duration}; use rayon::prelude::*; use synchronoise::SignalEvent; @@ -34,6 +34,21 @@ fn ray_color(scene: &dyn Hittable, ray: &Ray, depth: usize) -> Vec3 { (1.0 - t) * first_color + t * second_color } +fn do_cancel(cancel_event: Option<&SignalEvent>) -> bool { + match cancel_event { + Some(event) => event.wait_timeout(Duration::from_secs(0)), + None => false, + } +} + +fn get_highest_divdable(value: usize, mut div: usize) -> usize { + // Feels like there could possibly be some other nicer trick to this. + while (value % div) != 0 { + div -= 1; + } + div +} + pub fn raytrace_scaled( buffer: &RwLock>, cancel_event: Option<&SignalEvent>, @@ -146,21 +161,6 @@ pub fn raytrace( }) } -fn do_cancel(cancel_event: Option<&SignalEvent>) -> bool { - match cancel_event { - Some(event) => event.wait_timeout(Duration::from_secs(0)), - None => false, - } -} - -fn get_highest_divdable(value: usize, mut div: usize) -> usize { - // Feels like there could possibly be some other nicer trick to this. - while (value % div) != 0 { - div -= 1; - } - div -} - pub fn render( buffer: &RwLock>, camera: &RwLock, @@ -228,21 +228,12 @@ pub fn render( .into_par_iter() .map(|image| { scale.map_or_else( - || { - raytrace( - buffer, - cancel_event, - (*scene).borrow(), - cam.clone(), - &image, - data, - ) - }, + || raytrace(buffer, cancel_event, scene, cam.clone(), &image, data), |_| { raytrace_scaled( buffer, cancel_event, - (*scene).borrow(), + scene, cam.clone(), &image, data, diff --git a/racer-tracer/src/scene.rs b/racer-tracer/src/scene.rs index 12e2296..e730db0 100644 --- a/racer-tracer/src/scene.rs +++ b/racer-tracer/src/scene.rs @@ -12,8 +12,13 @@ pub struct Scene { } impl Scene { - #[allow(dead_code)] - pub fn try_new(loader: Box) -> Result { + pub fn try_new(config_loader: &CSLoader) -> Result { + let loader: Box = match config_loader { + CSLoader::Yml { path } => Box::new(YmlLoader::new(path.clone())), + CSLoader::Random => Box::new(Random::new()), + CSLoader::None => Box::new(NoneLoader::new()), + }; + loader.load().map(|objects| Self { objects }) } @@ -47,13 +52,3 @@ impl Hittable for Scene { pub trait SceneLoader: Send + Sync { fn load(&self) -> Result>, TracerError>; } - -impl From<&CSLoader> for Box { - fn from(loader: &CSLoader) -> Self { - match loader { - CSLoader::Yml { path } => Box::new(YmlLoader::new(path.clone())), - CSLoader::Random => Box::new(Random::new()), - CSLoader::None => Box::new(NoneLoader::new()), - } - } -} diff --git a/racer-tracer/src/vec3.rs b/racer-tracer/src/vec3.rs index e315203..281fb26 100644 --- a/racer-tracer/src/vec3.rs +++ b/racer-tracer/src/vec3.rs @@ -87,7 +87,7 @@ impl Vec3 { let red: u32 = (self.data[0] * 255.0) as u32; let green: u32 = (self.data[1] * 255.0) as u32; let blue: u32 = (self.data[2] * 255.0) as u32; - // ARGB + // XRGB (255 << 24) | (red << 16) | green << 8 | blue } -- cgit v1.2.3