aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoreug-vs <eugene@eug-vs.xyz>2021-10-27 23:05:14 +0300
committereug-vs <eugene@eug-vs.xyz>2021-10-27 23:06:45 +0300
commit8b2dd268c48d45c7bced63fac1684052568e8f94 (patch)
tree983d53551d57be4b38aa07c3c0a622a5afa37c1f /src
parent28b63fcbbbdc6a1b7ba50ef2f6734b060a735c8c (diff)
downloadpistol-8b2dd268c48d45c7bced63fac1684052568e8f94.tar.gz
feat: more sophisticated camera movement
Diffstat (limited to 'src')
-rw-r--r--src/camera.rs11
-rw-r--r--src/main.rs56
2 files changed, 44 insertions, 23 deletions
diff --git a/src/camera.rs b/src/camera.rs
index 204b9f8..c620b24 100644
--- a/src/camera.rs
+++ b/src/camera.rs
@@ -1,8 +1,6 @@
-use cgmath::Matrix3;
-use cgmath::Rad;
use cgmath::Vector3;
use cgmath::prelude::*;
-use std::{cmp::{max, min}, f32::consts::PI, fmt};
+use std::fmt;
type Vector = Vector3<f32>;
@@ -29,12 +27,15 @@ pub struct Camera {
pub time: f32,
pub position: Vector,
pub direction: Vector,
+ pub up: Vector,
pub light: Vector,
pub angle: f32,
pub distance: f32,
pub brightness: f32,
pub aspect_ratio: f32,
pub buffer: Buffer,
+ pub speed: f32,
+ pub turn_rate: f32,
}
fn softmin(left: f32, right: f32, k: f32) -> f32 {
@@ -97,8 +98,8 @@ impl Camera {
let palette = "$@B%8&WM#oahkbdpqwmZO0QLCJUYXzcvunxrjft/\\|()1{}[]?-_+~<>i!lI;:,\"^`'. ";
let (screen_width, screen_height) = self.screen();
- let h_step = Matrix3::from_angle_z(Rad::turn_div_4()) * self.direction * screen_width / WIDTH as f32;
- let v_step = Vector { x: 0.0, y: 0.0, z: -screen_height / HEIGHT as f32 };
+ 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);
// Initialize with a corner
diff --git a/src/main.rs b/src/main.rs
index 8f11bdd..b83498d 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -12,6 +12,7 @@ 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(),
+ up: Vector3::unit_z(),
light: Vector3 { x: 1.0, y: 1.0, z: -1.0 }.normalize(),
angle: PI / 2.0,
distance: 1.0,
@@ -19,6 +20,8 @@ fn main() {
brightness: 5.0,
buffer: Buffer([[' '; WIDTH as usize]; HEIGHT as usize]),
time: 0.0,
+ speed: 0.5,
+ turn_rate: 30.0,
};
initscr();
@@ -36,7 +39,7 @@ fn main() {
addstr(&cam.buffer.to_string());
addstr(&format!("\nRendered in {:?} ({:.0} FPS)\n", timestamp.elapsed(), 1.0 / timestamp.elapsed().as_secs_f64()));
addstr(&format!("Camera: {:?}\n", cam.position));
- addstr(&format!("Facing: {:?}\n", cam.direction));
+ addstr(&format!("Facing: {:?}, Up: {:?}\n", cam.direction, cam.up));
addstr(&format!("Light: {:?}\n", cam.light));
refresh();
@@ -45,27 +48,44 @@ fn main() {
addstr(&format!("\nPressed: {:?}\n", char));
refresh();
- let cam_speed = 0.5;
- let cam_turn_rate = 30.0;
-
- if char == 106 || char == 74 {
- cam.position -= cam.direction * cam_speed;
- } else if char == 107 || char == 75 {
- cam.position += cam.direction * cam_speed;
- } else if char == 104 {
- cam.direction = Matrix3::from_angle_z(-Rad::full_turn() / cam_turn_rate) * cam.direction;
- } else if char == 108 {
- cam.direction = Matrix3::from_angle_z(Rad::full_turn() / cam_turn_rate) * cam.direction;
- } else if char == 72 {
- cam.position -= Matrix3::from_angle_z(Rad::turn_div_4()) * cam.direction * cam_speed;
- } else if char == 76 {
- cam.position += Matrix3::from_angle_z(Rad::turn_div_4()) * cam.direction * cam_speed;
+ if char == 107 { // k to move forward
+ cam.position += cam.direction * cam.speed;
+ } 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 == 104 { // h to rotate left
+ 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);
+ cam.direction = rotation * cam.direction;
+ cam.up = rotation * cam.up;
+ } else if char == 75 { // K to rotate up
+ let axis = cam.up.cross(cam.direction);
+ let angle = -Rad::full_turn() / cam.turn_rate;
+ let rotation = Matrix3::from_axis_angle(axis, angle);
+ cam.up = rotation * cam.up;
+ cam.direction = rotation * cam.direction;
+ } else if char == 74 { // J to rotate down
+ let axis = cam.up.cross(cam.direction);
+ let angle = Rad::full_turn() / cam.turn_rate;
+ let rotation = Matrix3::from_axis_angle(axis, angle);
+ cam.up = rotation * cam.up;
+ cam.direction = rotation * cam.direction;
+ } else if char == 117 { // u to move up along Z
+ cam.position += Vector3::unit_z() * cam.speed;
+ } else if char == 100 { // d to move down along Z
+ cam.position -= Vector3::unit_z() * cam.speed;
} else if char == 70 { // F to reverse camera direction
cam.direction = -cam.direction;
} else if char == 101 { // e to change lights
- cam.light = Matrix3::from_angle_z(Rad::turn_div_2() / cam_turn_rate) * cam.light;
+ cam.light = Matrix3::from_angle_z(Rad::turn_div_2() / cam.turn_rate) * cam.light;
} else if char == 69 { // E to change lights vertically
- cam.light = Matrix3::from_angle_y(Rad::turn_div_2() / cam_turn_rate) * cam.light;
+ cam.light = Matrix3::from_angle_y(Rad::turn_div_2() / cam.turn_rate) * cam.light;
}
}