-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcollision.cpp
89 lines (77 loc) · 3.44 KB
/
collision.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include "collision.hpp"
#include <algorithm>
//////////////////////////////////////////////////////////////////////
/// areColliding_SphereVsBox
//////////////////////////////////////////////////////////////////////
bool areColliding_SphereVsBox(
const vec2& posA, const float& radA, const vec2& posB,
const vec2& scaleB) noexcept {
const auto sphereLeft = posA.x() - radA;
const auto sphereRight = posA.x() + radA;
const auto sphereBottom = posA.y() - radA;
const auto sphereTop = posA.y() + radA;
const auto boxLeft = posB.x() - scaleB.x();
const auto boxRight = posB.x() + scaleB.x();
const auto boxBottom = posB.y() - scaleB.y();
const auto boxTop = posB.y() + scaleB.y();
return (
sphereRight > boxLeft && sphereLeft < boxRight &&
sphereTop > boxBottom && sphereBottom < boxTop);
}
//////////////////////////////////////////////////////////////////////
/// areColliding_BoxVsBox
//////////////////////////////////////////////////////////////////////
bool areColliding_BoxVsBox(
const vec2& posA, const vec2& sclA, const vec2& posB,
const vec2& sclB) noexcept {
const bool x = std::abs(posA.data()[0] - posB.data()[0]) <=
(sclA.data()[0] + sclB.data()[0]);
const bool y = std::abs(posA.data()[1] - posB.data()[1]) <=
(sclA.data()[1] + sclB.data()[1]);
return x && y;
/*const auto aLeft = posA.x() - sclA.x();
const auto aRight = posA.x() + sclA.x();
const auto aBot = posA.y() - sclA.y();
const auto aTop = posA.y() + sclA.y();
const auto bLeft = posB.x() - sclB.x();
const auto bRight = posB.x() + sclB.x();
const auto bBot = posB.y() - sclB.y();
const auto bTop = posB.y() + sclB.y();
return (aRight >= bLeft && aLeft <= bRight && aTop >= bBot && aBot <=
bTop);*/
}
//////////////////////////////////////////////////////////////////////
/// rayBBoxIntersection
//////////////////////////////////////////////////////////////////////
std::tuple<bool, vec2, vec2, float> rayBBoxIntersection(
const vec2& rayPos, const vec2& rayDir, const vec2& boxCenter,
const vec2& boxExtents, const bool projectBackwards) noexcept {
const vec2 boxMin = boxCenter - boxExtents;
const vec2 boxMax = boxCenter + boxExtents;
const vec2 invDir = vec2(1.0F) / rayDir;
const auto tx1 = (boxMin.x() - rayPos.x()) * invDir.x();
const auto tx2 = (boxMax.x() - rayPos.x()) * invDir.x();
auto tmin = std::min(tx1, tx2);
auto tmax = std::max(tx1, tx2);
const auto ty1 = (boxMin.y() - rayPos.y()) * invDir.y();
const auto ty2 = (boxMax.y() - rayPos.y()) * invDir.y();
tmin = std::max(tmin, std::min(ty1, ty2));
tmax = std::min(tmax, std::max(ty1, ty2));
if (tmax >= tmin) {
const auto& projectAmount = projectBackwards ? tmin : tmax;
const vec2 intersectionPoint = rayPos + (rayDir * projectAmount);
const vec2 p = intersectionPoint - boxCenter;
const vec2 d = (boxMin - boxMax) * 0.5;
constexpr float bias = 1.00001F;
const vec2 normal =
vec2(
static_cast<float>(
static_cast<int>(p.x() / std::abs(d.x()) * bias)),
static_cast<float>(
static_cast<int>(p.y() / std::abs(d.x()) * bias)))
.normalize();
return std::make_tuple(
true, intersectionPoint, normal, std::abs(projectAmount));
}
return std::make_tuple(false, vec2(0), vec2(0), 0.0F);
}