diff --git a/sources/Component/Collision/CollisionComponent.cpp b/sources/Component/Collision/CollisionComponent.cpp index 8f7db0d7..678b0898 100644 --- a/sources/Component/Collision/CollisionComponent.cpp +++ b/sources/Component/Collision/CollisionComponent.cpp @@ -16,8 +16,8 @@ namespace BBM } CollisionComponent::CollisionComponent(WAL::Entity &entity, - const WAL::Callback &onCollide, - const WAL::Callback &onCollided, + const WAL::Callback &onCollide, + const WAL::Callback &onCollided, Vector3f positionOffset, Vector3f bound) : WAL::Component(entity), @@ -28,8 +28,8 @@ namespace BBM {} CollisionComponent::CollisionComponent(WAL::Entity &entity, - const WAL::Callback &onCollide, - const WAL::Callback &onCollided, + const WAL::Callback &onCollide, + const WAL::Callback &onCollided, float positionOffset, float boundSize) : WAL::Component(entity), diff --git a/sources/Component/Collision/CollisionComponent.hpp b/sources/Component/Collision/CollisionComponent.hpp index 933d2c31..1be3590d 100644 --- a/sources/Component/Collision/CollisionComponent.hpp +++ b/sources/Component/Collision/CollisionComponent.hpp @@ -14,10 +14,17 @@ namespace BBM class CollisionComponent : public WAL::Component { public: + //! @brief Used to tell the collided axis + enum CollidedAxis { + X = 1, + Y = 2, + Z = 4 + }; + //! @brief onCollide functions to be called - WAL::Callback onCollide; + WAL::Callback onCollide; //! @brief onCollided functions to be called - WAL::Callback onCollided; + WAL::Callback onCollided; //! @brief Bound size on all axis Vector3f bound; //! @brief Offset from the position component @@ -31,15 +38,15 @@ namespace BBM //! @brief Constructor with a WAL::Callback CollisionComponent(WAL::Entity &entity, - const WAL::Callback &onCollide, - const WAL::Callback &onCollided, + const WAL::Callback &onCollide, + const WAL::Callback &onCollided, Vector3f positionOffset, Vector3f bound); //! @brief Constructor with a WAL::Callback, same boundSize for all axis CollisionComponent(WAL::Entity &entity, - const WAL::Callback &onCollide, - const WAL::Callback &onCollided, + const WAL::Callback &onCollide, + const WAL::Callback &onCollided, float positionOffset, float boundSize = 0); diff --git a/sources/Map/Map.cpp b/sources/Map/Map.cpp index e688fa77..937343c8 100644 --- a/sources/Map/Map.cpp +++ b/sources/Map/Map.cpp @@ -3,7 +3,8 @@ // Edited by Benjamin Henry on 5/26/21. // -#include +#include "Component/Collision/CollisionComponent.hpp" +#include "System/Collision/CollisionSystem.hpp" #include "Map.hpp" #include @@ -11,7 +12,7 @@ namespace RAY3D = RAY::Drawables::Drawables3D; namespace BBM { - void MapGenerator::wallCollide(WAL::Entity &entity, const WAL::Entity &wall) + void MapGenerator::wallCollide(WAL::Entity &entity, const WAL::Entity &wall, int collidedAxis) { auto *mov = entity.tryGetComponent(); auto posspec = entity.getComponent(); @@ -20,20 +21,16 @@ namespace BBM if (!mov) return; - std::cout << "collided coords " << posspec.position << " cube " << posspecwall.position << std::endl; - //mov->_velocity = BBM::Vector3f (); - return; auto &pos = entity.getComponent(); const auto &wallPos = wall.getComponent(); auto diff = pos.position + mov->getVelocity() - wallPos.position; -// mov->_velocity = Vector3f(); - if (diff.x <= 0 && mov->_velocity.x < 0) + //mov->_velocity = Vector3f(); + //return; + if (collidedAxis & CollisionComponent::CollidedAxis::X) mov->_velocity.x = 0; - if (diff.x >= 0 && mov->_velocity.x > 0) + if (collidedAxis & CollisionComponent::CollidedAxis::Y) mov->_velocity.x = 0; - if (diff.z <= 0 && mov->_velocity.z < 0) - mov->_velocity.z = 0; - if (diff.z >= 0 && mov->_velocity.z > 0) + if (collidedAxis & CollisionComponent::CollidedAxis::Z) mov->_velocity.z = 0; } @@ -60,7 +57,7 @@ namespace BBM if (!(i % 2) && !(j % 2)) { scene->addEntity("Unbreakable Wall") .addComponent(i, 0, j) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePng)); } } @@ -74,25 +71,25 @@ namespace BBM scene->addEntity("Bottom Wall") .addComponent(Vector3f((width + 1) / 2, 0, -1)) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(width + 3, 1, 1)); scene->addEntity("Upper Wall") .addComponent(Vector3f((width + 1) / 2, 0, height + 1)) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(width + 3, 1, 1)); scene->addEntity("Left Wall") .addComponent(Vector3f(width + 1, 0, height / 2)) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(1, 1, height + 1)); scene->addEntity("Right Wall") .addComponent(Vector3f(-1, 0, height / 2)) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) .addComponent(unbreakableObj, std::make_pair(MAP_DIFFUSE, unbreakablePnj), RAY::Vector3(1, 1, height + 1)); @@ -142,7 +139,7 @@ namespace BBM scene->addEntity("Breakable Block") .addComponent(coords) .addComponent(1) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) .addComponent(breakableObj, std::make_pair(MAP_DIFFUSE, breakablePng)); } @@ -175,7 +172,7 @@ namespace BBM scene->addEntity("Unbreakable Block") .addComponent(coords) - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, .75) .addComponent(UnbreakableObj, std::make_pair(MAP_DIFFUSE, UnbreakablePng)); } diff --git a/sources/Map/Map.hpp b/sources/Map/Map.hpp index f6b082a8..f705eebf 100644 --- a/sources/Map/Map.hpp +++ b/sources/Map/Map.hpp @@ -156,7 +156,7 @@ namespace BBM static const std::string secondFloorHolePath; public: - static void wallCollide(WAL::Entity &entity, const WAL::Entity &wall); + static void wallCollide(WAL::Entity &entity, const WAL::Entity &wall, int collidedAxis); //! @param width Width of the map diff --git a/sources/Runner/Runner.cpp b/sources/Runner/Runner.cpp index 06ff3cb2..af08e264 100644 --- a/sources/Runner/Runner.cpp +++ b/sources/Runner/Runner.cpp @@ -80,11 +80,11 @@ namespace BBM .addComponent(10, 20, 10) .addComponent(Vector3f(2, 0, 2)); scene->addEntity("cube") - .addComponent(0, 0, 0) + .addComponent(-5, 0, -5) .addComponent(Vector3f(0, 0, 0), Vector3f(3, 3, 3), RED) .addComponent() .addComponent() - .addComponent(WAL::Callback(), &MapGenerator::wallCollide, -1, 3); + .addComponent(WAL::Callback(), &MapGenerator::wallCollide, -1, 3); std::srand(std::time(nullptr)); //MapGenerator::loadMap(16, 16, MapGenerator::createMap(16, 16), scene); return scene; diff --git a/sources/System/Collision/CollisionSystem.cpp b/sources/System/Collision/CollisionSystem.cpp index 50c5662a..14b6c12a 100644 --- a/sources/System/Collision/CollisionSystem.cpp +++ b/sources/System/Collision/CollisionSystem.cpp @@ -14,7 +14,7 @@ namespace BBM : System(wal) { } - bool CollisionSystem::collide(Vector3f minA, Vector3f maxA, Vector3f minB, Vector3f maxB) + bool CollisionSystem::boxesCollide(Vector3f minA, Vector3f maxA, Vector3f minB, Vector3f maxB) { bool overlapX = (minA.x <= maxB.x && maxA.x >= minB.x) || (minB.x <= maxA.x && maxB.x >= minA.x); bool overlapY = (minA.y <= maxB.y && maxA.y >= minB.y) || (minB.y <= maxA.y && maxB.y >= minA.y); @@ -28,32 +28,55 @@ namespace BBM auto &posA = entity.get(); auto &colA = entity.get(); Vector3f pointA = posA.position + colA.positionOffset; + Vector3f pointAx; + Vector3f pointAy; + Vector3f pointAz; - if (auto *movable = entity->tryGetComponent()) - pointA += movable->getVelocity(); + if (auto *movable = entity->tryGetComponent()) { + auto vel = movable->getVelocity(); + pointAx.x += vel.x; + pointAy.y += vel.y; + pointAz.z += vel.z; + } - Vector3f minA = Vector3f::min(pointA, pointA + colA.bound); - Vector3f maxA = Vector3f::max(pointA, pointA + colA.bound); + Vector3f minAx = Vector3f::min(pointAx, pointAx + colA.bound); + Vector3f maxAx = Vector3f::max(pointAx, pointAx + colA.bound); + + Vector3f minAy = Vector3f::min(pointAy, pointAy + colA.bound); + Vector3f maxAy = Vector3f::max(pointAy, pointAy + colA.bound); + + Vector3f minAz = Vector3f::min(pointAz, pointAz + colA.bound); + Vector3f maxAz = Vector3f::max(pointAz, pointAz + colA.bound); for (auto &[other, posB, colB] : this->getView()) { if (other.getUid() == entity->getUid()) continue; auto pointB = posB.position + colB.positionOffset; + int collidedAxis = 0; // TODO if B is also a movable we don't check with it's changing position Vector3f minB = Vector3f::min(pointB, pointB + colB.bound); Vector3f maxB = Vector3f::max(pointB, pointB + colB.bound); - if (collide(minA, maxA, minB, maxB)) { - std::cout << "collided" << std::endl + if (boxesCollide(minAx, maxAx, minB, maxB)) { + /* std::cout << "collided" << std::endl << "minA " << minA << std::endl << "maxA " << maxA << std::endl << "minB " << minB << std::endl - << "maxB " << maxB << std::endl; - return; - colA.onCollide(entity, other); - colB.onCollided(entity, other); + << "maxB " << maxB << std::endl;*/ + //return; + collidedAxis += CollisionComponent::CollidedAxis::X; + } + if (boxesCollide(minAy, maxAy, minB, maxB)) { + collidedAxis += CollisionComponent::CollidedAxis::Y; + } + if (boxesCollide(minAz, maxAz, minB, maxB)) { + collidedAxis += CollisionComponent::CollidedAxis::Z; + } + if (collidedAxis) { + colA.onCollide(entity, other, collidedAxis); + colB.onCollided(entity, other, collidedAxis); } } } diff --git a/sources/System/Collision/CollisionSystem.hpp b/sources/System/Collision/CollisionSystem.hpp index 2c0f5491..e1e75ede 100644 --- a/sources/System/Collision/CollisionSystem.hpp +++ b/sources/System/Collision/CollisionSystem.hpp @@ -31,6 +31,6 @@ namespace BBM CollisionSystem &operator=(const CollisionSystem &) = delete; //! @brief check AABB collision - static bool collide(Vector3f minA, Vector3f maxA, Vector3f minB, Vector3f maxB); + static bool boxesCollide(Vector3f minA, Vector3f maxA, Vector3f minB, Vector3f maxB); }; } \ No newline at end of file