From 2ca21a73c465fa1a1fec104f61c306e891eb9c89 Mon Sep 17 00:00:00 2001 From: Jukitsu <84381972+Jukitsu@users.noreply.github.com> Date: Sun, 26 Nov 2023 21:03:51 +0100 Subject: [PATCH] Physics :D --- Jukcraft/Jukcraft.vcxproj | 25 ++++---- Jukcraft/Jukcraft.vcxproj.filters | 76 +++++++++++++++++------- Jukcraft/Makefile | 36 +++++++---- Jukcraft/src/core/App.cpp | 2 +- Jukcraft/src/core/Camera.cpp | 21 +++---- Jukcraft/src/core/Game.cpp | 2 +- Jukcraft/src/{core => entity}/HitRay.cpp | 2 +- Jukcraft/src/{core => entity}/HitRay.h | 0 Jukcraft/src/entity/LivingEntity.cpp | 38 ++++++++++-- Jukcraft/src/entity/LivingEntity.h | 16 +++++ Jukcraft/src/models/Collider.h | 2 +- Jukcraft/src/physics/constants.h | 14 +++++ premake5.lua | 4 +- 13 files changed, 174 insertions(+), 64 deletions(-) rename Jukcraft/src/{core => entity}/HitRay.cpp (98%) rename Jukcraft/src/{core => entity}/HitRay.h (100%) create mode 100644 Jukcraft/src/physics/constants.h diff --git a/Jukcraft/Jukcraft.vcxproj b/Jukcraft/Jukcraft.vcxproj index fd0919d..2d44c6e 100644 --- a/Jukcraft/Jukcraft.vcxproj +++ b/Jukcraft/Jukcraft.vcxproj @@ -56,22 +56,22 @@ true - ..\bin\Debug-windowsJukcraft\ - ..\bin-int\Debug-windowsJukcraft\ + ..\bin\Debug-windows-Jukcraft\ + ..\bin-int\Debug-windows-Jukcraft\ Jukcraft .exe false - ..\bin\Beta-windowsJukcraft\ - ..\bin-int\Beta-windowsJukcraft\ + ..\bin\Beta-windows-Jukcraft\ + ..\bin-int\Beta-windows-Jukcraft\ Jukcraft .exe false - ..\bin\Release-windowsJukcraft\ - ..\bin-int\Release-windowsJukcraft\ + ..\bin\Release-windows-Jukcraft\ + ..\bin-int\Release-windows-Jukcraft\ Jukcraft .exe @@ -154,23 +154,24 @@ - + + - + - + + - @@ -182,11 +183,11 @@ - - + + diff --git a/Jukcraft/Jukcraft.vcxproj.filters b/Jukcraft/Jukcraft.vcxproj.filters index a8cbd27..4aed35f 100644 --- a/Jukcraft/Jukcraft.vcxproj.filters +++ b/Jukcraft/Jukcraft.vcxproj.filters @@ -7,6 +7,18 @@ {4E40957C-3A77-960D-E363-7C10CF79120F} + + {C2FD7FFB-AE9F-AAD1-975A-BE25839B3122} + + + {BE34F17E-2AF5-6CB5-F32F-B6325FAFB191} + + + {2983320E-1525-5DE4-FEDF-7038EA20E434} + + + {A823A1AC-1403-2048-1D1B-AB1E897986A9} + {9C6AA017-8837-FB22-B150-E9CA9D7C30B1} @@ -19,9 +31,6 @@ {0949E6C7-F5D7-6F91-9EF6-838C8A648037} - - {EF8827A6-5B14-956A-6425-185FD02FF16A} - {1C040F70-08FD-2DC2-312F-13471D870DCE} @@ -51,9 +60,6 @@ core - - core - core @@ -63,13 +69,40 @@ core + + entity + + + entity + + + entity + + + entity + + + entity\player + + + models + + + models + + + physics + renderer renderer\gfx\buffers + + renderer\gfx\buffers + renderer\gfx\objects @@ -79,9 +112,6 @@ renderer\gfx\objects - - renderer\models - renderer\texture @@ -100,12 +130,6 @@ world\chunk - - - - - - @@ -117,17 +141,29 @@ core - - core - core core + + entity + + + entity + + + entity + + + entity\player + + + renderer\gfx\buffers + vendor\stb @@ -143,9 +179,5 @@ world\chunk - - - - \ No newline at end of file diff --git a/Jukcraft/Makefile b/Jukcraft/Makefile index 090a63e..9306ede 100644 --- a/Jukcraft/Makefile +++ b/Jukcraft/Makefile @@ -12,9 +12,9 @@ endif ifeq ($(config),debug) RESCOMP = windres - TARGETDIR = ../bin/Debug-windowsJukcraft + TARGETDIR = ../bin/Debug-windows-Jukcraft TARGET = $(TARGETDIR)/Jukcraft.exe - OBJDIR = ../bin-int/Debug-windowsJukcraft + OBJDIR = ../bin-int/Debug-windows-Jukcraft PCH = src/pch.h GCH = $(OBJDIR)/$(notdir $(PCH)).gch DEFINES += -DGLFW_INCLUDE_NONE @@ -41,9 +41,9 @@ endif ifeq ($(config),beta) RESCOMP = windres - TARGETDIR = ../bin/Beta-windowsJukcraft + TARGETDIR = ../bin/Beta-windows-Jukcraft TARGET = $(TARGETDIR)/Jukcraft.exe - OBJDIR = ../bin-int/Beta-windowsJukcraft + OBJDIR = ../bin-int/Beta-windows-Jukcraft PCH = src/pch.h GCH = $(OBJDIR)/$(notdir $(PCH)).gch DEFINES += -DGLFW_INCLUDE_NONE -DGLM_FORCE_INLINE @@ -70,9 +70,9 @@ endif ifeq ($(config),release) RESCOMP = windres - TARGETDIR = ../bin/Release-windowsJukcraft + TARGETDIR = ../bin/Release-windows-Jukcraft TARGET = $(TARGETDIR)/Jukcraft.exe - OBJDIR = ../bin-int/Release-windowsJukcraft + OBJDIR = ../bin-int/Release-windows-Jukcraft PCH = src/pch.h GCH = $(OBJDIR)/$(notdir $(PCH)).gch DEFINES += -DGLFW_INCLUDE_NONE -DGLM_FORCE_INLINE -DSPDLOG_NO_EXCEPTIONS @@ -101,11 +101,15 @@ OBJECTS := \ $(OBJDIR)/App.o \ $(OBJDIR)/Camera.o \ $(OBJDIR)/Game.o \ - $(OBJDIR)/HitRay.o \ $(OBJDIR)/Log.o \ $(OBJDIR)/Window.o \ + $(OBJDIR)/BipedEntity.o \ + $(OBJDIR)/HitRay.o \ + $(OBJDIR)/LivingEntity.o \ + $(OBJDIR)/Player.o \ $(OBJDIR)/main.o \ $(OBJDIR)/pch.o \ + $(OBJDIR)/DynamicBuffer.o \ $(OBJDIR)/stb_build.o \ $(OBJDIR)/LightEngine.o \ $(OBJDIR)/World.o \ @@ -178,21 +182,33 @@ $(OBJDIR)/Camera.o: src/core/Camera.cpp $(OBJDIR)/Game.o: src/core/Game.cpp @echo $(notdir $<) $(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<" -$(OBJDIR)/HitRay.o: src/core/HitRay.cpp - @echo $(notdir $<) - $(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<" $(OBJDIR)/Log.o: src/core/Log.cpp @echo $(notdir $<) $(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<" $(OBJDIR)/Window.o: src/core/Window.cpp @echo $(notdir $<) $(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<" +$(OBJDIR)/BipedEntity.o: src/entity/BipedEntity.cpp + @echo $(notdir $<) + $(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<" +$(OBJDIR)/HitRay.o: src/entity/HitRay.cpp + @echo $(notdir $<) + $(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<" +$(OBJDIR)/LivingEntity.o: src/entity/LivingEntity.cpp + @echo $(notdir $<) + $(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<" +$(OBJDIR)/Player.o: src/entity/player/Player.cpp + @echo $(notdir $<) + $(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<" $(OBJDIR)/main.o: src/main.cpp @echo $(notdir $<) $(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<" $(OBJDIR)/pch.o: src/pch.cpp @echo $(notdir $<) $(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<" +$(OBJDIR)/DynamicBuffer.o: src/renderer/gfx/buffers/DynamicBuffer.cpp + @echo $(notdir $<) + $(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<" $(OBJDIR)/stb_build.o: src/vendor/stb/stb_build.cpp @echo $(notdir $<) $(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<" diff --git a/Jukcraft/src/core/App.cpp b/Jukcraft/src/core/App.cpp index eb5bc5a..d4a212a 100644 --- a/Jukcraft/src/core/App.cpp +++ b/Jukcraft/src/core/App.cpp @@ -72,7 +72,7 @@ namespace Jukcraft { if (glfwGetTime() - timer > 1.0) { timer++; - LOG_TRACE("FPS: {}, Updates: {}", frames, updates); + LOG_TRACE("FPS: {}, TPS: {}", frames, updates); updates = 0, frames = 0; } diff --git a/Jukcraft/src/core/Camera.cpp b/Jukcraft/src/core/Camera.cpp index ba9b6ba..ca033b3 100644 --- a/Jukcraft/src/core/Camera.cpp +++ b/Jukcraft/src/core/Camera.cpp @@ -4,12 +4,13 @@ #include #include "core/App.h" -static constexpr float WALKING_SPEED = 4.317f; +#include "physics/constants.h" + static constexpr float sensitivity = 0.005f; namespace Jukcraft { Camera::Camera(gfx::Shader& shader, std::unique_ptr& player) - :shader(shader), player(player), speed(WALKING_SPEED) { + :shader(shader), player(player), speed(WALK_SPEED) { ubo.allocate(sizeof(ShaderCameraData), nullptr, true); mappedUbo = reinterpret_cast(ubo.map(0, sizeof(ShaderCameraData))); @@ -43,18 +44,18 @@ namespace Jukcraft { if (App::GetWindow().isKeyPressed(GLFW_KEY_LEFT_SHIFT)) input.y += -1; if (App::GetWindow().isKeyPressed(GLFW_KEY_SPACE)) input.y += 1; - if (deltaTime * 20.0f > 1.0f) speed = WALKING_SPEED; - + if (deltaTime * 20.0f > 1.0f) + speed = WALK_SPEED; else - speed += (WALKING_SPEED - speed) * deltaTime * 20; + speed += (WALK_SPEED - speed) * deltaTime * 20; + - const float multiplier = speed; - if (input.y) { - player->velocity.y = input.y * multiplier; + if (input.y > 0) { + player->jump(); } if (input.x || input.z) { const float angle = player->yaw - glm::atan((float)input.z, (float)input.x) + glm::pi() / 2; - player->velocity.x = glm::cos(angle) * multiplier; - player->velocity.z = glm::sin(angle) * multiplier; + player->acceleration.x = glm::cos(angle) * speed; + player->acceleration.z = glm::sin(angle) * speed; } diff --git a/Jukcraft/src/core/Game.cpp b/Jukcraft/src/core/Game.cpp index 1ea1200..28fe0ef 100644 --- a/Jukcraft/src/core/Game.cpp +++ b/Jukcraft/src/core/Game.cpp @@ -1,7 +1,7 @@ #include "pch.h" #include "core/Game.h" #include -#include "core/HitRay.h" +#include "entity/HitRay.h" namespace Jukcraft { diff --git a/Jukcraft/src/core/HitRay.cpp b/Jukcraft/src/entity/HitRay.cpp similarity index 98% rename from Jukcraft/src/core/HitRay.cpp rename to Jukcraft/src/entity/HitRay.cpp index 8d0741f..bcde8c6 100644 --- a/Jukcraft/src/core/HitRay.cpp +++ b/Jukcraft/src/entity/HitRay.cpp @@ -1,5 +1,5 @@ #include "pch.h" -#include "core/HitRay.h" +#include "entity/HitRay.h" namespace Jukcraft { diff --git a/Jukcraft/src/core/HitRay.h b/Jukcraft/src/entity/HitRay.h similarity index 100% rename from Jukcraft/src/core/HitRay.h rename to Jukcraft/src/entity/HitRay.h diff --git a/Jukcraft/src/entity/LivingEntity.cpp b/Jukcraft/src/entity/LivingEntity.cpp index 0169922..1aba0ef 100644 --- a/Jukcraft/src/entity/LivingEntity.cpp +++ b/Jukcraft/src/entity/LivingEntity.cpp @@ -3,16 +3,19 @@ #include "world/World.h" namespace Jukcraft { + LivingEntity::LivingEntity(World& world, const glm::vec3& initialPos, const glm::vec3& initialVelocity, const glm::vec3& initialAcceleration, float initialYaw, float initialPitch, float width, float height) - :Entity(initialPos, initialVelocity, initialAcceleration, initialYaw, initialPitch), oldPosition(position), - width(0.6f), height(1.8f), collider(), world(world) { + :Entity(initialPos, initialVelocity, initialAcceleration, initialYaw, initialPitch), + oldPosition(position), interpolatedPos(position), interpolationStep(1.0f), + width(0.6f), height(1.8f), collider(), world(world), onGround(false) { collider.vx1 = position - glm::vec3(width / 2.0f, 0, width / 2.0f); collider.vx2 = position + glm::vec3(width / 2.0f, height, width / 2.0f); } LivingEntity::~LivingEntity() { } + void LivingEntity::updateCollider() { collider.vx1 = position - glm::vec3(width / 2.0f, 0, width / 2.0f); collider.vx2 = position + glm::vec3(width / 2.0f, height, width / 2.0f); @@ -83,18 +86,45 @@ namespace Jukcraft { velocity.z = 0; position.z += adjustedVelocity.z * entryTime; } + if (normal.y == 1) { + onGround = true; + } + + } + + void LivingEntity::jump(float hmax) { + if (!onGround) + return; + + velocity.y = glm::sqrt(-2 * g.y * hmax); } void LivingEntity::tick(float deltaTime) { oldPosition = position; + + velocity += acceleration * getFriction() * deltaTime; + acceleration = glm::vec3(0.0f); + updateCollider(); + + onGround = false; for (uint8_t i = 0; i < 3; i++) resolveCollisions(deltaTime); - acceleration += velocity * deltaTime; position += velocity * deltaTime; + velocity += g * deltaTime; + + auto comp = [](auto& a, auto& b) { return glm::abs(a) < glm::abs(b); }; + + glm::vec3 deltaFriction = glm::vec3( + std::min(velocity.x * getFriction().x * deltaTime, velocity.x, comp), + std::min(velocity.y * getFriction().y * deltaTime, velocity.y, comp), + std::min(velocity.z * getFriction().z * deltaTime, velocity.z, comp) + ); + velocity -= deltaFriction; + updateCollider(); + - velocity = glm::vec3(0.0f); } } \ No newline at end of file diff --git a/Jukcraft/src/entity/LivingEntity.h b/Jukcraft/src/entity/LivingEntity.h index c4c5fe5..0b34142 100644 --- a/Jukcraft/src/entity/LivingEntity.h +++ b/Jukcraft/src/entity/LivingEntity.h @@ -2,6 +2,8 @@ #include "entity/Entity.h" #include "models/Collider.h" +#include "physics/constants.h" + namespace Jukcraft { class World; @@ -16,13 +18,27 @@ namespace Jukcraft { void updateCollider(); void resolveCollisions(float deltaTime); + void jump(float jumpHeight = JUMP_HEIGHT); void tick(float deltaTime) override; + constexpr float getEyeLevel() const { return height - 0.2f; } constexpr const Collider& getCollider() const { return collider; } protected: + + constexpr const glm::vec3& getFriction() const { + if (onGround) + return FRICTION; + else if (velocity.y > 0) + return DRAG_JUMP; + else + return DRAG_FALL; + } + float width, height; + bool onGround; + glm::vec3 oldPosition; glm::vec3 interpolatedPos; float interpolationStep; diff --git a/Jukcraft/src/models/Collider.h b/Jukcraft/src/models/Collider.h index 3c5c579..1bf80f6 100644 --- a/Jukcraft/src/models/Collider.h +++ b/Jukcraft/src/models/Collider.h @@ -41,7 +41,7 @@ namespace Jukcraft { auto time = [](float x, float y) { if (y) return x / y; - return -sign(x) * std::numeric_limits::infinity(); + return -sign(x) * std::numeric_limits::infinity(); // Fuck C++ can't do limits properly }; diff --git a/Jukcraft/src/physics/constants.h b/Jukcraft/src/physics/constants.h new file mode 100644 index 0000000..6701324 --- /dev/null +++ b/Jukcraft/src/physics/constants.h @@ -0,0 +1,14 @@ +#pragma once + +namespace Jukcraft { + constexpr glm::vec3 g = glm::vec3(0.0f, -32.0f, 0.0f); + + constexpr float JUMP_HEIGHT = 1.25f; // Changed in Minecraft 1.9 for 1.5f + constexpr float WALK_SPEED = 4.317f; + + constexpr glm::vec3 FRICTION = glm::vec3(20.0f, 20.0f, 20.0f); + + constexpr glm::vec3 DRAG_FLY = glm::vec3(5.0f, 5.0f, 5.0f); + constexpr glm::vec3 DRAG_JUMP = glm::vec3(1.8f, 0.0f, 1.8f); + constexpr glm::vec3 DRAG_FALL = glm::vec3(1.8f, 0.4f, 1.8f); +} diff --git a/premake5.lua b/premake5.lua index 83f6ce5..8a6ae88 100644 --- a/premake5.lua +++ b/premake5.lua @@ -180,8 +180,8 @@ project "Jukcraft" cppdialect "C++17" staticruntime "on" - targetdir ("bin/" .. outputdir .. "%{prj.name}") - objdir ("bin-int/" .. outputdir .. "%{prj.name}") + targetdir ("bin/" .. outputdir .. "-%{prj.name}") + objdir ("bin-int/" .. outputdir .. "-%{prj.name}") files { "Jukcraft/src/**.h",