diff options
author | eug-vs <eugene@eug-vs.xyz> | 2021-10-28 00:54:26 +0300 |
---|---|---|
committer | eug-vs <eugene@eug-vs.xyz> | 2021-10-28 00:54:26 +0300 |
commit | 7e4d84eb99ed3f9e3681c3cdda0c5de3b91ef90a (patch) | |
tree | 18a3c28af298b15d5ea62c8829e501652066664e | |
parent | 8b2dd268c48d45c7bced63fac1684052568e8f94 (diff) | |
download | pistol-7e4d84eb99ed3f9e3681c3cdda0c5de3b91ef90a.tar.gz |
feat: use Matrix to compute screen position
-rw-r--r-- | src/camera.rs | 27 | ||||
-rw-r--r-- | src/main.rs | 14 |
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 |