5#include "../graphics/Skybox.h"
6#include "hellfire/ecs/CameraComponent.h"
10 environment_ = std::make_unique<SceneEnvironment>();
14 "assets/skyboxes/px.png",
15 "assets/skyboxes/nx.png",
16 "assets/skyboxes/py.png",
17 "assets/skyboxes/ny.png",
18 "assets/skyboxes/pz.png",
19 "assets/skyboxes/nz.png"
22 environment_->set_skybox(*skybox);
33 auto entity = std::make_unique<
Entity>(id, unique_name);
37 entities_[id] = std::move(entity);
38 root_entities_.push_back(id);
41 entities_[id]->initialize_scripts();
47 const auto it = entities_.find(id);
48 if (it == entities_.end())
return;
51 it->second->cleanup_scripts();
58 const std::vector<EntityID> children = get_children(id);
59 for (
const EntityID child_id: children) {
60 destroy_entity(child_id);
64 if (
const auto parent_it = parent_map_.find(id); parent_it != parent_map_.end()) {
65 const EntityID parent_id = parent_it->second;
66 auto &siblings = children_map_[parent_id];
67 std::erase(siblings, id);
68 parent_map_.erase(parent_it);
71 std::erase(root_entities_, id);
75 children_map_.erase(id);
82 const auto it = entities_.find(id);
83 return it != entities_.end() ? it->second.get() :
nullptr;
87 const auto it = entities_.find(id);
88 return it != entities_.end() ? it->second.get() :
nullptr;
92 if (potential_descendant == potential_ancestor)
return true;
95 const auto it = children_map_.find(potential_ancestor);
96 if (it == children_map_.end())
return false;
98 for (
const EntityID child : it->second) {
99 if (is_descendant(potential_descendant, child))
return true;
106 if (entities_.find(child_id) == entities_.end())
return;
107 if (parent_id != 0 && entities_.find(parent_id) == entities_.end())
return;
113 if (
auto it = parent_map_.find(child_id); it != parent_map_.end()) {
114 EntityID old_parent = it->second;
115 auto &siblings = children_map_[old_parent];
116 siblings.erase(std::remove(siblings.begin(), siblings.end(), child_id), siblings.end());
119 root_entities_.erase(std::remove(root_entities_.begin(), root_entities_.end(), child_id),
120 root_entities_.end());
124 if (parent_id != 0) {
125 parent_map_[child_id] = parent_id;
126 children_map_[parent_id].push_back(child_id);
129 parent_map_.erase(child_id);
130 root_entities_.push_back(child_id);
139 const auto it = parent_map_.find(entity_id);
140 return it != parent_map_.end() ? it->second : 0;
144 const auto it = parent_map_.find(entity_id);
145 return it != parent_map_.end();
149 const auto it = children_map_.find(parent_id);
150 return it != children_map_.end() ? it->second : std::vector<EntityID>{};
154 for (
const EntityID root_id: root_entities_) {
155 if (
const Entity *entity = get_entity(root_id)) {
156 entity->initialize_scripts();
162 for (
const EntityID root_id: root_entities_) {
163 update_hierarchy(root_id, delta_time);
169 for (
const EntityID root_id: root_entities_) {
170 update_world_matrices_recursive(root_id, glm::mat4(1.0f));
175 for (
const auto &[id, entity]: entities_) {
176 if (entity->get_name() == name)
182 void Scene::set_default_camera(
const EntityID camera_id) {
196 std::vector<EntityID> cameras;
197 for (
const auto &[id, entity]: entities_) {
198 if (entity->has_component<CameraComponent>()) {
199 cameras.push_back(id);
209 bool name_exists =
false;
210 for (
const auto &[id, entity]: entities_) {
211 if (entity->get_name() == base_name) {
219 name_counters_[base_name] = 0;
224 int &counter = name_counters_[base_name];
225 std::string unique_name;
229 unique_name = base_name +
" (" + std::to_string(counter) +
")";
233 for (
const auto &entity: entities_ | std::views::values) {
234 if (entity->get_name() == unique_name) {
239 }
while (name_exists);
255 for (EntityID child_id: get_children(entity_id)) {
256 update_hierarchy(child_id, delta_time);
267 <<
"' (ID: " << entity_id <<
") missing TransformComponent!\n";
273 transform->update_world_matrix(parent_world);
276 const glm::mat4 &this_world = transform->get_world_matrix();
277 for (EntityID child_id: get_children(entity_id)) {
278 update_world_matrices_recursive(child_id, this_world);
283 std::vector<EntityID> &results) {
287 if (predicate(entity)) {
288 results.push_back(entity_id);
291 for (EntityID child_id: get_children(entity_id)) {
292 find_entities_recursive(child_id, predicate, results);
const std::string & get_name() const
void update_scripts(float delta_time) const
Manages a collection of entities and their hierarchical relationships.
Entity * find_entity_by_name(const std::string &name)
Finds an entity by its name.
Scene(std::string name="Unnamed")
Constructs a new Scene with an optional name.
const Entity * get_entity(EntityID id) const
Retrieves an entity by its ID (const version)
virtual void initialize()
Initializes the scene Called once when the scene is first loaded or created.
void set_as_root(EntityID entity_id)
Makes an entity a root entity (removes parent)
virtual void update(float delta_time)
Updates all entities in the scene.
EntityID get_parent(EntityID entity_id) const
Gets the parent ID of an entity.
bool has_parent(EntityID entity_id) const
Checks if an entity has a parent.
EntityID default_camera_entity_id_
CameraComponent * get_default_camera() const
void set_parent(EntityID child_id, EntityID parent_id)
Sets the parent of an entity.
void update_world_matrices()
Updates world transformation matrices for all entities Propagates transformations through the entity ...
virtual ~Scene()
Destructor.
std::string generate_unique_name(const std::string &base_name)
Entity * get_entity(EntityID id)
Retrieves an entity by its ID.
void destroy_entity(EntityID id)
Destroys an entity and removes it from the scene.
std::vector< EntityID > get_children(EntityID parent_id) const
Gets all children of a parent entity.
std::vector< EntityID > get_camera_entities() const
void find_entities_recursive(EntityID entity_id, const std::function< bool(Entity *)> &predicate, std::vector< EntityID > &results)
bool is_descendant(EntityID potential_descendant, EntityID potential_ancestor)
Checks if one entity is a descendant of another.
void update_world_matrices_recursive(unsigned int entity_id, const glm::mat4 &parent_world)
void update_hierarchy(EntityID entity_id, float delta_time)
EntityID create_entity(const std::string &name="GameObject")
Creates a new entity in the scene.
void set_cubemap_faces(const std::array< std::string, 6 > &faces)