mpri-graphics-project/periodic_updates.cpp

125 lines
3.0 KiB
C++

#include "periodic_updates.hpp"
#include <ctime>
#include <cmath>
#include <chrono>
#include <GL/glut.h>
struct Movement {
Movement() :
fwd(false),
bck(false),
left(false),
right(false),
turn_l(false),
turn_r(false),
sight_angle(3.14159)
{}
bool
fwd,
bck,
left,
right,
turn_l,
turn_r;
double sight_angle;
void tick() {
sight_angle += (turn_l - turn_r) * .05;
}
Point movement() {
Point front_dir = Point(-sin(sight_angle), 0, -cos(sight_angle)),
left_dir = Point(-cos(sight_angle), 0, sin(sight_angle));
return (fwd - bck) * front_dir
+ (left - right) * left_dir;
}
Point sight() {
return Point(-sin(sight_angle), 0., -cos(sight_angle));
}
};
static Ball* _ball = nullptr;
static std::chrono::time_point<std::chrono::steady_clock>
_last_time, _init_clocks;
static bool is_paused = false;
static double speed_factor = 1.;
static KeyMappings _keymap = KeyMappings::qwerty();
static Movement _movement;
static Point _position(0., 2.5, -10.);
static GlutRender* _render = nullptr;
void init_periodic_static(Ball* ball, GlutRender* render) {
_last_time = std::chrono::steady_clock::now();
_init_clocks = std::chrono::steady_clock::now();
_ball = ball;
_render = render;
}
void set_key_mapping(const KeyMappings& mapping) {
_keymap = mapping;
}
double ellapsed_double(
std::chrono::time_point<std::chrono::steady_clock> beg,
std::chrono::time_point<std::chrono::steady_clock> end)
{
std::chrono::duration<double> ellapsed_db = end - beg;
return ellapsed_db.count();
}
void periodic_update() {
auto now = std::chrono::steady_clock::now();
if(!is_paused)
_ball->update_pos(speed_factor * ellapsed_double(_last_time, now));
_movement.tick();
_position += _movement.movement();
Point look_at = _position + _movement.sight();
_render->set_camera(_position, look_at);
_last_time = now;
glutPostRedisplay();
}
void mvt_keys_update(bool up, unsigned key) {
if(key == _keymap.mv_fwd)
_movement.fwd = !up;
else if(key == _keymap.mv_bck)
_movement.bck = !up;
else if(key == _keymap.mv_left)
_movement.left = !up;
else if(key == _keymap.mv_right)
_movement.right = !up;
else if(key == _keymap.turn_left)
_movement.turn_l = !up;
else if(key == _keymap.turn_right)
_movement.turn_r = !up;
}
void periodic_kb_handler(unsigned char key, int, int) {
if(key == ' ')
is_paused = !is_paused;
else if(key == '<') {
speed_factor -= .1;
if(speed_factor <= 0.05)
speed_factor = .1;
}
else if(key == '>') {
speed_factor += .1;
}
else if(key == '0') {
speed_factor = 1.;
}
mvt_keys_update(false, key);
}
void periodic_kb_up_handler(unsigned char key, int, int) {
mvt_keys_update(true, key);
}