diff --git a/CMakeLists.txt b/CMakeLists.txt index 91ab332..360b4d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ set(SRC_FILES "src/systems/transform.cpp" "src/systems/render.cpp" - "src/systems/physics.cpp" + "src/systems/collisions.cpp" "src/resources/shader.cpp" "src/resources/material.cpp" @@ -44,7 +44,7 @@ set(INCLUDE_FILES "include/systems/transform.hpp" "include/systems/render.hpp" - "include/systems/physics.hpp" + "include/systems/collisions.hpp" "include/resources/shader.hpp" "include/resources/material.hpp" diff --git a/include/components/collider.hpp b/include/components/collider.hpp index 65318bc..b2985cb 100644 --- a/include/components/collider.hpp +++ b/include/components/collider.hpp @@ -28,6 +28,7 @@ namespace engine { auto getJustUncollided() { return m_justUncollided; } auto getLastEntityCollided() { return m_lastEntityCollided; } auto getLastCollisionNormal() { return m_lastCollisionNormal; } + auto getLastCollisionPoint() { return m_lastCollisionPoint; } private: bool m_isColliding; @@ -35,6 +36,7 @@ namespace engine { bool m_justUncollided; uint32_t m_lastEntityCollided; glm::vec3 m_lastCollisionNormal; + glm::vec3 m_lastCollisionPoint; }; } diff --git a/include/systems/physics.hpp b/include/systems/collisions.hpp similarity index 100% rename from include/systems/physics.hpp rename to include/systems/collisions.hpp diff --git a/src/scene.cpp b/src/scene.cpp index 027eaf9..4a61b92 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -5,7 +5,7 @@ #include "components/collider.hpp" #include "systems/transform.hpp" #include "systems/render.hpp" -#include "systems/physics.hpp" +#include "systems/collisions.hpp" namespace engine { diff --git a/src/systems/physics.cpp b/src/systems/collisions.cpp similarity index 89% rename from src/systems/physics.cpp rename to src/systems/collisions.cpp index 13b791a..5c82096 100644 --- a/src/systems/physics.cpp +++ b/src/systems/collisions.cpp @@ -1,4 +1,4 @@ -#include "systems/physics.hpp" +#include "systems/collisions.hpp" #include "components/transform.hpp" #include "components/collider.hpp" @@ -71,9 +71,11 @@ namespace engine { ec1->c->m_isColliding = true; ec1->c->m_lastEntityCollided = ec2->entity; ec1->c->m_lastCollisionNormal = glm::normalize(v); + ec1->c->m_lastCollisionPoint = ec1->pos + (v * ec1->c->colliders.sphereCollider.r / glm::sqrt(distanceSquared)); ec2->c->m_isColliding = true; ec2->c->m_lastEntityCollided = ec1->entity; ec2->c->m_lastCollisionNormal = -ec1->c->m_lastCollisionNormal; + ec2->c->m_lastCollisionPoint = ec1->c->m_lastCollisionPoint; } } else if ( (ec1->c->colliderType == ColliderType::PLANE && ec2->c->colliderType == ColliderType::SPHERE) || @@ -92,9 +94,12 @@ namespace engine { if (distance < sphere->c->colliders.sphereCollider.r) { plane->c->m_isColliding = true; plane->c->m_lastEntityCollided = sphere->entity; + plane->c->m_lastCollisionNormal = {0.0f, -1.0f, 0.0f}; + plane->c->m_lastCollisionPoint = {sphere->pos.x, plane->pos.y, sphere->pos.z}; sphere->c->m_isColliding = true; sphere->c->m_lastEntityCollided = plane->entity; sphere->c->m_lastCollisionNormal = {0.0f, 1.0f, 0.0f}; + sphere->c->m_lastCollisionPoint = plane->c->m_lastCollisionPoint; } } else { throw std::runtime_error("Collision combination not supported!"); diff --git a/test/src/camera_controller.cpp b/test/src/camera_controller.cpp index 9f3a0ff..250fa0f 100644 --- a/test/src/camera_controller.cpp +++ b/test/src/camera_controller.cpp @@ -43,39 +43,50 @@ void CameraControllerSystem::onUpdate(float ts) const float dt = ts; constexpr float G = 9.8f; - constexpr float MAX_SLOPE_ANGLE = glm::radians(20.0f); +// constexpr float MAX_SLOPE_ANGLE = glm::radians(20.0f); + constexpr float MAX_SLOPE_ANGLE = glm::radians(1000.0f); // treat every collider as a floor, (TODO: get wall collisions working so this can be removed) + constexpr float FLOOR_SINK_LEVEL = 0.05f; // how far into the floor to ground the player glm::vec3 norm = col->getLastCollisionNormal(); norm.y = 0.0f; glm::vec3 dir = glm::normalize(glm::rotateY(glm::vec3{ 1.0f, 0.0f, 0.0f }, c->m_yaw) + glm::rotateY(glm::vec3{ 0.0f, 0.0f, 1.0f }, c->m_yaw)); - const float slope = glm::half_pi() - glm::acos(glm::dot(dir, norm)); + const float slope = glm::length(glm::half_pi() - glm::acos(glm::dot(dir, norm))); bool isSliding = false; if (col->getIsColliding()) { - if (c->dy < 0.0f && slope <= MAX_SLOPE_ANGLE) { - // in the ground, push up a bit - t->position.y += dt; - c->dy = 0.0f; - } else { + if (slope > MAX_SLOPE_ANGLE) { // slide across wall isSliding = true; + } else { + if (c->dy < 0.0f && c->isGrounded == false) { + // in the ground, push up a bit + float floorY = col->getLastCollisionPoint().y; + t->position.y = floorY + col->colliders.sphereCollider.r - FLOOR_SINK_LEVEL; + c->dy = 0.0f; + c->isGrounded = true; + } } } - c->dy -= G * dt; + + if (col->getJustUncollided() && slope <= MAX_SLOPE_ANGLE) { + // just stopped colliding with a floor collider + c->isGrounded = false; + } + + if (c->isGrounded == false) + c->dy -= G * dt; // jumping constexpr float JUMPVEL = (float)2.82231110971133017648; //std::sqrt(2 * G * JUMPHEIGHT); - if (m_scene->app()->inputManager()->getButton("jump") && c->isJumping == false) { - if (col->getIsColliding()) - c->dy = JUMPVEL; + if (m_scene->app()->inputManager()->getButton("jump") && c->isGrounded == true) { + c->dy = JUMPVEL; } if (m_scene->app()->window()->getButton(engine::inputs::MouseButton::M_LEFT)) { c->dy += dt * c->thrust; - c->isJumping = true; } // in metres per second @@ -103,7 +114,7 @@ void CameraControllerSystem::onUpdate(float ts) const glm::vec3 d2zRotated = glm::rotateY(glm::vec3{ 0.0f, 0.0f, dz }, c->m_yaw); glm::vec3 hVel = (d2xRotated + d2zRotated); if (isSliding) { - hVel = glm::vec3{norm.z, 0.0f, norm.x}; + hVel = glm::vec3{norm.z, 0.0f, -norm.x}; } hVel *= SPEED; t->position += hVel * dt; @@ -114,7 +125,6 @@ void CameraControllerSystem::onUpdate(float ts) if (glm::length(t->position) > MAX_DISTANCE_FROM_ORIGIN) { t->position = { 0.0f, 5.0f, 0.0f }; c->dy = 0.0f; - c->isJumping = true; } /* ROTATION STUFF */ diff --git a/test/src/camera_controller.hpp b/test/src/camera_controller.hpp index ed2ed0e..6706180 100644 --- a/test/src/camera_controller.hpp +++ b/test/src/camera_controller.hpp @@ -10,7 +10,7 @@ struct CameraControllerComponent { const float walk_speed = 4.0f; - bool isJumping = false; + bool isGrounded = false; float dy = 0.0f; float standingHeight = 0.0f; const float thrust = 25.0f; diff --git a/test/src/game.cpp b/test/src/game.cpp index 934eac1..239ec22 100644 --- a/test/src/game.cpp +++ b/test/src/game.cpp @@ -63,7 +63,7 @@ void playGame() myScene->getSystem()->setCameraEntity(camera); - engine::util::loadMeshFromFile(myScene, app.getResourcePath("models/van/van.dae")); +// engine::util::loadMeshFromFile(myScene, app.getResourcePath("models/van/van.dae")); auto grassTexture = std::make_shared( app.gfx(), @@ -77,7 +77,7 @@ void playGame() auto enemyRenderable = myScene->addComponent(enemy); enemyRenderable->material = std::make_unique(app.getResource("engine.textured")); enemyRenderable->material->m_texture = app.getResource("engine.white"); - enemyRenderable->mesh = genSphereMesh(app.gfx(), 5.0f, 500, false); + enemyRenderable->mesh = genSphereMesh(app.gfx(), 5.0f, 50, false); auto enemyT = myScene->getComponent(enemy); enemyT->position.x += 10.0f; enemyT->position.y += 2.0f; @@ -90,7 +90,7 @@ void playGame() auto sphereRenderable = myScene->addComponent(sphere); sphereRenderable->material = std::make_unique(app.getResource("engine.textured")); sphereRenderable->material->m_texture = app.getResource("engine.white"); - sphereRenderable->mesh = genSphereMesh(app.gfx(), 100.0f, 100, true); + sphereRenderable->mesh = genSphereMesh(app.gfx(), 100.0f, 50, true); uint32_t light = myScene->createEntity("light"); myScene->getComponent(light)->position = glm::vec3{-10.0f, 10.0f, 10.0f};