File include/jen/screen.h changed (mode: 100644) (index ff80850..e60d4d6) |
... |
... |
struct jen::screen::Noclip |
43 |
43 |
/// @param move_spd Initial movement speed per second |
/// @param move_spd Initial movement speed per second |
44 |
44 |
/// @param window Used to access user input |
/// @param window Used to access user input |
45 |
45 |
void init(const Window &window, float view_sens, float move_spd) { |
void init(const Window &window, float view_sens, float move_spd) { |
46 |
|
this->cursor_pos = window.cursor; |
|
47 |
46 |
camera.position = {}; |
camera.position = {}; |
48 |
47 |
camera.pos_offset = {}; |
camera.pos_offset = {}; |
49 |
48 |
camera.offset_shift = {}; |
camera.offset_shift = {}; |
|
... |
... |
struct jen::screen::Noclip |
53 |
52 |
frustum.zNear = 0.5; |
frustum.zNear = 0.5; |
54 |
53 |
frustum.zFar = 32000; |
frustum.zFar = 32000; |
55 |
54 |
view_sensitivity = view_sens; |
view_sensitivity = view_sens; |
|
55 |
|
speed_sensitivity = 0.05f; |
56 |
56 |
move_speed = move_spd; |
move_speed = move_spd; |
57 |
57 |
} |
} |
58 |
58 |
/// @brief Update camera state from user input and also aspect ratio. |
/// @brief Update camera state from user input and also aspect ratio. |
59 |
59 |
/// Controls: |
/// Controls: |
60 |
60 |
/// - 'Q' and 'E' rotate camera around lookat vector |
/// - 'Q' and 'E' rotate camera around lookat vector |
61 |
61 |
/// - 'W'A'S'D' to move forward, left, back and right |
/// - 'W'A'S'D' to move forward, left, back and right |
62 |
|
/// - '=' to increase moving speed |
|
63 |
|
/// - '-' to decrease moving speed |
|
|
62 |
|
/// - scroll to modify moving speed |
64 |
63 |
/// - 'z' to multiply the clipping plane |
/// - 'z' to multiply the clipping plane |
65 |
64 |
/// - 'x' to divide clipping plane |
/// - 'x' to divide clipping plane |
66 |
65 |
/// - horizontal mouse movement to rotate the camera left or right, |
/// - horizontal mouse movement to rotate the camera left or right, |
|
... |
... |
struct jen::screen::Noclip |
85 |
84 |
sign = get_sign(window.is_on(Key::A), window.is_on(Key::D)); |
sign = get_sign(window.is_on(Key::A), window.is_on(Key::D)); |
86 |
85 |
if (sign != 0) |
if (sign != 0) |
87 |
86 |
camera.position -= camera.axis.x * elapsed_secs * move_speed * sign; |
camera.position -= camera.axis.x * elapsed_secs * move_speed * sign; |
88 |
|
if (window.is_on(Key::kEQUAL)) |
|
89 |
|
move_speed *= 1 + (3.5f * elapsed_secs); |
|
90 |
|
if (window.is_on(Key::kMINUS)) |
|
91 |
|
move_speed /= 1 + (3.5f * elapsed_secs); |
|
|
87 |
|
|
92 |
88 |
if (window.is_on(Key::Z)) { |
if (window.is_on(Key::Z)) { |
93 |
89 |
frustum.zNear *= 1 + (1.4f * elapsed_secs); |
frustum.zNear *= 1 + (1.4f * elapsed_secs); |
94 |
90 |
frustum.zFar *= 1 + (1.4f * elapsed_secs); |
frustum.zFar *= 1 + (1.4f * elapsed_secs); |
|
... |
... |
struct jen::screen::Noclip |
97 |
93 |
frustum.zNear /= 1 + (1.4f * elapsed_secs); |
frustum.zNear /= 1 + (1.4f * elapsed_secs); |
98 |
94 |
frustum.zFar /= 1 + (1.4f * elapsed_secs); |
frustum.zFar /= 1 + (1.4f * elapsed_secs); |
99 |
95 |
} |
} |
|
96 |
|
|
100 |
97 |
frustum.set_aspect(window.extent.x, window.extent.y); |
frustum.set_aspect(window.extent.x, window.extent.y); |
101 |
|
if (window.cursor != cursor_pos) { |
|
102 |
|
auto cursor_diff = jm::v2f::from(window.cursor - cursor_pos); |
|
103 |
|
cursor_diff *= view_sensitivity; |
|
104 |
|
camera.axis.z = jm::rotation(camera.axis.y, cursor_diff.x) |
|
105 |
|
* camera.axis.z; |
|
106 |
|
camera.axis.x = jm::cross(camera.axis.y, camera.axis.z).normalized(); |
|
107 |
98 |
|
|
108 |
|
camera.axis.y = jm::rotation(camera.axis.x, -cursor_diff.y) |
|
109 |
|
* camera.axis.y; |
|
110 |
|
camera.axis.z = jm::cross(camera.axis.x, camera.axis.y).normalized(); |
|
|
99 |
|
move_speed += std::numeric_limits<double>::epsilon(); |
|
100 |
|
move_speed *= 1 + (speed_sensitivity * -window.scroll_diff.y); |
|
101 |
|
|
|
102 |
|
auto cursor_diff = jm::v2f::from(window.cursor_diff); |
|
103 |
|
cursor_diff *= view_sensitivity; |
|
104 |
|
camera.axis.z = jm::rotation(camera.axis.y, cursor_diff.x) |
|
105 |
|
* camera.axis.z; |
|
106 |
|
camera.axis.x = jm::cross(camera.axis.y, camera.axis.z).normalized(); |
|
107 |
|
|
|
108 |
|
camera.axis.y = jm::rotation(camera.axis.x, -cursor_diff.y) |
|
109 |
|
* camera.axis.y; |
|
110 |
|
camera.axis.z = jm::cross(camera.axis.x, camera.axis.y).normalized(); |
111 |
111 |
|
|
112 |
|
cursor_pos = window.cursor; |
|
113 |
|
} |
|
114 |
112 |
camera.stash_to_shift(); |
camera.stash_to_shift(); |
115 |
113 |
} |
} |
116 |
|
/// Last known cursor position |
|
117 |
|
jm::v2f64 cursor_pos; |
|
118 |
114 |
/// Rotation radians per second per cursor pixel |
/// Rotation radians per second per cursor pixel |
119 |
115 |
float view_sensitivity; |
float view_sensitivity; |
|
116 |
|
/// Speed multiplier per scroll "tick" |
|
117 |
|
float speed_sensitivity; |
120 |
118 |
/// Movement speed per second |
/// Movement speed per second |
121 |
119 |
float move_speed; |
float move_speed; |
122 |
120 |
/// @see Camera |
/// @see Camera |
File include/jen/window.h changed (mode: 100644) (index a938b96..c4f3d0e) |
... |
... |
struct jen::Window |
37 |
37 |
HIDDEN = GLFW_CURSOR_HIDDEN, |
HIDDEN = GLFW_CURSOR_HIDDEN, |
38 |
38 |
DISABLED = GLFW_CURSOR_DISABLED |
DISABLED = GLFW_CURSOR_DISABLED |
39 |
39 |
}; |
}; |
40 |
|
/// @brief Cursor is just a 2D position vector. |
|
41 |
|
using Cursor = jm::v2f64; |
|
42 |
40 |
/// @brief Extent is 2D size vector. |
/// @brief Extent is 2D size vector. |
43 |
|
using Extent = jm::vec2<int>; |
|
|
41 |
|
using Extent = jm::v2i32; |
44 |
42 |
/// @brief "I DON'T CARE SIZE". |
/// @brief "I DON'T CARE SIZE". |
45 |
43 |
constexpr static const Extent ExtentAny = { GLFW_DONT_CARE, GLFW_DONT_CARE }; |
constexpr static const Extent ExtentAny = { GLFW_DONT_CARE, GLFW_DONT_CARE }; |
46 |
44 |
/// @brief Set Window visible or invisible. |
/// @brief Set Window visible or invisible. |
|
... |
... |
struct jen::Window |
82 |
80 |
/// @brief Update user input and window state. |
/// @brief Update user input and window state. |
83 |
81 |
/// Recommended for realtime application |
/// Recommended for realtime application |
84 |
82 |
/// @see glfwPollEvents |
/// @see glfwPollEvents |
85 |
|
static void poll() { |
|
|
83 |
|
void poll() { |
|
84 |
|
scroll_diff = {}; |
|
85 |
|
cursor_diff = {}; |
86 |
86 |
glfwPollEvents(); |
glfwPollEvents(); |
87 |
87 |
} |
} |
88 |
88 |
/// @brief Wait untill user input or window state will be changed. |
/// @brief Wait untill user input or window state will be changed. |
89 |
89 |
/// Same as glfwPollEvents, but it will wait for something to update. |
/// Same as glfwPollEvents, but it will wait for something to update. |
90 |
90 |
/// Recommended for interactive window usage |
/// Recommended for interactive window usage |
91 |
91 |
/// @see glfwWaitEvents |
/// @see glfwWaitEvents |
92 |
|
static void wait() { |
|
|
92 |
|
void wait() { |
|
93 |
|
scroll_diff = {}; |
|
94 |
|
cursor_diff = {}; |
93 |
95 |
glfwWaitEvents(); |
glfwWaitEvents(); |
94 |
96 |
} |
} |
95 |
97 |
/// @brief Check if user wants to close the window. |
/// @brief Check if user wants to close the window. |
|
... |
... |
struct jen::Window |
183 |
185 |
/// and framebuffer must be drawn again |
/// and framebuffer must be drawn again |
184 |
186 |
bool is_damaged; |
bool is_damaged; |
185 |
187 |
/// User cursor position |
/// User cursor position |
186 |
|
Cursor cursor; |
|
|
188 |
|
jm::v2f64 cursor; |
|
189 |
|
// Cursor offset between event polls |
|
190 |
|
jm::v2f64 cursor_diff; |
|
191 |
|
// Scroll offset between event polls |
|
192 |
|
jm::v2f64 scroll_diff; |
187 |
193 |
}; |
}; |
188 |
194 |
/// @brief Button state helper. |
/// @brief Button state helper. |
189 |
195 |
struct jen::Button { |
struct jen::Button { |
|
... |
... |
struct jen::Button { |
192 |
198 |
/// @param w window handle to get input from |
/// @param w window handle to get input from |
193 |
199 |
/// @return If button is pressed, it returns true. If button was not released |
/// @return If button is pressed, it returns true. If button was not released |
194 |
200 |
/// and this function is called again than it will return false. |
/// and this function is called again than it will return false. |
195 |
|
[[nodiscard]] bool is_fired(Key::Board key, const Window &w) { |
|
|
201 |
|
template<typename K> |
|
202 |
|
[[nodiscard]] bool is_fired(K key, const Window &w) { |
196 |
203 |
Key::State new_state = w.state(key); |
Key::State new_state = w.state(key); |
197 |
204 |
if (new_state != state) { |
if (new_state != state) { |
198 |
205 |
bool is_fired = new_state == Key::State::ON; |
bool is_fired = new_state == Key::State::ON; |
File src/instance/instance.cpp changed (mode: 100644) (index 7ea62aa..b9fcffa) |
... |
... |
using Window = jen::Window; |
47 |
47 |
init_window(Window *p, Window::Extent extent, |
init_window(Window *p, Window::Extent extent, |
48 |
48 |
const char* title, bool is_visible) { |
const char* title, bool is_visible) { |
49 |
49 |
p->is_visible = is_visible; |
p->is_visible = is_visible; |
50 |
|
p->extent = extent; |
|
|
50 |
|
p->extent = extent; |
|
51 |
|
p->cursor = {}; |
|
52 |
|
p->scroll_diff = {}; |
|
53 |
|
p->cursor_diff = {}; |
51 |
54 |
|
|
52 |
55 |
p->is_iconified = false; |
p->is_iconified = false; |
53 |
56 |
p->is_visible = true; |
p->is_visible = true; |
|
... |
... |
init_window(Window *p, Window::Extent extent, |
94 |
97 |
}); |
}); |
95 |
98 |
glfwSetCursorPosCallback(p->p_window, [](GLFWwindow *p_w, double x, double y){ |
glfwSetCursorPosCallback(p->p_window, [](GLFWwindow *p_w, double x, double y){ |
96 |
99 |
auto &win = *reinterpret_cast<Window*>(glfwGetWindowUserPointer(p_w)); |
auto &win = *reinterpret_cast<Window*>(glfwGetWindowUserPointer(p_w)); |
97 |
|
win.cursor = {x, y}; |
|
|
100 |
|
jm::v2f64 pos = {x, y}; |
|
101 |
|
win.cursor_diff = pos - win.cursor; |
|
102 |
|
win.cursor = pos; |
|
103 |
|
}); |
|
104 |
|
glfwSetScrollCallback(p->p_window, [](GLFWwindow *p_w, double x, double y){ |
|
105 |
|
auto &win = *reinterpret_cast<Window*>(glfwGetWindowUserPointer(p_w)); |
|
106 |
|
win.scroll_diff = jm::v2f64{x, y}; |
98 |
107 |
}); |
}); |
99 |
108 |
|
|
100 |
109 |
glfwGetCursorPos(p->p_window, &p->cursor.x, &p->cursor.y); |
glfwGetCursorPos(p->p_window, &p->cursor.x, &p->cursor.y); |