summaryrefslogtreecommitdiff
path: root/racer-tracer
diff options
context:
space:
mode:
authorSakarias Johansson <sakarias.johansson@goodbyekansas.com>2023-03-14 15:39:45 +0100
committerSakarias Johansson <sakariasjohansson@hotmail.com>2023-03-14 20:32:13 +0100
commit7d32f05f6123dc12ab099cf337f9abe137750e43 (patch)
treee30ad8933ae3e71f2beec104abf1ce3bcd1aa329 /racer-tracer
parentf19c8cc40c5caf8abb4f04aaf9f91ec3a8c1ccbc (diff)
downloadracer-tracer-7d32f05f6123dc12ab099cf337f9abe137750e43.tar.gz
racer-tracer-7d32f05f6123dc12ab099cf337f9abe137750e43.tar.xz
racer-tracer-7d32f05f6123dc12ab099cf337f9abe137750e43.zip
🧹 Misc cleanup
- 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.
Diffstat (limited to 'racer-tracer')
-rw-r--r--racer-tracer/src/image_action.rs96
-rw-r--r--racer-tracer/src/image_action/png.rs64
-rw-r--r--racer-tracer/src/image_action/wait_for_signal.rs25
-rw-r--r--racer-tracer/src/main.rs29
-rw-r--r--racer-tracer/src/render.rs45
-rw-r--r--racer-tracer/src/scene.rs19
-rw-r--r--racer-tracer/src/vec3.rs2
7 files changed, 134 insertions, 146 deletions
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<dyn ImageAction> {
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<Vec<u32>>,
- _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::<Vec<u8>>()
- })
- .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<Vec<u32>>,
- 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<Vec<u32>>,
+ _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::<Vec<u8>>()
+ })
+ .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<Vec<u32>>,
+ 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<Vec<u32>> = 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<dyn ImageAction> = (&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<Vec<u32>>,
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<Vec<u32>>,
camera: &RwLock<Camera>,
@@ -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<dyn SceneLoader>) -> Result<Self, TracerError> {
+ pub fn try_new(config_loader: &CSLoader) -> Result<Self, TracerError> {
+ let loader: Box<dyn SceneLoader> = 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<Vec<Box<dyn Hittable>>, TracerError>;
}
-
-impl From<&CSLoader> for Box<dyn SceneLoader> {
- 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
}