diff --git a/CMakeLists.txt b/CMakeLists.txt index 67fdfe0..529db4a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,8 +7,8 @@ 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/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 ECS/Components/ObjMesh.h Util/stb_setup.cpp ECS/Components/Texture.h ECS/Components/LODObjMesh.h ECS/Components/SineAnimation.h ECS/Systems/SineAnimationSystem.h ECS/Components/DirectionalLight.h Rendering/Material.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/Components/PathMove.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 ECS/Components/ObjMesh.h Util/stb_setup.cpp ECS/Components/Texture.h ECS/Components/LODObjMesh.h ECS/Components/SineAnimation.h ECS/Systems/SineAnimationSystem.h ECS/Components/DirectionalLight.h Rendering/Material.h ECS/Systems/PathMoveSystem.h) include_directories(${OPENGL_INCLUDE_DIRS}) -target_link_libraries(ecsgame ${OPENGL_LIBRARY} glfw glm ${CMAKE_DL_LIBS}) \ No newline at end of file +target_link_libraries(ecsgame ${OPENGL_LIBRARY} glfw glm ${CMAKE_DL_LIBS}) diff --git a/ECS/Components/PathMove.h b/ECS/Components/PathMove.h new file mode 100644 index 0000000..2af6daf --- /dev/null +++ b/ECS/Components/PathMove.h @@ -0,0 +1,22 @@ +#ifndef __PATHMOVE_H__ +#define __PATHMOVE_H__ + +#include +#include + +struct PathMove { + struct Path { + std::vector points; + }; + + PathMove(double speed) : speed(speed) {} + + double speed; + + Path path; + + int current_point_index; + + float time_passed = 0.0; +}; +#endif // __PATHMOVE_H__ \ No newline at end of file diff --git a/ECS/Components/Transform.h b/ECS/Components/Transform.h index 9db515c..a643027 100644 --- a/ECS/Components/Transform.h +++ b/ECS/Components/Transform.h @@ -30,6 +30,11 @@ struct Transform { matrix = glm::rotate(matrix, glm::radians(degrees), axis); } + void set_position(glm::vec3 position) { + glm::vec3 difference = getPosition() - position; + translate(-difference); + } + glm::vec3 getPosition() const { return matrix * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); } diff --git a/ECS/Systems/PathMoveSystem.h b/ECS/Systems/PathMoveSystem.h new file mode 100644 index 0000000..fe471d6 --- /dev/null +++ b/ECS/Systems/PathMoveSystem.h @@ -0,0 +1,107 @@ +#ifndef __PATHMOVESYSTEM_H__ +#define __PATHMOVESYSTEM_H__ + +#include +#include + +#include + +#include "../ECS.h" +#include "../Components/Transform.h" +#include "../Events/InputEvent.h" +#include "../Components/PathMove.h" + +using namespace ECS; + +// Spline helper functions + +// Calculate the t value for a Catmull–Rom spline +float get_t(float alpha, float t, glm::vec3 p0, glm::vec3 p1) { + float a = pow((p1.x - p0.x), 2.0f) + pow((p1.y - p0.y), 2.0f) + pow((p1.z - p0.z), 2.0f); + float b = pow(a, alpha * 0.5f); + + return (b + t); +} + +// Given four points, calculate an interpolated point between p1 and p2 using a Catmul-Rom spline. +// t specifies the position along the path, with t=0 being p1 and t=2 being p2. +glm::vec3 catmul(float alpha, glm::vec3 p0, glm::vec3 p1, glm::vec3 p2, glm::vec3 p3, float t) { + float t0 = 0.0f; + float t1 = get_t(alpha, t0, p0, p1); + float t2 = get_t(alpha, t1, p1, p2); + float t3 = get_t(alpha, t2, p2, p3); + + // Lerp t to be between t1 and t2 + t = t1 + t * (t2 - t1); + + glm::vec3 A1 = (t1-t)/(t1-t0)*p0 + (t-t0)/(t1-t0)*p1; + glm::vec3 A2 = (t2-t)/(t2-t1)*p1 + (t-t1)/(t2-t1)*p2; + glm::vec3 A3 = (t3-t)/(t3-t2)*p2 + (t-t2)/(t3-t2)*p3; + + glm::vec3 B1 = (t2-t)/(t2-t0)*A1 + (t-t0)/(t2-t0)*A2; + glm::vec3 B2 = (t3-t)/(t3-t1)*A2 + (t-t1)/(t3-t1)*A3; + + glm::vec3 C = (t2-t)/(t2-t1)*B1 + (t-t1)/(t2-t1)*B2; + + return C; +} + +class PathMoveSystem : public EntitySystem, public EventSubscriber { + void configure(World *pWorld) override { + myWorld = pWorld; + + // TODO: Changing velocity + myWorld->subscribe(this); + } + + void receive(World *pWorld, const InputEvent &event) override { + if (event.key == GLFW_KEY_W) { + myWorld->each([&](Entity *ent, ComponentHandle pathmove) { + if (event.action == GLFW_PRESS) { + // TODO: Velocity adder + } else if (event.action == GLFW_RELEASE) { + // TODO + } + }); + } else if (event.key == GLFW_KEY_S) { + myWorld->each([&](Entity *ent, ComponentHandle pathmove) { + if (event.action == GLFW_PRESS) { + // TODO + } else if (event.action == GLFW_RELEASE) { + // TODO + } + }); + } + } + + void tick(World *pWorld, float deltaTime) override { + PathMove::Path path; + + path.points = std::vector{ + glm::vec3(0.0, 2.0, 0.0), + glm::vec3(0.0, 2.0, 1.0), + glm::vec3(2.0, 2.0, 2.0), + glm::vec3(1.0, 3.0, 3.0), + glm::vec3(-2.0, 2.0, 4.0), + glm::vec3(2.0, 2.0, 4.0), + }; + + pWorld->each( + [&](Entity *ent, ComponentHandle transform, ComponentHandle pathmove) { + pathmove->time_passed += deltaTime; + + // Move from the second to the third point for now + glm::vec3 point = catmul(0.5f, path.points[0], path.points[1], path.points[2], path.points[3], pathmove->time_passed * 0.5); + transform->set_position(point); + }); + } + + void unconfigure(World *pWorld) override { + pWorld->unsubscribeAll(this); + } + +private: + World *myWorld; +}; + +#endif // __PATHMOVESYSTEM_H__ \ No newline at end of file diff --git a/main.cpp b/main.cpp index e7e7c56..d178147 100644 --- a/main.cpp +++ b/main.cpp @@ -12,11 +12,13 @@ #include "ECS/Systems/KeyboardMovementSystem.h" #include "ECS/Systems/RenderSystem.h" #include "ECS/Systems/MouseLookSystem.h" +#include "ECS/Systems/PathMoveSystem.h" #include "ECS/Components/ObjMesh.h" #include "ECS/Components/Texture.h" #include "ECS/Components/SineAnimation.h" #include "ECS/Systems/SineAnimationSystem.h" #include "ECS/Components/DirectionalLight.h" +#include "ECS/Components/PathMove.h" using namespace ECS; @@ -78,6 +80,7 @@ int main() { // world->registerSystem(new PositionDebugOutputSystem()); world->registerSystem(new KeyboardMovementSystem()); world->registerSystem(new MouseLookSystem(1280, 720)); + world->registerSystem(new PathMoveSystem()); world->registerSystem(new SineAnimationSystem()); RenderSystem* renderSystem = new RenderSystem(); @@ -85,9 +88,10 @@ int main() { Entity *player = world->create(); player->assign(); - player->assign(glm::vec3(2.f, 2.f, 2.f)); + //player->assign(glm::vec3(2.f, 2.f, 2.f)); + //player->assign(0.1); player->assign(70.0f, 1280, 720, 0.1f, 100.0f); - player->assign(0.1); + player->assign(10.0); player->get()->translate(glm::vec3(0.0f, 1.0f, 2.0f)); Entity *monkey = world->create();