-
Notifications
You must be signed in to change notification settings - Fork 0
/
DrawList.hpp
128 lines (97 loc) · 3.01 KB
/
DrawList.hpp
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
#pragma once
#include <memory>
#include <vector>
#include <algorithm>
#include <execution>
#include "Math.hpp"
struct AABB // Axis-Aligned Bounding Boxes
{
glm::vec3 Min;
glm::vec3 Max;
};
struct DrawableObject : std::enable_shared_from_this<DrawableObject>
{
VertexArrayObject VAO = VertexArrayObject();
VertexBufferObject VBO = VertexBufferObject();
ElementBufferObject EBO = ElementBufferObject();
std::string TypeName;
std::vector<Vertex> Vertices;
Location Loc;
AABB BoundingBox;
void CalculateAABB()
{
if (Vertices.size() == 0)
return;
auto MinVertex = Vertices[0].Position;
auto MaxVertex = Vertices[0].Position;
for (auto&& Vertex : Vertices)
{
MinVertex = glm::min(MinVertex, Vertex.Position);
MaxVertex = glm::max(MaxVertex, Vertex.Position);
}
BoundingBox.Min = MinVertex + Loc.Vec;
BoundingBox.Max = MaxVertex + Loc.Vec;
}
virtual void Draw(std::shared_ptr<ShaderProgram> Shader) = 0;
void Push();
};
class Drawlist
{
inline static std::shared_ptr<Drawlist> InternalInstance;
inline static std::vector<std::shared_ptr<DrawableObject>> Drawables;
public:
static auto Singleton()
{
if (!InternalInstance)
{
InternalInstance = std::make_shared<Drawlist>();
}
return InternalInstance;
}
static void Push(std::shared_ptr<DrawableObject> InDrawable)
{
Singleton()->Drawables.emplace_back(InDrawable);
}
static void Draw(std::shared_ptr<ShaderProgram> Shader)
{
for (auto&& Drawable : Singleton()->Drawables)
{
Drawable->Draw(Shader);
}
}
};
void DrawableObject::Push()
{
Drawlist::Push(shared_from_this());
}
template <typename T, typename... ArgsT>
auto SpawnDrawable(Location InWorldLocation, std::shared_ptr<Texture2D> InTexture, ArgsT... Args)
{
auto D = std::make_shared<T>(InWorldLocation, InTexture, Args...);
D->Push();
return D;
}
bool AABBIntersection(AABB BoundingBox, const glm::vec3& RayOrigin, const glm::vec3& RayDirection)
{
glm::vec3 InvDir = 1.0f / RayDirection;
glm::vec3 tMin = (BoundingBox.Min - RayOrigin) * InvDir;
glm::vec3 tMax = (BoundingBox.Max - RayOrigin) * InvDir;
glm::vec3 t1 = glm::min(tMin, tMax);
glm::vec3 t2 = glm::max(tMin, tMax);
float tNear = glm::max(glm::max(t1.x, t1.y), t1.z);
float tFar = glm::min(glm::min(t2.x, t2.y), t2.z);
return tNear <= tFar && tFar >= 0.0f;
}
inline std::vector<std::shared_ptr<struct DrawableObject>> HitScanTargets;
std::vector<std::shared_ptr<struct DrawableObject>> CheckHitScanTargets(const glm::vec3& RayOrigin, const glm::vec3& RayDirection)
{
std::vector<std::shared_ptr<struct DrawableObject>> HitTargets;
for (auto&& Target : HitScanTargets)
{
if (AABBIntersection(Target->BoundingBox, RayOrigin, RayDirection))
{
HitTargets.emplace_back(Target);
}
}
return HitTargets;
}