Monad Engine da02fba2
> Undercity Codex_
Loading...
Searching...
No Matches
Scene.cpp
Go to the documentation of this file.
1#include "scene/Scene.h"
2#include "scene/components/AnimationComponent.h"
3#include "scene/components/CameraComponent.h"
4#include "scene/components/LightComponent.h"
5#include "scene/components/MeshComponent.h"
6#include "scene/components/PhysicsComponent.h"
7#include "scene/components/PlayerControllerComponent.h"
8#include "scene/components/AudioComponent.h"
9#include "scene/components/AudioListenerComponent.h"
11#include "Engine.h"
12
13#include <algorithm>
14
15namespace eng
16{
18 {
19 AnimationComponent::Register();
20 CameraComponent::Register();
21 LightComponent::Register();
22 MeshComponent::Register();
23 PhysicsComponent::Register();
24 PlayerControllerComponent::Register();
25 AudioComponent::Register();
26 AudioListenerComponent::Register();
27 SpriteComponent::Register();
28 }
29
30 void Scene::Update(float deltaTime)
31 {
32 m_objects.erase(
33 std::remove_if(m_objects.begin(), m_objects.end(),
34 [](const std::unique_ptr<GameObject>& obj) { return !obj->IsAlive(); }),
35 m_objects.end()
36 );
37
38 for (auto& obj : m_objectsToAdd)
39 {
40 SetParent(obj.first, obj.second);
41 }
42 m_objectsToAdd.clear();
43
44 m_isUpdating = true;
45 for (auto it = m_objects.begin(); it != m_objects.end();)
46 {
47 if ((*it)->IsAlive())
48 {
49 (*it)->Update(deltaTime);
50 ++it;
51 }
52 else
53 {
54 it = m_objects.erase(it);
55 }
56 }
57 m_isUpdating = false;
58 }
59
61 {
62 m_objects.clear();
63 }
64
65 GameObject* Scene::CreateObject(const std::string& name, GameObject* parent)
66 {
67 auto obj = new GameObject();
68 obj->SetName(name);
69 obj->m_scene = this;
70 if (m_isUpdating)
71 {
72 m_objectsToAdd.push_back({ obj, parent });
73 }
74 else
75 {
76 SetParent(obj, parent);
77 }
78 return obj;
79 }
80
81 GameObject* Scene::CreateObject(const std::string& type, const std::string& name, GameObject* parent)
82 {
84 if (obj)
85 {
86 obj->SetName(name);
87 obj->m_scene = this;
88 if (m_isUpdating)
89 {
90 m_objectsToAdd.push_back({ obj, parent });
91 }
92 else
93 {
94 SetParent(obj, parent);
95 }
96 }
97 return obj;
98 }
99
101 {
102 bool result = false;
103 auto currentParent = obj->GetParent();
104
105 if (parent == nullptr)
106 {
107 if (currentParent != nullptr)
108 {
109 auto it = std::find_if(
110 currentParent->m_children.begin(),
111 currentParent->m_children.end(),
112 [obj](const std::unique_ptr<GameObject>& el) {
113 return el.get() == obj;
114 }
115 );
116
117 if (it != currentParent->m_children.end())
118 {
119 m_objects.push_back(std::move(*it));
120 obj->m_parent = nullptr;
121 currentParent->m_children.erase(it);
122 result = true;
123 }
124 }
125 // No parent currently. This can be in 2 cases
126 // 1. The object is in the scene root
127 // 2. The object has been just created
128 else
129 {
130 auto it = std::find_if(
131 m_objects.begin(),
132 m_objects.end(),
133 [obj](const std::unique_ptr<GameObject>& el) {
134 return el.get() == obj;
135 }
136 );
137
138 if (it == m_objects.end())
139 {
140 std::unique_ptr<GameObject> objHolder(obj);
141 m_objects.push_back(std::move(objHolder));
142 result = true;
143 }
144 }
145 }
146 // We are trying to add it as a child of another object
147 else
148 {
149 if (currentParent != nullptr)
150 {
151 auto it = std::find_if(
152 currentParent->m_children.begin(),
153 currentParent->m_children.end(),
154 [obj](const std::unique_ptr<GameObject>& el) {
155 return el.get() == obj;
156 }
157 );
158
159 if (it != currentParent->m_children.end())
160 {
161 bool found = false;
162 auto currentElement = parent;
163 while (currentElement)
164 {
165 if (currentElement == obj)
166 {
167 found = true;
168 break;
169 }
170 currentElement = currentElement->GetParent();
171 }
172
173 if (!found)
174 {
175 parent->m_children.push_back(std::move(*it));
176 obj->m_parent = parent;
177 currentParent->m_children.erase(it);
178 result = true;
179 }
180 }
181 }
182 // No parent currently. This can be in 2 cases
183 // 1. The object is in the scene root
184 // 2. The object has been just created
185 else
186 {
187 auto it = std::find_if(
188 m_objects.begin(),
189 m_objects.end(),
190 [obj](const std::unique_ptr<GameObject>& el) {
191 return el.get() == obj;
192 }
193 );
194
195 // The object has been hust created
196 if (it == m_objects.end())
197 {
198 std::unique_ptr<GameObject> objHolder(obj);
199 parent->m_children.push_back(std::move(objHolder));
200 obj->m_parent = parent;
201 result = true;
202 }
203 else
204 {
205 bool found = false;
206 auto currentElement = parent;
207 while (currentElement)
208 {
209 if (currentElement == obj)
210 {
211 found = true;
212 break;
213 }
214 currentElement = currentElement->GetParent();
215 }
216
217 if (!found)
218 {
219 parent->m_children.push_back(std::move(*it));
220 obj->m_parent = parent;
221 m_objects.erase(it);
222 result = true;
223 }
224 }
225 }
226 }
227
228 return result;
229 }
230
232 {
233 m_mainCamera = camera;
234 }
235
237 {
238 return m_mainCamera;
239 }
240
241 std::vector<LightData> Scene::CollectLights()
242 {
243 std::vector<LightData> lights;
244 for (auto& obj : m_objects)
245 {
246 CollectLightsRecursive(obj.get(), lights);
247 }
248 return lights;
249 }
250
251 std::shared_ptr<Scene> Scene::Load(const std::string& path)
252 {
253 const std::string contents = Engine::GetInstance().GetFileSystem().LoadAssetFileText(path);
254 if (contents.empty())
255 {
256 return nullptr;
257 }
258
259 auto json = nlohmann::json::parse(contents);
260 if (json.empty())
261 {
262 return nullptr;
263 }
264
265 auto result = std::make_shared<Scene>();
266
267 const std::string sceneName = json.value("name", "noname");
268
269 if (json.contains("objects") && json["objects"].is_array())
270 {
271 const auto& objects = json["objects"];
272
273 for (const auto& obj : objects)
274 {
275 result->LoadObject(obj, nullptr);
276 }
277 }
278
279 if (json.contains("camera"))
280 {
281 std::string cameraObjName = json.value("camera", "");
282 for (const auto& child : result->m_objects)
283 {
284 if (auto object = child->FindChildByName(cameraObjName))
285 {
286 result->SetMainCamera(object);
287 break;
288 }
289 }
290 }
291
292 return result;
293 }
294
295 void Scene::CollectLightsRecursive(GameObject* obj, std::vector<LightData>& out)
296 {
297 if (auto light = obj->GetComponent<LightComponent>())
298 {
299 LightData data;
300 data.color = light->GetColor();
301 data.position = obj->GetWorldPosition();
302 out.push_back(data);
303 }
304
305 for (auto& child : obj->m_children)
306 {
307 CollectLightsRecursive(child.get(), out);
308 }
309 }
310
311 void Scene::LoadObject(const nlohmann::json& jsonObject, GameObject* parent)
312 {
313 const std::string name = jsonObject.value("name", "Object");
314
315 GameObject* gameObject = nullptr;
316
317 if (jsonObject.contains("type"))
318 {
319 const std::string type = jsonObject.value("type", "");
320 if (type == "gltf")
321 {
322 std::string path = jsonObject.value("path", "");
323 gameObject = GameObject::LoadGLTF(path, this);
324 if (gameObject)
325 {
326 gameObject->SetParent(parent);
327 gameObject->SetName(name);
328 }
329 }
330 else
331 {
332 gameObject = CreateObject(type, name, parent);
333 }
334 }
335 else
336 {
337 gameObject = CreateObject(name, parent);
338 }
339
340 if (!gameObject)
341 {
342 return;
343 }
344
345 // Read transform
346 if (jsonObject.contains("position"))
347 {
348 auto posObj = jsonObject["position"];
349 glm::vec3 pos;
350 pos.x = posObj.value("x", 0.0f);
351 pos.y = posObj.value("y", 0.0f);
352 pos.z = posObj.value("z", 0.0f);
353 gameObject->SetPosition(pos);
354 }
355
356 if (jsonObject.contains("rotation"))
357 {
358 auto rotObj = jsonObject["rotation"];
359 glm::quat rot;
360 rot.x = rotObj.value("x", 0.0f);
361 rot.y = rotObj.value("y", 0.0f);
362 rot.z = rotObj.value("z", 0.0f);
363 rot.w = rotObj.value("w", 1.0f);
364 gameObject->SetRotation(rot);
365 }
366
367 if (jsonObject.contains("scale"))
368 {
369 auto scaleObj = jsonObject["scale"];
370 glm::vec3 scale;
371 scale.x = scaleObj.value("x", 1.0f);
372 scale.y = scaleObj.value("y", 1.0f);
373 scale.z = scaleObj.value("z", 1.0f);
374 gameObject->SetScale(scale);
375 }
376
377 gameObject->LoadProperties(jsonObject);
378
379 if (jsonObject.contains("components") && jsonObject["components"].is_array())
380 {
381 const auto& components = jsonObject["components"];
382 for (const auto& comp : components)
383 {
384 const std::string type = comp.value("type", "");
385 Component* component = ComponentFactory::GetInstance().CreateComponent(type);
386 if (component)
387 {
388 component->LoadProperties(comp);
389 gameObject->AddComponent(component);
390 }
391 }
392 }
393
394 if (jsonObject.contains("children") && jsonObject["children"].is_array())
395 {
396 const auto& children = jsonObject["children"];
397 for (const auto& child : children)
398 {
399 LoadObject(child, gameObject);
400 }
401 }
402
403 gameObject->Init();
404 }
405}
static ComponentFactory & GetInstance()
Definition Component.cpp:20
Component * CreateComponent(const std::string &name)
Definition Component.cpp:26
virtual void LoadProperties(const nlohmann::json &json)
Definition Component.cpp:7
FileSystem & GetFileSystem()
Definition Engine.cpp:205
static Engine & GetInstance()
Definition Engine.cpp:50
std::string LoadAssetFileText(const std::string &relativePath)
static GameObjectFactory & GetInstance()
GameObject * CreateGameObject(const std::string &typeName)
static GameObject * LoadGLTF(const std::string &path, Scene *scene)
glm::vec3 GetWorldPosition() const
void SetName(const std::string &name)
GameObject * GetParent()
GameObject * m_parent
Definition GameObject.h:83
std::vector< std::unique_ptr< GameObject > > m_children
Definition GameObject.h:85
std::vector< LightData > CollectLights()
Definition Scene.cpp:241
void Clear()
Definition Scene.cpp:60
void SetMainCamera(GameObject *camera)
Definition Scene.cpp:231
static std::shared_ptr< Scene > Load(const std::string &path)
Definition Scene.cpp:251
void Update(float deltaTime)
Definition Scene.cpp:30
GameObject * CreateObject(const std::string &name, GameObject *parent=nullptr)
Definition Scene.cpp:65
bool SetParent(GameObject *obj, GameObject *parent)
Definition Scene.cpp:100
GameObject * GetMainCamera()
Definition Scene.cpp:236
static void RegisterTypes()
Definition Scene.cpp:17
glm::vec3 color
Definition Common.h:18
glm::vec3 position
Definition Common.h:19