diff --git a/CMakeLists.txt b/CMakeLists.txt
index 66d5ecf..386cd09 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -7,7 +7,7 @@ find_package(OpenGL REQUIRED)
find_package(glfw3 REQUIRED)
find_package(glm REQUIRED)
-add_executable(ecsgame Util/glad.c Util/OBJ_Loader.h Rendering/Shader.cpp Rendering/Shader.h main.cpp ECS/Components/Transform.h ECS/Components/Movement.h ECS/Events/InputEvent.h ECS/Systems/GravitySystem.h ECS/Systems/PositionDebugSystem.h ECS/Systems/KeyboardMovementSystem.h ECS/Components/Camera.h ECS/Systems/RenderSystem.h ECS/Components/Mesh.h)
+add_executable(ecsgame Util/glad.c Util/OBJ_Loader.h Rendering/Shader.cpp Rendering/Shader.h main.cpp ECS/Components/Transform.h ECS/Components/Movement.h ECS/Events/InputEvent.h ECS/Events/MouseMoveEvent.h ECS/Systems/GravitySystem.h ECS/Systems/PositionDebugSystem.h ECS/Systems/KeyboardMovementSystem.h ECS/Components/Camera.h ECS/Systems/RenderSystem.h ECS/Components/Mesh.h ECS/Systems/MouseLookSystem.h ECS/Components/MouseLook.h)
include_directories(${OPENGL_INCLUDE_DIRS})
diff --git a/ECS/Components/Camera.h b/ECS/Components/Camera.h
index 6bf6c4a..f4be5c2 100644
--- a/ECS/Components/Camera.h
+++ b/ECS/Components/Camera.h
@@ -14,6 +14,8 @@ struct Camera {
glm::perspective(glm::radians(fov), width / height, near, far)) {}
glm::mat4 projection;
+
+ glm::mat4 view;
};
#endif //ECSGAME_CAMERA_H
diff --git a/ECS/Components/MouseLook.h b/ECS/Components/MouseLook.h
new file mode 100644
index 0000000..a60ed5c
--- /dev/null
+++ b/ECS/Components/MouseLook.h
@@ -0,0 +1,14 @@
+//
+// Created by karl on 07.01.20.
+//
+
+#ifndef ECSGAME_MOUSELOOK_H
+#define ECSGAME_MOUSELOOK_H
+
+struct MouseLook {
+ explicit MouseLook(float sensitivity) : sensitivity(sensitivity) {}
+
+ float sensitivity;
+};
+
+#endif //ECSGAME_MOUSELOOK_H
diff --git a/ECS/Components/Transform.h b/ECS/Components/Transform.h
index e29cb78..593f7c7 100644
--- a/ECS/Components/Transform.h
+++ b/ECS/Components/Transform.h
@@ -33,6 +33,18 @@ struct Transform {
glm::vec3 getPosition() {
return matrix * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
}
+
+ glm::vec3 forward() {
+ return matrix * glm::vec4(0.0, 0.0, -1.0, 1.0);
+ }
+
+ glm::vec3 up() {
+ return matrix * glm::vec4(0.0, 1.0, 0.0, 1.0);
+ }
+
+ glm::vec3 right() {
+ return matrix * glm::vec4(1.0, 0.0, 0.0, 1.0);
+ }
};
#endif //ECSGAME_TRANSFORM_H
diff --git a/ECS/Events/MouseMoveEvent.h b/ECS/Events/MouseMoveEvent.h
new file mode 100644
index 0000000..e9405ba
--- /dev/null
+++ b/ECS/Events/MouseMoveEvent.h
@@ -0,0 +1,13 @@
+//
+// Created by karl on 04.01.20.
+//
+
+#ifndef ECSGAME_MOUSEMOVEEVENT_H
+#define ECSGAME_MOUSEMOVEEVENT_H
+
+struct MouseMoveEvent {
+ double newX;
+ double newY;
+};
+
+#endif //ECSGAME_INPUTEVENT_H
diff --git a/ECS/Systems/KeyboardMovementSystem.h b/ECS/Systems/KeyboardMovementSystem.h
index e9bd690..0b63113 100644
--- a/ECS/Systems/KeyboardMovementSystem.h
+++ b/ECS/Systems/KeyboardMovementSystem.h
@@ -64,7 +64,7 @@ class KeyboardMovementSystem : public EntitySystem, public EventSubscribereach(
[&](Entity *ent, ComponentHandle transform, ComponentHandle movement) {
- transform->translate(glm::vec3(movement->moving) * movement->speed * deltaTime);
+ transform->translate(glm::mat3x3(transform->matrix) * glm::vec3(movement->moving) * movement->speed * deltaTime);
});
}
diff --git a/ECS/Systems/MouseLookSystem.h b/ECS/Systems/MouseLookSystem.h
new file mode 100644
index 0000000..fbfcfbf
--- /dev/null
+++ b/ECS/Systems/MouseLookSystem.h
@@ -0,0 +1,73 @@
+//
+// Created by karl on 07.01.20.
+//
+
+#ifndef ECSGAME_MOUSELOOKSYSTEM_H
+#define ECSGAME_MOUSELOOKSYSTEM_H
+
+#include "../ECS.h"
+#include "../Components/Transform.h"
+#include "../Components/MouseLook.h"
+#include "../Events/MouseMoveEvent.h"
+
+using namespace ECS;
+
+class MouseLookSystem : public EntitySystem, public EventSubscriber {
+public:
+ explicit MouseLookSystem(int width, int height) : lastX(width / 2.0), lastY(height / 2.0) {}
+
+ void configure(World *pWorld) override {
+ myWorld = pWorld;
+
+ myWorld->subscribe(this);
+ }
+
+ void unconfigure(World *pWorld) override {
+ pWorld->unsubscribeAll(this);
+ }
+
+ void receive(World *pWorld, const MouseMoveEvent &event) override {
+ pWorld->each([&](Entity *ent, ComponentHandle transform, ComponentHandle mouse, ComponentHandle camera) {
+ double xOffset = event.newX - lastX;
+ double yOffset = lastY - event.newY;
+
+ lastX = event.newX;
+ lastY = event.newY;
+
+ yaw += xOffset * mouse->sensitivity;
+ pitch += yOffset * mouse->sensitivity;
+ });
+ }
+
+ void tick(World *pWorld, float deltaTime) override {
+ pWorld->each([&](Entity *ent, ComponentHandle transform, ComponentHandle mouse, ComponentHandle camera) {
+ if(pitch > 89.0f)
+ pitch = 89.0f;
+ if(pitch < -89.0f)
+ pitch = -89.0f;
+
+ glm::vec3 direction;
+ direction.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch));
+ direction.y = sin(glm::radians(pitch));
+ direction.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch));
+
+ glm::vec3 cameraOrigin = transform->getPosition();
+ glm::vec3 cameraFront = glm::normalize(direction);
+ glm::vec3 cameraUp = glm::vec3(0.0, 1.0, 0.0);
+ glm::vec3 cameraRight = glm::cross(cameraFront, cameraUp);
+
+ camera->view = glm::lookAt(cameraOrigin, cameraOrigin + cameraFront, cameraUp);
+ });
+ }
+
+private:
+ double lastX;
+ double lastY;
+
+ double pitch = 0.0;
+ double yaw = 0.0;
+
+ World *myWorld;
+};
+
+#endif //ECSGAME_MOUSELOOKSYSTEM_H
diff --git a/ECS/Systems/RenderSystem.h b/ECS/Systems/RenderSystem.h
index dcb03e5..6a2c687 100644
--- a/ECS/Systems/RenderSystem.h
+++ b/ECS/Systems/RenderSystem.h
@@ -23,7 +23,7 @@ public:
shader.use();
shader.setMat4("projection", camera->projection);
- shader.setMat4("view", cameraTransform->matrix);
+ shader.setMat4("view", camera->view);
pWorld->each([&](Entity *ent, ComponentHandle mesh, ComponentHandle transform) {
shader.setMat4("model", transform->matrix);
diff --git a/main.cpp b/main.cpp
index 71aed38..760a802 100644
--- a/main.cpp
+++ b/main.cpp
@@ -6,10 +6,12 @@
#include "Rendering/Shader.h"
#include "ECS/ECS.h"
#include "ECS/Events/InputEvent.h"
+#include "ECS/Events/MouseMoveEvent.h"
#include "ECS/Systems/GravitySystem.h"
#include "ECS/Systems/PositionDebugSystem.h"
#include "ECS/Systems/KeyboardMovementSystem.h"
#include "ECS/Systems/RenderSystem.h"
+#include "ECS/Systems/MouseLookSystem.h"
using namespace ECS;
@@ -24,6 +26,10 @@ static void key_callback(GLFWwindow *window, int key, int scancode, int action,
world->emit({key, action});
}
+static void mouse_callback(GLFWwindow* window, double xpos, double ypos) {
+ world->emit({xpos, ypos});
+}
+
int main() {
GLFWwindow *window;
@@ -41,6 +47,10 @@ int main() {
/* Make the window's context current */
glfwMakeContextCurrent(window);
+ glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
+
+ glfwSetCursorPosCallback(window, mouse_callback);
+
glfwSetKeyCallback(window, key_callback);
// glad: load all OpenGL function pointers
@@ -55,8 +65,9 @@ int main() {
// TODO: Could be automated by getting all classes within 'ECS/Systems'
// world->registerSystem(new GravitySystem(-9.8f));
- world->registerSystem(new PositionDebugOutputSystem());
+ // world->registerSystem(new PositionDebugOutputSystem());
world->registerSystem(new KeyboardMovementSystem());
+ world->registerSystem(new MouseLookSystem(640, 480));
RenderSystem* renderSystem = new RenderSystem();
world->registerSystem(renderSystem);
@@ -65,6 +76,7 @@ int main() {
player->assign();
player->assign(glm::vec3(1.f, 1.f, 1.f));
player->assign(70.0f, 640, 480, 0.1f, 100.0f);
+ player->assign(0.1);
Entity *box = world->create();
box->assign();
@@ -111,7 +123,7 @@ int main() {
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f
});
- box->get()->translate(glm::vec3(0.0f, 0.0f, -10.0f));
+ box->get()->translate(glm::vec3(0.0f, 0.0f, -5.0f));
Shader defaultShader("Shaders/default-vertex.vs", "Shaders/default-fragment.fs");
@@ -125,8 +137,6 @@ int main() {
timeInLastFrame = glfwGetTime();
elapsed_time += delta;
- std::cout << "Elapsed time: " << elapsed_time << std::endl;
-
world->tick(delta);
renderSystem->render(world, defaultShader);