aboutsummaryrefslogtreecommitdiff
path: root/src/camera.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/camera.rs')
-rw-r--r--src/camera.rs27
1 files changed, 14 insertions, 13 deletions
diff --git a/src/camera.rs b/src/camera.rs
index c620b24..31a0c5e 100644
--- a/src/camera.rs
+++ b/src/camera.rs
@@ -1,3 +1,4 @@
+use cgmath::Matrix3;
use cgmath::Vector3;
use cgmath::prelude::*;
use std::fmt;
@@ -98,27 +99,27 @@ impl Camera {
let palette = "$@B%8&WM#oahkbdpqwmZO0QLCJUYXzcvunxrjft/\\|()1{}[]?-_+~<>i!lI;:,\"^`'. ";
let (screen_width, screen_height) = self.screen();
- let h_step = self.up.cross(self.direction) * screen_width / WIDTH as f32;
- let v_step = -self.up * screen_height / HEIGHT as f32;
- // println!("Steps: h{}, v{}", h_step, v_step);
+ let cross = self.up.cross(self.direction);
- // Initialize with a corner
- let point = self.position + (self.direction.normalize() * self.distance) - (h_step * (WIDTH / 2) as f32 + v_step * (HEIGHT / 2) as f32);
- // println!("Corner: {}", point);
-
- let mut ray_dir = point - self.position;
+ // Linear transormation operator for calculating screen position
+ // Assumes "initial" screen is perpendicular to OX
+ // and it's bottom edge is parallel to OY
+ let operator = Matrix3::from_cols(
+ self.direction * self.distance,
+ cross * screen_width,
+ self.up * screen_height,
+ );
for i in 0..HEIGHT as usize {
- ray_dir = ray_dir + v_step;
+ let ix = i as f32 / HEIGHT as f32;
for j in 0..WIDTH as usize {
- ray_dir = ray_dir + h_step;
-
+ let jx = j as f32 / WIDTH as f32;
+ // Apply transform to unit square centered at (1, 0, 0)
+ let ray_dir = operator * Vector { x: 1.0, y: 0.5 - jx, z: 0.5 - ix };
let brightness = self.shoot_ray(ray_dir);
self.buffer.0[i][j] = palette.chars().nth((brightness * palette.len() as f32) as usize - 1).unwrap();
- // println!("[{}, {}]: {}", i, j, ray_dir);
}
- ray_dir = ray_dir - h_step * WIDTH as f32;
}
}