-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcollision.cpp
More file actions
118 lines (97 loc) · 2.6 KB
/
collision.cpp
File metadata and controls
118 lines (97 loc) · 2.6 KB
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include "collision.h"
std::vector<CollisionLayer> COLLISION_LAYERS = { CollisionLayer::Default, CollisionLayer::Terrain, };
Collision::Collision()
{
this->clear();
}
void Collision::addObject(GameObject* gameObject)
{
CollisionLayer objectLayer = static_cast<Collider*>(gameObject->getComponent(ComponentType::T_Collider))->getLayer();
this->objects[objectLayer][gameObject->getID()] = gameObject;
}
void Collision::removeObject(GameObject* gameObject)
{
if (gameObject->hasComponent(ComponentType::T_Collider))
{
CollisionLayer objectLayer = static_cast<Collider*>(gameObject->getComponent(ComponentType::T_Collider))->getLayer();
this->objects[objectLayer].erase(gameObject->getID());
}
}
void Collision::clear()
{
for (CollisionLayer layer : COLLISION_LAYERS)
{
this->objects[layer] = std::unordered_map<int, GameObject*>();
}
}
void Collision::processRemovals()
{
for (auto& layerPair : this->objects) {
auto& objectMap = layerPair.second;
for (auto it = objectMap.begin(); it != objectMap.end(); ) {
if (!it->second || it->second->getQueuedForRemoval()) {
it = objectMap.erase(it);
}
else {
++it;
}
}
}
}
void Collision::update()
{
this->resolve();
}
void Collision::resolve()
{
for (const auto& layerPair : this->objects)
{
CollisionLayer layer = layerPair.first;
for (const auto& objectPair : layerPair.second)
{
GameObject* object = objectPair.second;
Collider* collider = static_cast<Collider*>(object->getComponent(ComponentType::T_Collider));
collider->resetManifold();
if (object->transform->getStatic())
{
continue;
}
this->search(collider);
for (GameObject* overlappingObject : this->overlappingObjects)
{
Collider* otherCollider = static_cast<Collider*>(overlappingObject->getComponent(ComponentType::T_Collider));
if (otherCollider->isTrigger)
{
otherCollider->setManifold(true, collider);
continue;
}
Manifold manifold = collider->intersects(otherCollider);
if (manifold.colliding)
{
// std::cout << "COLLIDING\n";
collider->resolveOverlap(manifold);
collider->resetManifold();
}
}
}
}
}
void Collision::search(Collider* collider)
{
this->overlappingObjects.clear();
for (CollisionLayer layer : collider->getCollideLayers())
{
for (const auto& objectPair : this->objects[layer])
{
Collider* other = static_cast<Collider*>(objectPair.second->getComponent(ComponentType::T_Collider));
if (collider == other)
{
continue;
}
if (other->getRect().intersects(collider->getRect()))
{
this->overlappingObjects.push_back(objectPair.second);
}
}
}
}