aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvimene <vincent.menegaux@gmail.com>2025-01-03 04:02:23 +0100
committervimene <vincent.menegaux@gmail.com>2025-01-03 04:02:23 +0100
commit77cd3a0538d342e25010132317734f27af4bed8e (patch)
tree372d57aa2a76437d80c9312f1e81a54439bf9b42
parent26b4b82a7be2c029491f3009b66b3cbf8db5d93c (diff)
downloadengine-77cd3a0538d342e25010132317734f27af4bed8e.tar.gz
improved keyboard and mouse controls
-rw-r--r--Makefile.am4
-rw-r--r--src/ctrl/keyboard.h17
-rw-r--r--src/ctrl/mouse.h20
-rw-r--r--src/engine.cpp132
-rw-r--r--src/math/tform.h3
-rw-r--r--src/math/vector.h6
6 files changed, 128 insertions, 54 deletions
diff --git a/Makefile.am b/Makefile.am
index 680bc68..60712f6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -24,7 +24,9 @@ engine_SOURCES = \
src/o3d/tri.h \
src/o3d/tri_deriv.h src/o3d/tri_deriv.cpp \
src/o3d/camera.h \
- src/o3d/scene.h
+ src/o3d/scene.h \
+ src/ctrl/keyboard.h \
+ src/ctrl/mouse.h
engine_CPPFLAGS = -std=gnu++23 -Wall -Wextra $(DEPS_CPPFLAGS)
engine_LDFLAGS = -std=gnu++23 -Wall -Wextra
engine_LDADD = $(DEPS_LIBS)
diff --git a/src/ctrl/keyboard.h b/src/ctrl/keyboard.h
new file mode 100644
index 0000000..de7297c
--- /dev/null
+++ b/src/ctrl/keyboard.h
@@ -0,0 +1,17 @@
+#ifndef CTRL_KEYBOARD_H
+#define CTRL_KEYBOARD_H
+
+namespace engine::controllers {
+
+class Keyboard {
+ public:
+ bool fw_down, bw_down, left_down, right_down, zoom_down;
+
+ constexpr Keyboard() :
+ fw_down{false}, bw_down{false}, left_down{false},
+ right_down{false}, zoom_down{false} {}
+};
+
+}
+
+#endif // CTRL_KEYBOARD_H
diff --git a/src/ctrl/mouse.h b/src/ctrl/mouse.h
new file mode 100644
index 0000000..8b66cee
--- /dev/null
+++ b/src/ctrl/mouse.h
@@ -0,0 +1,20 @@
+#ifndef CTRL_MOUSE_H
+#define CTRL_MOUSE_H
+
+#include "math/vector.h"
+
+using engine::math::Vector2;
+
+namespace engine::controllers {
+
+class Mouse {
+ public:
+ bool moved;
+ Vector2 rel_motion;
+
+ constexpr Mouse() : moved{false}, rel_motion{0.f, 0.f} {}
+};
+
+}
+
+#endif // CTRL_MOUSE_H
diff --git a/src/engine.cpp b/src/engine.cpp
index 0d99578..6e05d7f 100644
--- a/src/engine.cpp
+++ b/src/engine.cpp
@@ -31,6 +31,8 @@
#include "math/mat4.h"
#include "math/quat.h"
#include "math/tform.h"
+#include "ctrl/keyboard.h"
+#include "ctrl/mouse.h"
#include "renderer.h"
#include "obj_parser.h"
@@ -43,10 +45,13 @@ using
engine::o3d::Triangle,
engine::o3d::Camera,
engine::o3d::VertexData,
+ engine::math::Vector2,
engine::math::Vector3,
engine::math::Vector4,
engine::math::Matrix4,
- engine::math::Quaternion;
+ engine::math::Quaternion,
+ engine::controllers::Keyboard,
+ engine::controllers::Mouse;
#define FPS 60
@@ -124,6 +129,10 @@ static void scene_main(Renderer<FrameBuffer>& renderer, const Matrix4& final_tra
}
};
+ Keyboard kb{};
+ Mouse mouse{};
+ float rx = 0.f, ry = 0.f;
+
camera = &scene.camera;
while (cont) {
@@ -146,16 +155,28 @@ static void scene_main(Renderer<FrameBuffer>& renderer, const Matrix4& final_tra
}(std::make_integer_sequence<std::size_t, 3>());
}
}
- cont = update_frame(scene);
+ cont = update_frame(scene, kb, mouse);
+
+ if (mouse.moved) {
+ rx += -mouse.rel_motion.y;
+ ry += -mouse.rel_motion.x;
+ if (rx < -PI / 2.f) rx = -PI / 2.f;
+ if (rx > PI / 2.f) rx = PI / 2.f;
+ scene.camera.transform.rot = Quaternion::euler_zxy(rx, ry, 0.f);
+ }
+
+ Vector3 movement(0.f, 0.f, 0.f);
+ if (kb.fw_down) movement.z += -1.f;
+ if (kb.left_down) movement.x += -1.f;
+ if (kb.bw_down) movement.z += +1.f;
+ if (kb.right_down) movement.x += +1.f;
+ if (kb.fw_down || kb.left_down || kb.bw_down || kb.right_down) movement.normalize();
+ scene.camera.transform.loc += movement.rot(Quaternion::rot_y(ry)) * .05f;
+ scene.camera.fov = (kb.zoom_down ? 40.f : 80.f) * PI / 180.f;
}
}
#ifdef ENABLE_NCURSES
-#define MKEY_Z 122
-#define MKEY_Q 113
-#define MKEY_S 115
-#define MKEY_D 100
-
#define MKEY_ESC 27
static int main_term() {
@@ -173,7 +194,7 @@ static int main_term() {
getmaxyx(stdscr, h, w);
Renderer<CharacterFrameBuffer> renderer{CharacterFrameBuffer{static_cast<unsigned int>(w), static_cast<unsigned int>(h)}};
- scene_main(renderer, Matrix4::scale(Vector3(2.f, 1.f, 1.f)), [&](Scene& scene) {
+ scene_main(renderer, Matrix4::scale(Vector3(2.f, 1.f, 1.f)), [&](Scene& scene, Keyboard& kb, Mouse& mouse) {
(void) scene;
mvaddnstr(0, 0, renderer.fb.chars(), renderer.width() * renderer.height());
@@ -182,28 +203,48 @@ static int main_term() {
timeout(10);
int c = getch();
- if (c == MKEY_ESC) return false;
+ kb.fw_down = false;
+ kb.left_down = false;
+ kb.bw_down = false;
+ kb.right_down = false;
+
+ mouse.moved = false;
+ mouse.rel_motion = Vector2(0.f, 0.f);
+
switch (c) {
- case KEY_UP:
- // a.x += 0.1f;
- // dist += .1f;
+ case 'z':
+ kb.fw_down = true;
break;
- case KEY_DOWN:
- // a.x -= 0.1f;
- // dist -= .1f;
+ case 'q':
+ kb.left_down = true;
break;
- case KEY_LEFT:
- // a.y += 0.1f;
+ case 's':
+ kb.bw_down = true;
break;
- case KEY_RIGHT:
- // a.y -= 0.1f;
+ case 'd':
+ kb.right_down = true;
break;
- case MKEY_Q:
- // a.z += 0.1f;
+ case 'p':
+ kb.zoom_down = !kb.zoom_down;
break;
- case MKEY_D:
- // a.z -= 0.1f;
+ case KEY_UP:
+ mouse.moved = true;
+ mouse.rel_motion = Vector2(0.f, -.1f);
+ break;
+ case KEY_LEFT:
+ mouse.moved = true;
+ mouse.rel_motion = Vector2(-.1f, 0.f);
+ break;
+ case KEY_DOWN:
+ mouse.moved = true;
+ mouse.rel_motion = Vector2(0.f, +.1f);
+ break;
+ case KEY_RIGHT:
+ mouse.moved = true;
+ mouse.rel_motion = Vector2(+.1f, 0.f);
break;
+ case MKEY_ESC:
+ return false;
}
getmaxyx(stdscr, h, w);
@@ -244,10 +285,7 @@ static int main_graphical() {
SDL_Event e;
- float rx = 0.f, ry = 0.f;
- bool fw_down = false, left_down = false, bw_down = false, right_down = false, zoom_down = false;
-
- scene_main(engine_renderer, Matrix4::idty(), [&](Scene& scene) {
+ scene_main(engine_renderer, Matrix4::idty(), [&](Scene& scene, Keyboard& kb, Mouse& mouse) {
(void) scene;
SDL_UpdateTexture(texture, nullptr, engine_renderer.fb.pixels(), SCREEN_WIDTH * 4);
SDL_RenderClear(renderer);
@@ -256,6 +294,8 @@ static int main_graphical() {
SDL_UpdateWindowSurface(window);
SDL_SetRelativeMouseMode(SDL_TRUE);
bool cont = true;
+ mouse.moved = false;
+ mouse.rel_motion = Vector2(0.f, 0.f);
if (SDL_WaitEventTimeout(&e, 10)) {
do {
switch (e.type) {
@@ -265,38 +305,38 @@ static int main_graphical() {
case SDL_KEYDOWN:
switch (e.key.keysym.sym) {
case SDLK_z:
- fw_down = true;
+ kb.fw_down = true;
break;
case SDLK_q:
- left_down = true;
+ kb.left_down = true;
break;
case SDLK_s:
- bw_down = true;
+ kb.bw_down = true;
break;
case SDLK_d:
- right_down = true;
+ kb.right_down = true;
break;
case SDLK_LCTRL:
- zoom_down = true;
+ kb.zoom_down = true;
break;
}
break;
case SDL_KEYUP:
switch (e.key.keysym.sym) {
case SDLK_z:
- fw_down = false;
+ kb.fw_down = false;
break;
case SDLK_q:
- left_down = false;
+ kb.left_down = false;
break;
case SDLK_s:
- bw_down = false;
+ kb.bw_down = false;
break;
case SDLK_d:
- right_down = false;
+ kb.right_down = false;
break;
case SDLK_LCTRL:
- zoom_down = false;
+ kb.zoom_down = false;
break;
case SDLK_ESCAPE:
cont = false;
@@ -304,25 +344,15 @@ static int main_graphical() {
}
break;
case SDL_MOUSEMOTION:
- rx += -static_cast<float>(e.motion.yrel) * .01f;
- ry += -static_cast<float>(e.motion.xrel) * .01f;
- if (rx < -PI / 2.f) rx = -PI / 2.f;
- if (rx > PI / 2.f) rx = PI / 2.f;
- scene.camera.transform.rot = Quaternion::euler_zxy(rx, ry, 0.f);
+ mouse.moved = true;
+ mouse.rel_motion += Vector2(
+ static_cast<float>(e.motion.xrel) * .01f,
+ static_cast<float>(e.motion.yrel) * .01f);
break;
}
} while (SDL_PollEvent(&e));
}
- Vector3 movement(0.f, 0.f, 0.f);
- if (fw_down) movement.z += -1.f;
- if (left_down) movement.x += -1.f;
- if (bw_down) movement.z += +1.f;
- if (right_down) movement.x += +1.f;
- if (fw_down || left_down || bw_down || right_down) movement.normalize();
- scene.camera.transform.loc += movement.rot(Quaternion::rot_y(ry)) * .05f;
- scene.camera.fov = (zoom_down ? 40.f : 80.f) * PI / 180.f;
-
return cont;
});
diff --git a/src/math/tform.h b/src/math/tform.h
index 2a654b8..74186f8 100644
--- a/src/math/tform.h
+++ b/src/math/tform.h
@@ -14,8 +14,7 @@ class Transform {
Quaternion rot;
Vector3 scale;
- constexpr Transform(Vector3 loc, Quaternion rot, Vector3 scale) : loc{loc}, rot{rot}, scale{scale} {
- }
+ constexpr Transform(Vector3 loc, Quaternion rot, Vector3 scale) : loc{loc}, rot{rot}, scale{scale} {}
constexpr Transform opposite() const & {
return {-loc, rot.conjugate(), 1.f / scale};
diff --git a/src/math/vector.h b/src/math/vector.h
index d755c89..fcfc5bd 100644
--- a/src/math/vector.h
+++ b/src/math/vector.h
@@ -33,6 +33,12 @@ struct Vector2 {
return *this + (-other);
}
+ constexpr Vector2 operator+=(const Vector2& other) & {
+ x += other.x;
+ y += other.y;
+ return *this;
+ }
+
constexpr float det(const Vector2& other) const & {
return this->x * other.y - other.x * this->y;
}