Added camera!
- Can be translated locally or moved to a point in the world - Rotates locally around local x- and z-axis and around global y-axis. Added key checks to test camera movement. Added Quaternions (Inherits from CoordinatesVector<double,4>) with a view to handling the camera orientation. Added equality operators for CoordinatesVectors. Removed slow `glutGet()` calls. Added custom reshape callback as we now store the window parameters to avoid some `glutGet()` calls. Renamed `KeyStateManager` to `InputStatus` as it handles more than key states now. Mouse movement callback now captures the cursor, handles its re-centering and when the cursor enters the window far away from its last position. TODO : Consider limiting rotations for the camera (Prevents flipping the head around)
This commit is contained in:
parent
b8036a1c36
commit
459ad7e6c3
11 changed files with 494 additions and 174 deletions
165
src/InputStatus.cpp
Normal file
165
src/InputStatus.cpp
Normal file
|
@ -0,0 +1,165 @@
|
|||
//
|
||||
// Created by trotfunky on 07/10/2019.
|
||||
//
|
||||
|
||||
#include "InputStatus.h"
|
||||
#include <iostream>
|
||||
|
||||
// Initialize static members
|
||||
|
||||
Vec2i InputStatus::window_center;
|
||||
Vec2f InputStatus::mouse_sensitivity{100, 100};
|
||||
|
||||
std::map<unsigned char,bool> InputStatus::ascii_keys_status = {};
|
||||
std::map<int,bool> InputStatus::special_keys_status = {};
|
||||
std::map<int,bool> InputStatus::mouse_button_status = {};
|
||||
|
||||
Vec2i InputStatus::current_mouse_delta;
|
||||
Vec2i InputStatus::last_mouse_delta;
|
||||
Vec2i InputStatus::last_mouse_position;
|
||||
|
||||
void InputStatus::register_glut_callbacks()
|
||||
{
|
||||
glutKeyboardFunc(InputStatus::key_press);
|
||||
glutKeyboardUpFunc(InputStatus::key_up);
|
||||
glutSpecialFunc(InputStatus::special_key_press);
|
||||
glutSpecialUpFunc(InputStatus::special_key_up);
|
||||
|
||||
glutMouseFunc(InputStatus::mouse_click);
|
||||
glutPassiveMotionFunc(InputStatus::mouse_movement);
|
||||
glutMotionFunc(InputStatus::mouse_movement);
|
||||
}
|
||||
|
||||
// ==================
|
||||
// Keyboard
|
||||
// ==================
|
||||
|
||||
bool InputStatus::is_key_pressed(unsigned char key)
|
||||
{
|
||||
if (ascii_keys_status.find(key) == ascii_keys_status.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return ascii_keys_status.at(key);
|
||||
}
|
||||
|
||||
bool InputStatus::is_special_key_pressed(int key)
|
||||
{
|
||||
if (special_keys_status.find(key) == special_keys_status.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return special_keys_status.at(key);
|
||||
}
|
||||
|
||||
void InputStatus::key_press(unsigned char event_key, int mouse_x, int mouse_y)
|
||||
{
|
||||
update_key(event_key,true);
|
||||
mouse_movement(mouse_x,mouse_y);
|
||||
}
|
||||
|
||||
void InputStatus::key_up(unsigned char event_key, int mouse_x, int mouse_y)
|
||||
{
|
||||
update_key(event_key,false);
|
||||
mouse_movement(mouse_x,mouse_y);
|
||||
}
|
||||
|
||||
void InputStatus::special_key_press(int event_key, int mouse_x, int mouse_y)
|
||||
{
|
||||
update_special_key(event_key,true);
|
||||
mouse_movement(mouse_x,mouse_y);
|
||||
}
|
||||
|
||||
void InputStatus::special_key_up(int event_key, int mouse_x, int mouse_y)
|
||||
{
|
||||
update_special_key(event_key,false);
|
||||
mouse_movement(mouse_x,mouse_y);
|
||||
}
|
||||
|
||||
void InputStatus::update_key(unsigned char event_key, bool new_status)
|
||||
{
|
||||
if (ascii_keys_status.find(event_key) != ascii_keys_status.end())
|
||||
{
|
||||
ascii_keys_status.at(event_key) = new_status;
|
||||
}
|
||||
else
|
||||
{
|
||||
ascii_keys_status.insert({event_key,new_status});
|
||||
}
|
||||
}
|
||||
|
||||
void InputStatus::update_special_key(int event_key, bool new_status)
|
||||
{
|
||||
if (special_keys_status.find(event_key) != special_keys_status.end())
|
||||
{
|
||||
special_keys_status.at(event_key) = new_status;
|
||||
}
|
||||
else
|
||||
{
|
||||
special_keys_status.insert({event_key,new_status});
|
||||
}
|
||||
}
|
||||
|
||||
// ==================
|
||||
// Mouse
|
||||
// ==================
|
||||
|
||||
void InputStatus::mouse_movement(int mouse_x, int mouse_y)
|
||||
{
|
||||
Vec2i current_frame;
|
||||
current_frame.x = mouse_x;
|
||||
current_frame.y = mouse_y;
|
||||
|
||||
// Prevent counting the glutWarpPointer movement into account
|
||||
if (current_frame != window_center)
|
||||
{
|
||||
Vec2i frame_delta = current_frame - last_mouse_position;
|
||||
// Prevent jumping around when entering the window
|
||||
if (frame_delta.magnitude() < window_center.magnitude()/10)
|
||||
{
|
||||
current_mouse_delta.x += frame_delta.x;
|
||||
current_mouse_delta.y += frame_delta.y;
|
||||
|
||||
// Re-center mouse
|
||||
glutWarpPointer(window_center.x, window_center.y);
|
||||
}
|
||||
}
|
||||
|
||||
last_mouse_position = current_frame;
|
||||
}
|
||||
|
||||
void InputStatus::mouse_click(int mouse_button, int button_state, int mouse_x, int mouse_y)
|
||||
{
|
||||
bool new_status = button_state == GLUT_DOWN;
|
||||
|
||||
if (mouse_button_status.find(mouse_button) != mouse_button_status.end())
|
||||
{
|
||||
mouse_button_status.at(mouse_button) = new_status;
|
||||
}
|
||||
else
|
||||
{
|
||||
mouse_button_status.insert({mouse_button,new_status});
|
||||
}
|
||||
mouse_movement(mouse_x,mouse_y);
|
||||
}
|
||||
|
||||
bool InputStatus::is_mouse_button_pressed(int mouse_button)
|
||||
{
|
||||
|
||||
if (mouse_button_status.find(mouse_button) == mouse_button_status.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return mouse_button_status.at(mouse_button);
|
||||
}
|
||||
|
||||
const Vec2i& InputStatus::get_mouse_delta(bool update)
|
||||
{
|
||||
if (update)
|
||||
{
|
||||
last_mouse_delta = current_mouse_delta;
|
||||
current_mouse_delta.x = 0;
|
||||
current_mouse_delta.y = 0;
|
||||
}
|
||||
return last_mouse_delta;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue