// Copyright (c) 2023 Dominic Masters // // This software is released under the MIT License. // https://opensource.org/licenses/MIT #include "Box.hpp" using namespace Dawn; bool_t boxIsPointInside(glm::vec2 point, glm::vec2 min, glm::vec2 max) { return ( point.x >= min.x && point.x <= max.x && point.y >= min.y && point.y <= max.y ); } bool_t Dawn::boxCheckCollision( glm::vec2 posA, glm::vec2 minA, glm::vec2 maxA, glm::vec2 posB, glm::vec2 minB, glm::vec2 maxB, glm::vec2 velocity, glm::vec2 &normal, float_t &entryTime, float_t &exitTime, glm::vec2 &entryPoint, glm::vec2 &exitPoint ) { // Calculate the time intervals of overlap in the x and y axes glm::vec2 invEntry = glm::vec2(0.0f); glm::vec2 invExit = glm::vec2(0.0f); if (velocity.x >= 0.0f) { invEntry.x = ((minB.x + posB.x) - (maxA.x + posA.x)) / velocity.x; invExit.x = ((maxB.x + posB.x) - (minA.x + posA.x)) / velocity.x; } else { invEntry.x = ((maxB.x + posB.x) - (minA.x + posA.x)) / velocity.x; invExit.x = ((minB.x + posB.x) - (maxA.x + posA.x)) / velocity.x; } if (velocity.y >= 0.0f) { invEntry.y = ((minB.y + posB.y) - (maxA.y + posA.y)) / velocity.y; invExit.y = ((maxB.y + posB.y) - (minA.y + posA.y)) / velocity.y; } else { invEntry.y = ((maxB.y + posB.y) - (minA.y + posA.y)) / velocity.y; invExit.y = ((minB.y + posB.y) - (maxA.y + posA.y)) / velocity.y; } // Calculate the time of entry and exit for each axis glm::vec2 entry = glm::max(invEntry, glm::vec2(0.0f)); glm::vec2 exit = glm::min(invExit, glm::vec2(1.0f)); // Find the time of entry and exit entryTime = glm::max(entry.x, entry.y); exitTime = glm::min(exit.x, exit.y); // If there is no overlap in either axis, there is no collision if (entryTime > exitTime || entry.x < 0.0f && entry.y < 0.0f || entry.x > 1.0f || entry.y > 1.0f) { return false; } // Calculate the normal of the collision if (entry.x > entry.y) { if (invEntry.x < 0.0f) { normal = glm::vec2(1.0f, 0.0f); } else { normal = glm::vec2(-1.0f, 0.0f); } } else { if (invEntry.y < 0.0f) { normal = glm::vec2(0.0f, 1.0f); } else { normal = glm::vec2(0.0f, -1.0f); } } // Calculate the entry and exit points entryPoint = posA + velocity * entryTime; exitPoint = posA + velocity * exitTime; return true; } bool_t Dawn::boxIsBoxColliding( glm::vec2 posA, glm::vec2 minA, glm::vec2 maxA, glm::vec2 posB, glm::vec2 minB, glm::vec2 maxB ) { // Check for no overlap in X axis if (posA.x + maxA.x < posB.x + minB.x || posB.x + maxB.x < posA.x + minA.x) { return false; } // Check for no overlap in Y axis if (posA.y + maxA.y < posB.y + minB.y || posB.y + maxB.y < posA.y + minA.y) { return false; } return true; }