aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreug-vs <eugene@eug-vs.xyz>2021-10-28 00:54:26 +0300
committereug-vs <eugene@eug-vs.xyz>2021-10-28 00:54:26 +0300
commit7e4d84eb99ed3f9e3681c3cdda0c5de3b91ef90a (patch)
tree18a3c28af298b15d5ea62c8829e501652066664e
parent8b2dd268c48d45c7bced63fac1684052568e8f94 (diff)
downloadpistol-7e4d84eb99ed3f9e3681c3cdda0c5de3b91ef90a.tar.gz
feat: use Matrix to compute screen position
-rw-r--r--src/camera.rs27
-rw-r--r--src/main.rs14
2 files changed, 21 insertions, 20 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;
}
}
diff --git a/src/main.rs b/src/main.rs
index b83498d..b288918 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -3,15 +3,15 @@ extern crate ncurses;
mod camera;
mod canvas;
use std::{f32::consts::PI, time::Instant};
-use cgmath::{Angle, InnerSpace, Matrix3, Rad, Vector3};
+use cgmath::{Angle, InnerSpace, Matrix3, Rad, Vector3, Zero};
use ncurses::*;
use crate::camera::{Buffer, Camera, WIDTH, HEIGHT};
fn main() {
let mut cam = Camera {
- position: Vector3 { x: 0.0, y: -0.7, z: 0.0 },
- direction: Vector3 { x: 1.0, y: 0.0, z: 0.0 }.normalize(),
+ position: Vector3::zero(),
+ direction: Vector3::unit_x(),
up: Vector3::unit_z(),
light: Vector3 { x: 1.0, y: 1.0, z: -1.0 }.normalize(),
angle: PI / 2.0,
@@ -53,15 +53,15 @@ fn main() {
} else if char == 106 { // j to move backward
cam.position -= cam.direction * cam.speed;
} else if char == 72 { // H to move left
- cam.position -= Matrix3::from_axis_angle(cam.up, Rad::turn_div_4()) * cam.direction * cam.speed;
- } else if char == 76 { // L to move right
cam.position += Matrix3::from_axis_angle(cam.up, Rad::turn_div_4()) * cam.direction * cam.speed;
+ } else if char == 76 { // L to move right
+ cam.position -= Matrix3::from_axis_angle(cam.up, Rad::turn_div_4()) * cam.direction * cam.speed;
} else if char == 104 { // h to rotate left
- let rotation = Matrix3::from_angle_z(-Rad::full_turn() / cam.turn_rate);
+ let rotation = Matrix3::from_angle_z(Rad::full_turn() / cam.turn_rate);
cam.direction = rotation * cam.direction;
cam.up = rotation * cam.up;
} else if char == 108 { // l to rotate right
- let rotation = Matrix3::from_angle_z(Rad::full_turn() / cam.turn_rate);
+ let rotation = Matrix3::from_angle_z(-Rad::full_turn() / cam.turn_rate);
cam.direction = rotation * cam.direction;
cam.up = rotation * cam.up;
} else if char == 75 { // K to rotate up