Elevate Engine 1
Loading...
Searching...
No Matches
GameObject.cpp
Go to the documentation of this file.
1#include "GameObject.h"
2
3#include <format>
4
5#include <entt/entt.hpp>
6#include <glm/vec3.hpp>
7#include <glm/mat4x4.hpp>
8#include <glm/gtx/matrix_decompose.hpp>
9
16
17
18namespace Elevate
19{
20 uint32_t GameObject::s_goIdCount = 0;
21
22 GameObject::GameObject(std::string name, std::shared_ptr<Scene> scene, std::shared_ptr<GameObject> parent)
23 : m_name(name), m_scene(scene.get()), m_parent(parent)
24 {
25 m_goId = s_goIdCount;
26 s_goIdCount++;
27 }
28
29 void GameObject::SetFromGlobalMatrix(const glm::mat4& newWorld)
30 {
31 glm::mat4 newLocal = m_parent ? glm::inverse(m_parent->GenGlobalMatrix()) * newWorld : newWorld;
32
33 glm::vec3 scale;
34 glm::quat rotationQuat;
35 glm::vec3 position;
36 glm::vec3 skew;
37 glm::vec4 perspective;
38
39 glm::decompose(newLocal, scale, rotationQuat, position, skew, perspective);
40 glm::vec3 rotationEuler = glm::degrees(glm::eulerAngles(rotationQuat));
41
42 SetScale(scale);
43 SetRotation(rotationEuler);
44 SetPosition(position);
45 }
46
48 {
49 glm::mat4 global = GenGlobalMatrix();
50 return glm::vec3(global[3]);
51 }
52
54 {
55 // TODO MAKE GETCOMPONENTS ONLY RETURN ACTIVE COMOPNENTS TO PREVENT THE CHECK
56 for (Component* comp : GetComponents())
57 {
58 if (comp->IsActive())
59 {
60 comp->Update();
61 }
62 }
63
64 for (std::shared_ptr<GameObject> child : m_childs)
65 {
66 child->Update();
67 }
68 }
69
71 {
72 // TODO MAKE GETCOMPONENTS ONLY RETURN ACTIVE COMOPNENTS TO PREVENT THE CHECK
73 for (Component* comp : GetComponents())
74 {
75 if (comp->IsActive())
76 {
77 comp->Render();
78 }
79 }
80
81 for (std::shared_ptr<GameObject> child : m_childs)
82 {
83 child->Render();
84 }
85 }
86
88 {
89 for (Component* comp : GetComponents())
90 {
91 if (comp->IsActive())
92 {
93 comp->OnNotify(e);
94 }
95 }
96
97 for (std::shared_ptr<GameObject> child : m_childs)
98 {
99 child->Notify(e);
100 }
101 }
102
104 {
105 if (m_entityId != EE_INVALID_ENTITY_ID && m_isInitialized)
106 {
108 }
109
110 for (Component* comp : GetComponents())
111 {
112 if (comp->IsActive())
113 {
114 comp->OnSetPosition();
115 }
116 }
117
118 for (std::shared_ptr<GameObject> child : m_childs)
119 {
120 child->OnSetPosition();
121 }
122 }
123
125 {
126 for (Component* comp : GetComponents())
127 {
128 if (comp->IsActive())
129 {
130 comp->OnSetRotation();
131 }
132 }
133
134 for (std::shared_ptr<GameObject> child : m_childs)
135 {
136 child->OnSetRotation();
137 }
138 }
139
141 {
142 for (Component* comp : GetComponents())
143 {
144 if (comp->IsActive())
145 {
146 comp->OnSetScale();
147 }
148 }
149
150 for (std::shared_ptr<GameObject> child : m_childs)
151 {
152 child->OnSetScale();
153 }
154 }
155
156 void GameObject::Initialize()
157 {
158 if (m_scene)
159 {
160 if (m_parent)
161 {
162 m_parent->AddChild(shared_from_this());
163 }
164 else
165 {
166 m_scene->AddRootObject(shared_from_this());
167 }
168
169 auto& registryMap = GetRegistryMap();
170 auto registryIt = registryMap.find(m_scene->m_registryId);
171
172 if (registryIt == registryMap.end()) {
173 EE_CORE_ERROR("Registry not found for scene '%s' with id: %d",
174 m_scene->GetName(), m_scene->m_registryId);
175 return;
176 }
177 if (!registryIt->second) {
178 EE_CORE_ERROR("Registry pointer is null for scene '%s' with id: %d",
179 m_scene->GetName(), m_scene->m_registryId);
180 return;
181 }
182 entt::entity entity = registryIt->second->create();
183 m_entityId = static_cast<std::uint32_t>(entity);
184
186 m_isInitialized = true;
187 }
188 else
189 {
190 EE_CORE_ERROR("Object '%s' must be linked with an existing scene!", m_name);
191 }
192 }
193
194 //GameObject::~GameObject()
195 //{
196 // if (m_scene)
197 // {
198 // auto& registryMap = GetRegistryMap();
199 // auto registryIt = registryMap.find(m_scene->m_registryId);
200
201 // if (registryIt == registryMap.end())
202 // {
203 // return;
204 // }
205 // if (!registryIt->second)
206 // {
207 // return;
208 // }
209
211{
213
214 //if (m_scene)
215 //{
216 // m_scene->m_registryId.destroy(entt::entity(m_entityId));
217 //} else EE_CORE_ERROR("Object '{0}' must be destroyed from an existing scene!", m_name);
218}
219
220 std::vector<Component*> GameObject::GetComponents()
221 {
222 std::vector<Component*> components;
223 if (!m_scene) return components;
224
225 for (auto& [type, entry] : ComponentRegistry::GetEntries()) {
226 if (Component* component = entry.getter(weak_from_this())) {
227 components.push_back(component);
228 }
229 }
230
231 return components;
232 }
233
235 {
236 // TODO MAKE GETCOMPONENTS ONLY RETURN ACTIVE COMOPNENTS TO PREVENT THE CHECK
237 for (Component* comp : GetComponents())
238 {
239 if (comp->IsActive())
240 {
241 comp->RenderInEditor();
242 }
243 }
244
245 for (std::shared_ptr<GameObject> child : m_childs)
246 {
247 child->RenderInEditor();
248 }
249 }
250
252 {
253 // TODO MAKE GETCOMPONENTS ONLY RETURN ACTIVE COMOPNENTS TO PREVENT THE CHECK
254 for (Component* comp : GetComponents())
255 {
256 if (comp->IsActive())
257 {
258 comp->RenderWhenSelected();
259 }
260 }
261
262 for (std::shared_ptr<GameObject> child : m_childs)
263 {
264 child->RenderWhenSelected();
265 }
266 }
267
268 void GameObject::SetParent(std::shared_ptr<GameObject> newParent)
269 {
270 if (newParent == m_parent)
271 return;
272
273 if (m_parent)
274 {
275 m_parent->RemoveChild(shared_from_this());
276 }
277
278 this->m_parent = newParent;
279
280 if (newParent)
281 {
282 newParent->AddChild(shared_from_this());
283 if (m_scene)
284 {
285 m_scene->RemoveFromRoot(shared_from_this());
286 }
287 }
288 else {
289 m_scene->AddRootObject(shared_from_this());
290 }
291 }
292
294 {
295 if (m_parent) {
296 m_parent->RemoveChild(shared_from_this());
297 }
298 else {
299 m_scene->RemoveFromRoot(shared_from_this());
300 }
301
302 auto childsCopy = m_childs;
303 for (const auto& child : childsCopy)
304 {
305 if (child)
306 {
307 child->Destroy();
308 }
309 }
310 m_childs.clear();
311 m_parent.reset();
312 }
313
314 void GameObject::AddChild(std::shared_ptr<GameObject> child)
315 {
316 if (child)
317 {
318 child->m_parent = shared_from_this();
319 m_childs.emplace(child);
320 m_scene->RemoveFromRoot(child);
321 }
322 }
323
324 void GameObject::RemoveChild(std::shared_ptr<GameObject> child)
325 {
326 m_childs.erase(child);
327 }
328
329 std::shared_ptr<GameObject> GameObject::Create(std::string name, std::shared_ptr<Scene> scene, std::shared_ptr<GameObject> parent)
330 {
331 std::shared_ptr<GameObject> obj = std::make_shared<GameObject>(name, scene, parent);
332 obj->Initialize();
333 obj->SetPosition({ 0.0f, 0.0f, 0.0f });
334 return obj;
335 }
336
337 // TODO MOVE SOMEWHERE ELSE
339 {
340 if (m_parent)
341 {
342 return m_parent->GenGlobalMatrix() * GetModelMatrix();
343 }
344 else
345 {
346 return GetModelMatrix();
347 }
348 }
349}
#define EE_INVALID_ENTITY_ID
Definition GameObject.h:14
static std::unordered_map< std::type_index, Entry > & GetEntries()
static std::shared_ptr< GameObject > Create(std::string name, std::shared_ptr< Scene > scene, std::shared_ptr< GameObject > parent=nullptr)
void OnSetRotation() override
void Notify(Event &event)
void RemoveChild(std::shared_ptr< GameObject > child)
glm::mat4 GenGlobalMatrix() const
void OnSetPosition() override
glm::vec3 GetGlobalPosition()
void OnSetScale() override
void SetParent(std::shared_ptr< GameObject > newParent)
void SetFromGlobalMatrix(const glm::mat4 &newWorld)
void AddChild(std::shared_ptr< GameObject > child)
GameObject(std::string name, std::shared_ptr< Scene > scene, std::shared_ptr< GameObject > parent=nullptr)
std::vector< Component * > GetComponents()
const glm::mat4 & GetModelMatrix() const
void SetRotation(glm::vec3 rotation)
void SetPosition(glm::vec3 pos)
void SetScale(glm::vec3 scale)
const std::string & GetName() const
Definition Scene.h:47
static void UpdatePosition(GameObject *obj)
static void UnregisterGameObject(GameObject *obj)
static void RegisterGameObject(GameObject *obj)
std::unordered_map< uint32_t, std::unique_ptr< entt::registry > > & GetRegistryMap()