Unravel Engine C++ Reference
Loading...
Searching...
No Matches
scene.cpp
Go to the documentation of this file.
1#include "scene.h"
2#include "uuid/uuid.h"
11
14
17
20
24#include <engine/events.h>
25#include <engine/play_mode.h>
28
29#include <logging/logging.h>
30
31namespace unravel
32{
33
34namespace
35{
36
37// auto clone_entity_impl(entt::registry& r, entt::handle entity) -> entt::handle
38// {
39// entt::handle object(r, r.create());
40
41// for(auto [id, storage] : r.storage())
42// {
43// auto name = storage.type().name();
44
45// if(name.find("edyn::") != std::string_view::npos)
46// {
47// continue;
48// }
49
50// if(name.find("bullet::") != std::string_view::npos)
51// {
52// continue;
53// }
54
55// if(storage.contains(entity) && !storage.contains(object))
56// {
57// storage.push(object, storage.value(entity));
58// }
59// }
60
61// return object;
62// }
63
64template<typename Registry>
65void remove_all_components(entt::basic_handle<Registry> handle)
66{
67 auto& registry = *handle.registry();
68 auto entity = handle.entity();
69
70 for(auto [id, storage] : registry.storage())
71 {
72 storage.remove(entity);
73 }
74}
75
76auto get_scene_registry_impl() -> std::vector<scene*>&
77{
78 static std::vector<scene*> scenes;
79 return scenes;
80}
81
82void register_scene(scene* scn)
83{
84 auto& scenes = get_scene_registry_impl();
85 scenes.emplace_back(scn);
86}
87
88void unregister_scene(scene* scn)
89{
90 auto& scenes = get_scene_registry_impl();
91 scenes.erase(std::remove(scenes.begin(), scenes.end(), scn), scenes.end());
92}
93
94
95template<typename ...Ts>
96void destroy_dependent_components(entt::registry& r, entt::entity e)
97{
98 r.remove<Ts...>(e);
99}
100
101template<typename ...Ts>
102void destroy_dependent_components_recursive(entt::registry& r, entt::entity e)
103{
104 if(!r.valid(e))
105 {
106 return;
107 }
108 destroy_dependent_components<Ts...>(r, e);
109
110
111 auto transform = r.try_get<transform_component>(e);
112 if(transform)
113 {
114 for(auto child : transform->get_children())
115 {
116 destroy_dependent_components_recursive<Ts...>(r, child);
117 }
118 }
119}
120
121auto on_load_callback(hpp::span<const entt::handle> entities) -> void
122{
123 if(!entities.empty())
124 {
125 APP_SCOPE_PERF("On Load Callback");
126 auto& ctx = engine::context();
127 auto& play = ctx.get_cached<play_mode>();
128
129 if(play.is_simulation_running())
130 {
131 auto& rsys = ctx.get_cached<rendering_system>();
132 auto& ssys = ctx.get_cached<script_system>();
133
134 delta_t dt(0.016667f);
135 rsys.on_play_begin(entities, dt);
136 ssys.on_play_begin(entities);
137 }
138 }
139}
140
141} // namespace
142
143auto scene::get_all_scenes() -> const std::vector<scene*>&
144{
145 return get_scene_registry_impl();
146}
147
148scene::scene(const std::string& tag_name)
149 : tag(tag_name)
150{
151 register_scene(this);
152
153 registry = std::make_unique<entt::registry>();
154 unload();
155
159
162
165
168
171
174
177
178 on_destroy<prefab_component>(*registry).connect<&destroy_dependent_components_recursive<prefab_id_component>>();
179
180
183
187
190
191
192}
193
195{
196 unload();
197 unregister_scene(this);
198}
199
201{
202 registry->clear<script_component>();
203 registry->clear();
204 auto reserved_entity = registry->create();
205 source = {};
206}
207
208void scene::reload(bool call_callbacks)
209{
210 auto src = source;
211 if(!src)
212 {
213 return;
214 }
215 unload();
216 load_from(src, call_callbacks);
217}
218
219auto scene::load_from(const asset_handle<scene_prefab>& pfb, bool call_callbacks) -> bool
220{
221 if(call_callbacks)
222 {
223 push_on_load_callbacks({on_load_callback});
224 }
225
226 bool result = load_from_prefab(pfb, *this);
227
228 if(result)
229 {
230 source = pfb;
231 }
232 if(call_callbacks)
233 {
235 }
236 return result;
237}
238auto scene::instantiate_out(const asset_handle<prefab>& pfb, entt::handle& e, bool call_callbacks) -> bool
239{
240 return instantiate_out(*registry, pfb, e, call_callbacks);
241}
242
243auto scene::instantiate_out(entt::registry& reg, const asset_handle<prefab>& pfb, entt::handle& e, bool call_callbacks) -> bool
244{
245 APP_SCOPE_PERF("Instantiate Out Prefab");
246 if(call_callbacks)
247 {
248 push_on_load_callbacks({on_load_callback});
249 }
250 bool result = load_from_prefab_out(pfb, reg, e);
251 if(call_callbacks)
252 {
254 }
255 return result;
256}
257
258auto scene::instantiate(const asset_handle<prefab>& pfb, bool call_callbacks) -> entt::handle
259{
260 APP_SCOPE_PERF_OWNED(fmt::format("Instantiate Prefab {}", pfb.id()));
261 if(call_callbacks)
262 {
263 push_on_load_callbacks({on_load_callback});
264 }
265 auto e = load_from_prefab(pfb, *registry);
266 if(call_callbacks)
267 {
269 }
270 return e;
271}
272
273auto scene::instantiate(const asset_handle<prefab>& pfb, entt::handle parent, bool call_callbacks) -> entt::handle
274{
275 APP_SCOPE_PERF_OWNED(fmt::format("Instantiate Prefab {}", pfb.id()));
276 auto load_callback_override = [&](hpp::span<const entt::handle> entities) -> void
277 {
278 if(parent && !entities.empty())
279 {
280 auto e = entities[0];
281 if(e)
282 {
283 auto& trans_comp = e.get<transform_component>();
284 trans_comp.set_parent(parent, false);
285 }
286 else
287 {
288 APPLOG_ERROR("Entity not found in instantiate callback");
289 }
290
291 }
292
293 if(call_callbacks)
294 {
295 on_load_callback(entities);
296 }
297 };
298 push_on_load_callbacks({load_callback_override});
299 auto e = load_from_prefab(pfb, *registry);
301
302 return e;
303}
304
305auto scene::create_entity(entt::registry& r, const std::string& name, entt::handle parent) -> entt::handle
306{
307 entt::handle ent(r, r.create());
308 ent.emplace<tag_component>().name = !name.empty() ? name : "Entity";
309 ent.emplace<layer_component>();
310 ent.emplace<id_component>().regenerate_id();
311
312 auto& transform = ent.emplace<transform_component>();
313 if(parent)
314 {
315 transform.set_parent(parent, false);
316 }
317
318 return ent;
319}
320
321auto find_entity_by_uuid(entt::registry& registry, const hpp::uuid& target_uuid) -> entt::handle
322{
323 if(target_uuid.is_nil())
324 {
325 return {};
326 }
327 auto view = registry.view<id_component>();
328 for(auto e : view)
329 {
330 if(view.get<id_component>(e).id == target_uuid)
331 {
332 return entt::handle(registry, e);
333 }
334 }
335 return {};
336}
337
338auto scene::find_entity_by_uuid(const hpp::uuid& target_uuid) const -> entt::handle
339{
340 return ::unravel::find_entity_by_uuid(*registry, target_uuid);
341}
342
343auto scene::get_scene(entt::handle entity) -> scene*
344{
345 if(!entity)
346 {
347 return nullptr;
348 }
349
350 for(auto scene : get_all_scenes())
351 {
352 if(scene->registry.get() == entity.registry())
353 {
354 return scene;
355 }
356 }
357 return nullptr;
358}
359
360auto scene::create_entity(const std::string& tag, entt::handle parent) -> entt::handle
361{
362 return create_entity(*registry, tag, parent);
363}
364
365void scene::clone_entity(entt::handle& clone_to, entt::handle clone_from, bool keep_parent, bool call_callbacks)
366{
367 APP_SCOPE_PERF("Clone Entity");
368
369 auto load_callback_override = [&](hpp::span<const entt::handle> entities) -> void
370 {
371 if(keep_parent)
372 {
373 // get cloned from transform
374 auto& clone_from_component = clone_from.get<transform_component>();
375
376 // // get cloned to transform
377 auto& clone_to_component = clone_to.get<transform_component>();
378
379 // set parent from original
380 auto parent = clone_from_component.get_parent();
381 if(parent)
382 {
383 clone_to_component.set_parent(parent, false);
384 }
385 }
386
387 if(call_callbacks)
388 {
389 on_load_callback(entities);
390 }
391 };
392 push_on_load_callbacks({load_callback_override});
393 clone_entity_from_stream(clone_from, clone_to);
395
396}
397
398auto scene::clone_entity(entt::handle clone_from, bool keep_parent, bool call_callbacks) -> entt::handle
399{
400 APP_SCOPE_PERF("Clone Entity To");
401
402 auto* reg = clone_from.registry();
403 entt::handle clone_to(*reg, reg->create());
404 clone_entity(clone_to, clone_from, keep_parent, call_callbacks);
405 return clone_to;
406}
407
408void scene::clone_scene(const scene& src_scene, scene& dst_scene, bool call_callbacks)
409{
410 APP_SCOPE_PERF("Clone Scene");
411 if(call_callbacks)
412 {
413 push_on_load_callbacks({on_load_callback});
414 }
415 clone_scene_from_stream(src_scene, dst_scene);
416 if(call_callbacks)
417 {
419 }
420}
421
422void scene::clear_entity(entt::handle& handle)
423{
424 remove_all_components(handle);
425}
426
427
428auto scene::create_handle(entt::entity e) -> entt::handle
429{
430 entt::handle handle(*registry, e);
431 return handle;
432}
433
434auto scene::create_handle(entt::entity e) const -> entt::const_handle
435{
436 entt::const_handle handle(*registry, e);
437 return handle;
438}
439
440auto scene::find_entity_by_prefab_uuid(entt::handle entity, const hpp::uuid& target_uuid) -> entt::handle
441{
442 if (!entity)
443 {
444 return {};
445 }
446
447 auto* id_comp = entity.try_get<prefab_id_component>();
448 if (id_comp && id_comp->id == target_uuid)
449 {
450 return entity;
451 }
452
453 // Search children
454 auto* transform = entity.try_get<transform_component>();
455 if (transform)
456 {
457 for (auto child : transform->get_children())
458 {
459 auto found = find_entity_by_prefab_uuid(child, target_uuid);
460 if (found)
461 {
462 return found;
463 }
464 }
465 }
466
467 return {};
468}
469
470
471} // namespace unravel
472
473namespace entt
474{
476{
477 if(handle)
478 {
479 registry = handle.registry();
480 if(auto id = handle.try_get<unravel::id_component>())
481 {
482 uuid = id->id;
483 }
484 }
485}
487{
488 return ::unravel::find_entity_by_uuid(*registry, uuid);
489}
490}
static void on_create_component(entt::registry &r, entt::entity e)
Called when the component is created.
static void on_destroy_component(entt::registry &r, entt::entity e)
Called when the component is destroyed.
static void on_create_component(entt::registry &r, entt::entity e)
Called when the component is created.
static void on_destroy_component(entt::registry &r, entt::entity e)
Called when the component is destroyed.
static void on_destroy_component(entt::registry &r, entt::entity e)
static void on_create_component(entt::registry &r, entt::entity e)
static void on_destroy_component(entt::registry &r, entt::entity e)
static void on_create_component(entt::registry &r, entt::entity e)
static void on_destroy_component(entt::registry &r, entt::entity e)
Called when a physics component is destroyed.
static void on_create_component(entt::registry &r, entt::entity e)
Called when a physics component is created.
static void on_create_cc_component(entt::registry &r, entt::entity e)
static void on_destroy_cc_component(entt::registry &r, entt::entity e)
Class that contains core data for audio listeners. There can only be one instance of it per scene.
static void on_destroy_component(entt::registry &r, entt::entity e)
Called when the component is destroyed.
static void on_create_component(entt::registry &r, entt::entity e)
Called when the component is created.
Component that handles transformations (position, rotation, scale, etc.) in the ACE framework.
static void on_create_component(entt::registry &r, entt::entity e)
Called when the component is created.
auto set_parent(const entt::handle &parent, bool global_stays=true) -> bool
Sets the parent entity.
static void on_destroy_component(entt::registry &r, entt::entity e)
Called when the component is destroyed.
auto get_parent() const noexcept -> entt::handle
RELATIONSHIP.
std::chrono::duration< float > delta_t
uint16_t view
std::string name
Definition hub.cpp:33
std::string tag
Definition hub.cpp:32
#define APPLOG_ERROR(...)
Definition logging.h:20
const aiScene * scene
bgfx::Transform transform
Definition graphics.h:42
void clone_scene_from_stream(const scene &src_scene, scene &dst_scene)
Definition entity.cpp:1395
auto on_destroy(entt::registry &reg) -> decltype(auto)
Definition scene.h:50
void pop_on_load_callbacks()
Definition entity.cpp:104
auto on_update(entt::registry &reg) -> decltype(auto)
Definition scene.h:44
auto on_construct(entt::registry &reg) -> decltype(auto)
Definition scene.h:38
auto load_from_prefab_out(const asset_handle< prefab > &pfb, entt::registry &registry, entt::handle &obj) -> bool
Definition entity.cpp:1037
auto on_load(entt::registry &reg) -> typename on_load_bus< T >::sink_t
Definition scene.h:27
auto find_entity_by_uuid(entt::registry &registry, const hpp::uuid &target_uuid) -> entt::handle
Finds an entity by id_component UUID in a registry (no scene wrapper required).
Definition scene.cpp:321
void push_on_load_callbacks(const post_load_callbacks &callbacks)
Definition entity.cpp:96
auto load_from_prefab(const asset_handle< prefab > &pfb, entt::registry &registry) -> entt::handle
Definition entity.cpp:1101
void clone_entity_from_stream(entt::const_handle src_obj, entt::handle &dst_obj)
Definition entity.cpp:1198
#define APP_SCOPE_PERF_OWNED(name)
Create a scoped performance timer that records to the timeline profiler. Only accepts string literals...
Definition profiler.h:680
#define APP_SCOPE_PERF(name_literal)
Create a scoped performance timer that records to the timeline profiler. Only accepts string literals...
Definition profiler.h:675
entt::handle entity
Thread-safe handle to an asset.
entt::registry * registry
Definition scene.h:225
auto resolve() const -> entt::handle
Definition scene.cpp:486
hpp::uuid uuid
Definition scene.h:226
uhandle()=default
static auto context() -> rtti::context &
Definition engine.cpp:111
hpp::uuid id
The unique identifier for the entity.
Component that provides a unique identifier (UUID) for an entity.
Component that provides a layer mask for an entity.
Component that provides a unique identifier (UUID) for a prefab.
static void on_update_component(entt::registry &r, entt::entity e)
Called when the component is updated.
static void on_create_component(entt::registry &r, entt::entity e)
Called when the component is created.
static void on_destroy_component(entt::registry &r, entt::entity e)
Called when the component is destroyed.
Represents a scene in the ACE framework, managing entities and their relationships.
Definition scene.h:70
auto find_entity_by_uuid(const hpp::uuid &target_uuid) const -> entt::handle
Finds an entity by UUID in the scene.
Definition scene.cpp:338
void clear_entity(entt::handle &handle)
Definition scene.cpp:422
void reload(bool call_callbacks=true)
Reloads the scene from the source prefab asset.
Definition scene.cpp:208
auto instantiate_out(const asset_handle< prefab > &pfb, entt::handle &, bool call_callbacks=true) -> bool
Instantiates a prefab in the scene.
Definition scene.cpp:238
asset_handle< scene_prefab > source
The source prefab asset handle for the scene.
Definition scene.h:182
~scene()
Destroys the scene and cleans up resources.
Definition scene.cpp:194
auto load_from(const asset_handle< scene_prefab > &pfb, bool call_callbacks=true) -> bool
Loads a scene from a prefab asset.
Definition scene.cpp:219
static auto get_all_scenes() -> const std::vector< scene * > &
Definition scene.cpp:143
auto clone_entity(entt::handle clone_from, bool keep_parent=true, bool call_callbacks=true) -> entt::handle
Clones an existing entity in the scene.
Definition scene.cpp:398
auto instantiate(const asset_handle< prefab > &pfb, bool call_callbacks=true) -> entt::handle
Definition scene.cpp:258
auto create_entity(const std::string &tag={}, entt::handle parent={}) -> entt::handle
Creates an entity in the scene with an optional tag and parent.
Definition scene.cpp:360
static auto get_scene(entt::handle entity) -> scene *
Gets the scene from an entity handle.
Definition scene.cpp:343
void unload()
Unloads the scene, removing all entities.
Definition scene.cpp:200
static void clone_scene(const scene &src_scene, scene &dst_scene, bool call_callbacks=true)
Clones the entities from one scene to another.
Definition scene.cpp:408
std::unique_ptr< entt::registry > registry
The registry that manages all entities in the scene.
Definition scene.h:187
scene(const std::string &tag_name)
Constructs a new scene.
Definition scene.cpp:148
auto create_handle(entt::entity e) -> entt::handle
Creates an entity in the scene.
Definition scene.cpp:428
static auto find_entity_by_prefab_uuid(entt::handle root_entity, const hpp::uuid &target_uuid) -> entt::handle
Finds an entity by UUID in the scene.
Definition scene.cpp:440
Component that provides a tag (name or label) for an entity.
static void on_create_component(entt::registry &r, entt::entity e)
static void on_load_component(entt::registry &r, entt::entity e)
static void on_destroy_component(entt::registry &r, entt::entity e)
gfx::uniform_handle handle
Definition uniform.cpp:9
std::string tag_name