-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathShapes.cpp
More file actions
132 lines (103 loc) · 5.98 KB
/
Copy pathShapes.cpp
File metadata and controls
132 lines (103 loc) · 5.98 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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include "Shapes.h"
#include <cassert>
#include <glm/glm.hpp>
bool CheckCircleCircle(const glm::vec2& Circle1Position, const Circle& Circle1Shape, const glm::vec2& Circle2Position, const Circle& Circle2Shape)
{
//Determines distance between circles
glm::vec2 offset = Circle1Position - Circle2Position;
float distance = glm::length(offset);
//Determines the sum of the radii
float sum = Circle1Shape.Radius + Circle2Shape.Radius;
//If distance is less than sum, then collision has occured
return distance < sum;
}
bool CheckAABBAABB(const glm::vec2& AABB1Position, const AABB& AABB1Shape, const glm::vec2& AABB2Position, const AABB& AABB2Shape)
{
return AABB1Position.x - AABB1Shape.HalfExtents.x < AABB2Position.x + AABB2Shape.HalfExtents.x && //left within right collision
AABB1Position.x + AABB1Shape.HalfExtents.x > AABB2Position.x - AABB2Shape.HalfExtents.x && //right within left collision
AABB1Position.y - AABB1Shape.HalfExtents.y < AABB2Position.y + AABB2Shape.HalfExtents.y && //top within bottom collision
AABB1Position.y + AABB1Shape.HalfExtents.y > AABB2Position.y - AABB2Shape.HalfExtents.y; //right within top collision
}
bool CheckCircleAABB(const glm::vec2& PositionA, const Circle& CircleA, const glm::vec2& PositionB, const AABB& AABB)
{
//Finds the nearest point in the AABB in the direction of the circle
float DistanceX = PositionA.x - glm::clamp(PositionA.x, PositionB.x - AABB.HalfExtents.x, PositionB.x + AABB.HalfExtents.x);
float DistanceY = PositionA.y - glm::clamp(PositionA.y, PositionB.y - AABB.HalfExtents.y, PositionB.y + AABB.HalfExtents.y);
//Is considered to be in collision if the distance to that point is less than the circle's radius
return (DistanceX * DistanceX + DistanceY * DistanceY) < CircleA.Radius * CircleA.Radius;
}
bool CheckCircleCircle(const glm::vec2& Shape1Position, const Shape& Shape1, const glm::vec2& Shape2Position, const Shape& Shape2)
{
assert(Shape1.Type == ShapeType::CIRCLE && "Called CheckCircleCircle but a circle wasn't provided.");
assert(Shape2.Type == ShapeType::CIRCLE && "Called CheckCircleCircle but a circle wasn't provided.");
return CheckCircleCircle(Shape1Position, Shape1.CircleData, Shape2Position, Shape2.CircleData);
}
bool CheckAABBAABB(const glm::vec2& Shape1Position, const Shape& Shape1, const glm::vec2& Shape2Position, const Shape& Shape2)
{
assert(Shape1.Type == ShapeType::AABB && "Called CheckAABBAABB but an AABB wasn't provided.");
assert(Shape2.Type == ShapeType::AABB && "Called CheckAABBAABB but an AABB wasn't provided.");
return CheckAABBAABB(Shape1Position, Shape1.AABBData, Shape2Position, Shape2.AABBData);
}
bool CheckCircleAABB(const glm::vec2& Shape1Position, const Shape& Shape1, const glm::vec2& Shape2Position, const Shape& Shape2)
{
assert(Shape1.Type == ShapeType::CIRCLE && "Called CheckCircleAABB but a Circle wasn't provided for shape 1.");
assert(Shape2.Type == ShapeType::AABB && "Called CheckCircleAABB but an AABB wasn't provided for shape 2.");
return CheckCircleAABB(Shape1Position, Shape1.CircleData, Shape2Position, Shape2.AABBData);
}
glm::vec2 DepenetrateCircleCircle(const glm::vec2& PositionA, const Circle& CircleA, const glm::vec2& PositionB, const Circle& CircleB, float& Penetration)
{
//Gets the distance between the two circles
float distance = glm::length(PositionB - PositionA);
//Adds the sum of the two radii
float radii = CircleA.Radius + CircleB.Radius;
//Finds the difference and places it into the Penetration parameter
Penetration = radii - distance;
//Returns the direction to correct along
return glm::normalize(PositionB - PositionA);
}
glm::vec2 DepenetrateCircleCircle(const glm::vec2& PositionA, const Shape& ShapeA, const glm::vec2& PositionB, const Shape& ShapeB, float& Penetration)
{
return DepenetrateCircleCircle(PositionA, ShapeA.CircleData, PositionB, ShapeB.CircleData, Penetration);
}
glm::vec2 DepenetrateAABBAABB(const glm::vec2& PositionA, const Shape& AABB1, const glm::vec2& PositionB, const Shape& AABB2, float& Penetration)
{
//Calculates the overlap on each axis
float overlapX = (AABB1.AABBData.HalfExtents.x + AABB2.AABBData.HalfExtents.x) - abs(PositionB.x - PositionA.x);
float overlapY = (AABB1.AABBData.HalfExtents.y + AABB2.AABBData.HalfExtents.y) - abs(PositionB.y - PositionA.y);
//Returns the direction to correct along
if (overlapX < overlapY)
{
Penetration = overlapX;
return glm::normalize(PositionB - PositionA);
}
else
{
Penetration = overlapY;
return glm::normalize(PositionB - PositionA);
}
}
glm::vec2 DepenetrateCircleAABB(const glm::vec2& CirclePosition, const Shape& CircleA, const glm::vec2& AABBPosition, const Shape& AABB, float& Penetration)
{
//Finds the nearest point in the AABB in the direction of the circle
float NearestXPoint = CirclePosition.x - glm::clamp(CirclePosition.x, AABBPosition.x - AABB.AABBData.HalfExtents.x, AABBPosition.x + AABB.AABBData.HalfExtents.x);
float NearestYPoint = CirclePosition.y - glm::clamp(CirclePosition.y, AABBPosition.y - AABB.AABBData.HalfExtents.y, AABBPosition.y + AABB.AABBData.HalfExtents.y);
//Gets the center of the provided circle
glm::vec2 center = GetCenter(CirclePosition.x - CircleA.CircleData.Radius, CirclePosition.x + CircleA.CircleData.Radius,
CirclePosition.y - CircleA.CircleData.Radius, CirclePosition.y + CircleA.CircleData.Radius);
//Gets the penetration depth and the collision normal
if (NearestXPoint < NearestYPoint)
{
Penetration = CircleA.CircleData.Radius - (center.y - NearestXPoint);
return glm::normalize(NearestXPoint - center);
}
else
{
Penetration = CircleA.CircleData.Radius - (center.x - NearestYPoint);
return glm::normalize(NearestYPoint - center);
}
}
glm::vec2 GetCenter(float x1, float x2, float y1, float y2)
{
glm::vec2 circleCenter = { (x1 + x2) / 2, (y1 + y2) / 2 };
return circleCenter;
}