aboutsummaryrefslogtreecommitdiff
path: root/src/main.rs
blob: aa5a456540f5eb96259b6acd5b81dd8c7bf6135e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
extern crate ncurses;

mod camera;
mod canvas;
use std::{f32::consts::PI, time::Instant};
use cgmath::{Angle, InnerSpace, Matrix3, Rad, Vector3};
use ncurses::*;

use crate::camera::{Camera, WIDTH, HEIGHT};

fn main() {
    let mut cam = Camera {
        position: Vector3::new(-5.0, 0.0, 2.0),
        direction: Vector3::unit_x(),
        up: Vector3::unit_z(),
        light: Vector3 { x: 1.0, y: 1.0, z: -1.0 }.normalize(),
        angle: PI / 2.0,
        distance: 1.0,
        aspect_ratio: 2.0 * HEIGHT as f32 / WIDTH as f32,
        brightness: 5.0,
        time: 0.0,
        speed: 0.5,
        turn_rate: 30.0,
        width: 2.0,
        height: 4.0 * HEIGHT as f32 / WIDTH as f32,
        palette: "$@B%8&WM#oahkbdpqwmZO0QLCJUYXzcvunxrjft/\\|()1{}[]?-_+~<>i!lI;:,\"^`'. ".chars().collect(),
    };

    initscr();

    while true {
        clear();
        flushinp();

        // Render
        cam.time += 1.0;
        let timestamp = Instant::now();
        cam.render();
        addstr(&format!("\nRendered in {:?} ({:.0} FPS)\n", timestamp.elapsed(), 1.0 / timestamp.elapsed().as_secs_f64()));
        addstr(&format!("\nTime: {:?}\n", cam.time));
        addstr(&format!("Camera: {:?}\n", cam.position));
        addstr(&format!("Facing: {:?}, Up: {:?}\n", cam.direction, cam.up));
        addstr(&format!("Light: {:?}\n", cam.light));
        refresh();

        // Handle input
        let char = getch();
        addstr(&format!("\nPressed: {:?}\n", char));
        refresh();

        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;
        } else if char == 69 { // E to change lights vertically
            cam.light = Matrix3::from_angle_y(Rad::turn_div_2() / cam.turn_rate) * cam.light;
        }
    }

    endwin();
}