97 lines
2.7 KiB
C++
97 lines
2.7 KiB
C++
// 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;
|
|
} |