From f32a42b39379c40dc96b3f92e22ed616416879f9 Mon Sep 17 00:00:00 2001 From: bailwillharr Date: Sun, 12 Feb 2023 14:50:29 +0000 Subject: [PATCH] Collision stuff --- include/components/collider.hpp | 4 ---- include/systems/collisions.hpp | 1 + src/systems/collisions.cpp | 13 +++++++++++-- test/src/camera_controller.cpp | 26 +++++++++++--------------- test/src/camera_controller.hpp | 3 +++ test/src/game.cpp | 12 +++++++----- 6 files changed, 33 insertions(+), 26 deletions(-) diff --git a/include/components/collider.hpp b/include/components/collider.hpp index 40ee905..766da99 100644 --- a/include/components/collider.hpp +++ b/include/components/collider.hpp @@ -19,11 +19,7 @@ namespace engine { bool isTrigger = false; // entity receives an event on collision enter and exit AABB aabb{}; // broad phase - bool getIsColliding() { return isColliding; } - private: - bool isColliding = false; - }; } diff --git a/include/systems/collisions.hpp b/include/systems/collisions.hpp index c7f516d..294ec8d 100644 --- a/include/systems/collisions.hpp +++ b/include/systems/collisions.hpp @@ -21,6 +21,7 @@ namespace engine { bool isCollisionEnter; // false == collision exit uint32_t collidedEntity; // the entity that this entity collided with glm::vec3 normal; // the normal of the surface this entity collided with; ignored on collision exit + glm::vec3 point; // where the collision was detected }; private: diff --git a/src/systems/collisions.cpp b/src/systems/collisions.cpp index a5c0b08..28995a2 100644 --- a/src/systems/collisions.cpp +++ b/src/systems/collisions.cpp @@ -35,8 +35,8 @@ namespace engine { const float PZdistance = glm::abs(subjectCentre.z - object.pos2.z); const float NZdistance = glm::abs(subjectCentre.z - object.pos1.z); const std::array distances { PXdistance, NXdistance, PYdistance, NYdistance, PZdistance, NZdistance }; - const auto maxDistance = std::max_element(distances.begin(), distances.end()); - const int index = maxDistance - distances.begin(); + const auto minDistance = std::min_element(distances.begin(), distances.end()); + const int index = minDistance - distances.begin(); switch (index) { case 0: // P_X @@ -135,6 +135,10 @@ namespace engine { info.isCollisionEnter = true; info.collidedEntity = possibleCollision.dynamicEntity; info.normal = getAABBNormal(possibleCollision.staticAABB, possibleCollision.dynamicAABB); + + AABB object = possibleCollision.dynamicAABB; + info.point = object.pos2; + m_collisionInfos.emplace_back(possibleCollision.staticEntity, info); } if (possibleCollision.dynamicTrigger) { @@ -142,6 +146,11 @@ namespace engine { info.isCollisionEnter = true; info.collidedEntity = possibleCollision.staticEntity; info.normal = getAABBNormal(possibleCollision.dynamicAABB, possibleCollision.staticAABB); + + AABB object = possibleCollision.staticAABB; + info.point = object.pos2; + + m_collisionInfos.emplace_back(possibleCollision.dynamicEntity, info); } } diff --git a/test/src/camera_controller.cpp b/test/src/camera_controller.cpp index cdb9f0f..19a61f6 100644 --- a/test/src/camera_controller.cpp +++ b/test/src/camera_controller.cpp @@ -40,13 +40,12 @@ 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(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(); + glm::vec3 norm = c->lastCollisionNormal; norm.y = 0.0f; @@ -55,22 +54,22 @@ void CameraControllerSystem::onUpdate(float ts) bool isSliding = false; - if (col->getIsColliding()) { + if (c->justCollided) { 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; + float floorY = c->lastCollisionPoint.y; + t->position.y = floorY + 1.5f - FLOOR_SINK_LEVEL; c->dy = 0.0f; c->isGrounded = true; } } } - if (col->getJustUncollided() && slope <= MAX_SLOPE_ANGLE) { + if (c->justCollided == false && slope <= MAX_SLOPE_ANGLE) { // just stopped colliding with a floor collider c->isGrounded = false; } @@ -88,15 +87,10 @@ void CameraControllerSystem::onUpdate(float ts) c->dy += dt * c->thrust; } -*/ - // in metres per second float SPEED = c->walk_speed; if (m_scene->app()->inputManager()->getButton("sprint")) SPEED *= 10.0f; - if (m_scene->app()->inputManager()->getButton("fire")) t->position.y += dt * SPEED; - if (m_scene->app()->inputManager()->getButton("aim")) t->position.y -= dt * SPEED; - float dx = m_scene->app()->inputManager()->getAxis("movex"); float dz = (-m_scene->app()->inputManager()->getAxis("movey")); @@ -116,10 +110,9 @@ void CameraControllerSystem::onUpdate(float ts) const glm::vec3 d2xRotated = glm::rotateY(glm::vec3{ dx, 0.0f, 0.0f }, c->m_yaw); const glm::vec3 d2zRotated = glm::rotateY(glm::vec3{ 0.0f, 0.0f, dz }, c->m_yaw); glm::vec3 hVel = (d2xRotated + d2zRotated); -/* if (isSliding) { + if (isSliding) { hVel = glm::vec3{norm.z, 0.0f, -norm.x}; } -*/ hVel *= SPEED; t->position += hVel * dt; t->position.y += c->dy * dt; @@ -170,11 +163,14 @@ void CameraControllerSystem::onUpdate(float ts) m_scene->app()->window()->toggleFullscreen(); } + c->justCollided = false; + } // called once per frame void CameraControllerSystem::onEvent(engine::PhysicsSystem::CollisionEvent info) { - INFO("NORMAL X: {}, Y: {}, Z: {}", info.normal.x, info.normal.y, info.normal.z); - t->position += info.normal; + c->justCollided = info.isCollisionEnter; + c->lastCollisionNormal = info.normal; + c->lastCollisionPoint = info.point; } diff --git a/test/src/camera_controller.hpp b/test/src/camera_controller.hpp index 8b62cfc..a83900f 100644 --- a/test/src/camera_controller.hpp +++ b/test/src/camera_controller.hpp @@ -19,6 +19,9 @@ struct CameraControllerComponent { float standingHeight = 0.0f; const float thrust = 25.0f; + glm::vec3 lastCollisionNormal{}; + glm::vec3 lastCollisionPoint{}; + bool justCollided = false; }; class CameraControllerSystem : public engine::System, public engine::EventHandler { diff --git a/test/src/game.cpp b/test/src/game.cpp index f866e1c..026b063 100644 --- a/test/src/game.cpp +++ b/test/src/game.cpp @@ -97,20 +97,20 @@ void playGame(bool enableFrameLimiter) myScene->getComponent(skybox)->position = { -1.0f, -1.0f, -1.0f }; } - /* enemy sphere */ + /* enemy cube */ { uint32_t enemy = myScene->createEntity("enemy"); 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, 50, false); + enemyRenderable->mesh = genCuboidMesh(app.gfx(), 10.0f, 10.0f, 10.0f); auto enemyTransform = myScene->getComponent(enemy); enemyTransform->position.x = 10.0f; enemyTransform->position.y = 0.0f; enemyTransform->position.z = 14.0f; auto enemyCollider = myScene->addComponent(enemy); enemyCollider->isStatic = true; - enemyCollider->aabb = { { -5.0f, -5.0f, -5.0f }, { 5.0f, 5.0f, 5.0f } }; // A box enclosing the sphere + enemyCollider->aabb = { { 0.0f, 0.0f, 0.0f }, { 10.0f, 10.0f, 10.0f } }; // A box enclosing the sphere } /* floor */ @@ -127,11 +127,13 @@ void playGame(bool enableFrameLimiter) } // cubes! - { + if (0) { constexpr int SIZE = 10; const uint32_t cubeParent = myScene->createEntity("cubeParent"); - myScene->getComponent(cubeParent)->position = { 10.0f, 5.0f, 10.0f }; + engine::TransformComponent* cubeParentTransform = myScene->getComponent(cubeParent); + cubeParentTransform->position = { 100.0f, 0.0f, 100.0f }; + cubeParentTransform->scale = { 100.0f, 100.0f, 100.0f }; std::shared_ptr cubeMesh = genCuboidMesh(app.gfx(), 0.1f, 0.1f, 0.1f); const auto cubeMaterial = std::make_shared(app.getResource("engine.textured"));