Loading...
Searching...
No Matches
ModelInstantiator.cpp
Go to the documentation of this file.
1//
2// Created by denzel on 08/12/2025.
3//
4
6
7#include "hellfire/ecs/RenderableComponent.h"
8#include "hellfire/ecs/TransformComponent.h"
9#include "hellfire/ecs/components/MeshComponent.h"
10#include "hellfire/serializers/ModelSerializer.h"
11
12namespace hellfire {
14 : assets_(assets)
15 , registry_(registry)
16 {}
17
18 EntityID ModelInstantiator::instantiate(Scene& scene, AssetID model_asset_id, EntityID parent) {
19 auto meta = registry_.get_asset(model_asset_id);
20 if (!meta) {
21 std::cerr << "ModelInstantiator: Asset not found: " << model_asset_id << std::endl;
22 return INVALID_ENTITY;
23 }
24
25 return instantiate(scene, registry_.get_absolute_path(model_asset_id), parent);
26 }
27
29 const std::filesystem::path& hfmodel_path,
30 EntityID parent) {
31 auto model_opt = ModelSerializer::load(hfmodel_path);
32 if (!model_opt) {
33 std::cerr << "ModelInstantiator: Failed to load model: " << hfmodel_path << std::endl;
34 return INVALID_ENTITY;
35 }
36
37 return instantiate(scene, *model_opt, parent);
38 }
39
41 const ImportResult& model,
42 EntityID parent) {
43 if (!model.success || model.nodes.empty()) {
44 std::cerr << "ModelInstantiator: Invalid model data" << std::endl;
45 return INVALID_ENTITY;
46 }
47
48 return instantiate_node(scene, model, model.root_node_index, parent);
49 }
50
52 const ImportResult& model,
53 size_t node_index,
54 EntityID parent) {
55 const auto& node = model.nodes[node_index];
56
57 // Create entity
58 EntityID entity_id = scene.create_entity(node.name);
59 Entity* entity = scene.get_entity(entity_id);
60
61 // Set transform
62 auto* transform = entity->get_component<TransformComponent>();
63 if (transform) {
64 transform->set_position(node.position);
65 transform->set_rotation(node.rotation);
66 transform->set_scale(node.scale);
67 }
68
69 // Set parent
70 if (parent != INVALID_ENTITY) {
71 scene.set_parent(entity_id, parent);
72 }
73
74 // Attach mesh components
75 if (node.mesh_indices.size() == 1) {
76 // Single mesh - attach directly to this entity
77 const auto& mesh_ref = model.meshes[node.mesh_indices[0]];
78 attach_mesh_components(entity, mesh_ref);
79 }
80 else if (node.mesh_indices.size() > 1) {
81 // Multiple meshes - create child entities for each
82 for (size_t mesh_idx : node.mesh_indices) {
83 const auto& mesh_ref = model.meshes[mesh_idx];
84
85 EntityID mesh_entity_id = scene.create_entity(mesh_ref.name);
86 Entity* mesh_entity = scene.get_entity(mesh_entity_id);
87 scene.set_parent(mesh_entity_id, entity_id);
88
89 attach_mesh_components(mesh_entity, mesh_ref);
90 }
91 }
92
93 // Recursively instantiate children
94 for (size_t child_idx : node.child_indices) {
95 instantiate_node(scene, model, child_idx, entity_id);
96 }
97
98 return entity_id;
99 }
100
102 // Add MeshComponent
103 auto* mesh_comp = entity->add_component<MeshComponent>();
104 mesh_comp->set_mesh_asset(mesh_ref.mesh_asset);
105
106 // Load actual mesh data
107 if (auto mesh = assets_.get_mesh(mesh_ref.mesh_asset)) {
108 mesh_comp->set_mesh(mesh);
109 }
110
111 // Add RenderableComponent with material
112 auto* renderable = entity->add_component<RenderableComponent>();
113 renderable->set_material_asset(mesh_ref.material_asset);
114
115 // Load actual material data
116 if (mesh_ref.material_asset != INVALID_ASSET_ID) {
117 if (auto material = assets_.get_material(mesh_ref.material_asset)) {
118 renderable->set_material(material);
119 }
120 }
121 }
122
123
124}
static constexpr hellfire::EntityID INVALID_ENTITY
Definition Scene.h:10
Registry for storing assets.
std::filesystem::path get_absolute_path(AssetID uuid)
Creates scene entities from an ImportResult.
EntityID instantiate(Scene &scene, const ImportResult &model, EntityID parent=INVALID_ENTITY)
ModelInstantiator(AssetManager &assets, AssetRegistry &registry)
EntityID instantiate(Scene &scene, const std::filesystem::path &hfmodel_path, EntityID parent=INVALID_ENTITY)
EntityID instantiate(Scene &scene, AssetID model_asset_id, EntityID parent=INVALID_ENTITY)
void attach_mesh_components(Entity *entity, const ImportedMesh &mesh_ref)
EntityID instantiate_node(Scene &scene, const ImportResult &model, size_t node_index, EntityID parent)
Serializes the ImportResult to a .hfmodel file.
static std::optional< ImportResult > load(const std::filesystem::path &filepath)
Manages a collection of entities and their hierarchical relationships.
Definition Scene.h:24
void set_parent(EntityID child_id, EntityID parent_id)
Sets the parent of an entity.
Definition Scene.cpp:105
Entity * get_entity(EntityID id)
Retrieves an entity by its ID.
Definition Scene.cpp:81
constexpr AssetID INVALID_ASSET_ID
Complete result of importing a model file.
Represents an imported mesh with its material binding.