5#include "../graphics/Skybox.h"
6#include "hellfire/ecs/CameraComponent.h"
10 environment_ = std::make_unique<SceneEnvironment>();
23 "assets/skyboxes/space_right.png",
24 "assets/skyboxes/space_left.png",
25 "assets/skyboxes/space_top.png",
26 "assets/skyboxes/space_bottom.png",
27 "assets/skyboxes/space_front.png",
28 "assets/skyboxes/space_back.png"
31 environment_->set_skybox(*skybox);
42 auto entity = std::make_unique<
Entity>(id, unique_name);
46 entities_[id] = std::move(entity);
47 root_entities_.push_back(id);
50 entities_[id]->initialize_scripts();
56 const auto it = entities_.find(id);
57 if (it == entities_.end())
return;
60 it->second->cleanup_scripts();
67 const std::vector<EntityID> children = get_children(id);
68 for (
const EntityID child_id: children) {
69 destroy_entity(child_id);
73 if (
const auto parent_it = parent_map_.find(id); parent_it != parent_map_.end()) {
74 const EntityID parent_id = parent_it->second;
75 auto &siblings = children_map_[parent_id];
76 std::erase(siblings, id);
77 parent_map_.erase(parent_it);
80 std::erase(root_entities_, id);
84 children_map_.erase(id);
91 const auto it = entities_.find(id);
92 return it != entities_.end() ? it->second.get() :
nullptr;
96 const auto it = entities_.find(id);
97 return it != entities_.end() ? it->second.get() :
nullptr;
101 if (potential_descendant == potential_ancestor)
return true;
104 const auto it = children_map_.find(potential_ancestor);
105 if (it == children_map_.end())
return false;
107 for (
const EntityID child: it->second) {
108 if (is_descendant(potential_descendant, child))
return true;
115 if (entities_.find(child_id) == entities_.end())
return;
116 if (parent_id != 0 && entities_.find(parent_id) == entities_.end())
return;
122 if (
auto it = parent_map_.find(child_id); it != parent_map_.end()) {
123 EntityID old_parent = it->second;
124 auto &siblings = children_map_[old_parent];
125 siblings.erase(std::remove(siblings.begin(), siblings.end(), child_id), siblings.end());
128 root_entities_.erase(std::remove(root_entities_.begin(), root_entities_.end(), child_id),
129 root_entities_.end());
133 if (parent_id != 0) {
134 parent_map_[child_id] = parent_id;
135 children_map_[parent_id].push_back(child_id);
138 parent_map_.erase(child_id);
139 root_entities_.push_back(child_id);
148 const auto it = parent_map_.find(entity_id);
149 return it != parent_map_.end() ? it->second : 0;
153 const auto it = parent_map_.find(entity_id);
154 return it != parent_map_.end();
158 const auto it = children_map_.find(parent_id);
159 return it != children_map_.end() ? it->second : std::vector<EntityID>{};
163 for (
const EntityID root_id: root_entities_) {
164 if (
const Entity *entity = get_entity(root_id)) {
165 entity->initialize_scripts();
171 for (
const EntityID root_id: root_entities_) {
172 update_hierarchy(root_id, delta_time);
178 for (
const EntityID root_id: root_entities_) {
179 update_world_matrices_recursive(root_id, glm::mat4(1.0f));
184 for (
const auto &[id, entity]: entities_) {
185 if (entity->get_name() == name)
191 void Scene::set_default_camera(
const EntityID camera_id) {
205 std::vector<EntityID> cameras;
206 for (
const auto &[id, entity]: entities_) {
207 if (entity->has_component<CameraComponent>()) {
208 cameras.push_back(id);
217 bool name_exists =
false;
218 for (
const auto &[id, entity]: entities_) {
219 if (entity->get_name() == base_name) {
227 name_counters_[base_name] = 0;
232 int &counter = name_counters_[base_name];
233 std::string unique_name;
237 unique_name = base_name +
" (" + std::to_string(counter) +
")";
241 for (
const auto &entity: entities_ | std::views::values) {
242 if (entity->get_name() == unique_name) {
247 }
while (name_exists);
263 for (EntityID child_id: get_children(entity_id)) {
264 update_hierarchy(child_id, delta_time);
275 <<
"' (ID: " << entity_id <<
") missing TransformComponent!\n";
281 transform->update_world_matrix(parent_world);
284 const glm::mat4 &this_world = transform->get_world_matrix();
285 for (EntityID child_id: get_children(entity_id)) {
286 update_world_matrices_recursive(child_id, this_world);
291 std::vector<EntityID> &results) {
295 if (predicate(entity)) {
296 results.push_back(entity_id);
299 for (EntityID child_id: get_children(entity_id)) {
300 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)