80 lines
2.0 KiB
Rust
80 lines
2.0 KiB
Rust
// camera.rs
|
|
|
|
use nalgebra::*;
|
|
|
|
use crate::renderer::{Ray,Intersection};
|
|
use crate::elements::*;
|
|
|
|
|
|
enum Camera {
|
|
OrthoCamera(OrthoCamera),
|
|
PerspectiveCamera(PerspectiveCamera),
|
|
}
|
|
|
|
// TODO: Create a separate scene object
|
|
pub trait RaySource {
|
|
fn trace(&self, ray: &Ray) -> Option<Intersection>;
|
|
}
|
|
|
|
pub struct OrthoCamera {
|
|
pub pos: Vec3<f64>,
|
|
pub output_img: bmp::Image,
|
|
pub elements: Vec<Element>,
|
|
pub lights: Vec<LightSrc>,
|
|
//spheres: Vec<Sphere>,
|
|
//light: LightSrc,
|
|
|
|
pub shadow_bias: f64,
|
|
pub max_recursion_depth: u32
|
|
}
|
|
|
|
impl RaySource for OrthoCamera {
|
|
fn trace(&self, ray: &Ray) -> Option<Intersection> {
|
|
self.elements.iter()
|
|
.filter_map(|s| s.intersect(ray).map(|d| Intersection::new(d, s) ))
|
|
.min_by(|i1, i2| i1.distance.partial_cmp(&i2.distance).unwrap())
|
|
}
|
|
}
|
|
|
|
pub struct PerspectiveCamera {
|
|
pub pos: Vec3<f64>,
|
|
pub output_img: bmp::Image,
|
|
pub elements: Vec<Element>,
|
|
pub lights: Vec<LightSrc>,
|
|
pub shadow_bias: f64,
|
|
pub max_recursion_depth: u32,
|
|
pub fov: f64,
|
|
pub scene_width: u32,
|
|
pub scene_height: u32,
|
|
}
|
|
|
|
impl PerspectiveCamera {
|
|
pub fn create_prime(&self, x: u32, y: u32) -> Ray {
|
|
let sensor_x = ((x as f64 + 0.5) / self.scene_width as f64) * 2.0 - 1.0;
|
|
let sensor_y = 1.0 - ((y as f64 + 0.5) / self.scene_height as f64) * 2.0;
|
|
|
|
Ray {
|
|
pos: self.pos,
|
|
dir: Vec3::new(sensor_x, sensor_y, 1.0).normalize(),
|
|
}
|
|
}
|
|
|
|
pub fn percent_complete(&self, row: u32) -> f64 {
|
|
let float_row = row as f64;
|
|
let float_scene_height = self.scene_height as f64;
|
|
let float_scene_width = self.scene_width as f64;
|
|
|
|
((float_row * float_scene_width) / (float_scene_width * float_scene_height)) * 100.0
|
|
}
|
|
}
|
|
|
|
impl RaySource for PerspectiveCamera {
|
|
fn trace(&self, ray: &Ray) -> Option<Intersection> {
|
|
self.elements.iter()
|
|
.filter_map(|s| s.intersect(ray).map(|d| Intersection::new(d, s) ))
|
|
.min_by(|i1, i2| i1.distance.partial_cmp(&i2.distance).unwrap())
|
|
}
|
|
}
|
|
|
|
|