Khaotic Engine Reborn
Loading...
Searching...
No Matches
scene_manager Class Reference

Public Member Functions

bool initialize (application_class *app)
 
bool shutdown ()
 
bool save_scene_as ()
 
bool save_scene ()
 
bool load_scene ()
 
std::wstring get_scene_path ()
 
std::string convert_w_string_to_string (const std::wstring &w_str)
 

Detailed Description

Definition at line 12 of file scene_manager.h.

Constructor & Destructor Documentation

◆ scene_manager()

scene_manager::scene_manager ( )

Definition at line 4 of file scene_manager.cpp.

5{
6}

◆ ~scene_manager()

scene_manager::~scene_manager ( )

Definition at line 8 of file scene_manager.cpp.

9{
10 shutdown();
11}

Member Function Documentation

◆ convert_w_string_to_string()

std::string scene_manager::convert_w_string_to_string ( const std::wstring & w_str)

Convert a wide string to a standard string.

Parameters
w_str
Returns
The converted string.

Definition at line 444 of file scene_manager.cpp.

445{
446 if (wstr.empty()) return std::string();
447
448 int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
449 std::string str(size_needed, 0);
450 WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &str[0], size_needed, NULL, NULL);
451 return str;
452}

◆ get_scene_path()

std::wstring scene_manager::get_scene_path ( )

Get the current scene path.

Returns
The path to the current scene as a string.

Definition at line 418 of file scene_manager.cpp.

419{
420 OPENFILENAME ofn;
421 wchar_t szFile[260];
422
423 ZeroMemory(&ofn, sizeof(ofn));
424 ofn.lStructSize = sizeof(ofn);
425 ofn.hwndOwner = app_->get_hwnd();
426 ofn.lpstrFile = szFile;
427 ofn.lpstrFile[0] = '\0';
428 ofn.nMaxFile = sizeof(szFile);
429 ofn.lpstrFilter = L"Ker Scene\0*.ker\0";
430 ofn.nFilterIndex = 1;
431 ofn.lpstrFileTitle = NULL;
432 ofn.nMaxFileTitle = 0;
433 ofn.lpstrInitialDir = NULL;
434 ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
435
436 if (GetOpenFileName(&ofn) == TRUE)
437 {
438 std::filesystem::path filepath = ofn.lpstrFile;
439 return filepath.wstring();
440 }
441 return L"";
442}

◆ initialize()

bool scene_manager::initialize ( application_class * app)

Initialize the scene manager with the application instance.

Parameters
appPointer to the application class instance.
Returns
True if initialization is successful, otherwise false.

Definition at line 13 of file scene_manager.cpp.

14{
15 if (!app) {
16 Logger::Get().Log("Application pointer is null", __FILE__, __LINE__, Logger::LogLevel::Error);
17 return false;
18 }
19
20 app_ = app;
21 return true;
22}
static Logger & Get()
Definition Logger.h:20
void Log(const std::string &message, const std::string &fileName, int lineNumber, LogLevel level=LogLevel::Info)
Definition Logger.h:158

◆ load_scene()

bool scene_manager::load_scene ( )

Function to load a scene from a file. This function will prompt the user to choose a file to load.

Returns
True if the scene was loaded successfully, otherwise false.

Definition at line 67 of file scene_manager.cpp.

67 {
68 Logger::Get().Log("Loading scene from " , __FILE__, __LINE__, Logger::LogLevel::Info);
69
70 object_id_ = app_->get_object_id();
71 w_folder_ = app_->get_w_folder();
72 direct_3d_ = app_->get_direct_3d();
73 std::wstring scenePath = get_scene_path();
74
75 if (!scenePath.empty()) {
76 scene_path_ = convert_w_string_to_string(scenePath);
77 }
78
79 std::ifstream inFile(scene_path_);
80 if (!inFile.is_open()) {
81 Logger::Get().Log("Failed to open file for loading scene: " + scene_path_, __FILE__, __LINE__, Logger::LogLevel::Error);
82 return false;
83 }
84
85 // Réinitialiser l'ID d'objet le plus élevé
86 object_id_ = 0;
87
88 // Récupérer l'EntityManager pour créer de nouvelles entités
89 auto entity_manager = app_->get_entity_manager();
90
91 // Supprimer toutes les entités existantes
92 entity_manager->Clear();
93
94 // Sauvegarder le répertoire de travail actuel
95 std::wstring currentDirectory = w_folder_;
96
97 std::string line;
98 while (std::getline(inFile, line)) {
99 std::istringstream iss(line);
100 int id;
101 std::string name;
102 XMFLOAT3 position, rotation, scale;
103 std::string modelPath;
104 std::string shaderTypeStr;
105 float boundingRadius;
106 std::string objectTypeStr;
107 float mass;
108 bool physicsEnabled;
109
110 // Lire les données de base de l'entité
111 iss >> id >> name
112 >> position.x >> position.y >> position.z
113 >> rotation.x >> rotation.y >> rotation.z
114 >> scale.x >> scale.y >> scale.z;
115
116 // Lire le chemin du modèle - vérifier s'il est vide
117 iss >> modelPath;
118
119 // Si le chemin du modèle est vide ou commence par une lettre majuscule (probablement un type de shader),
120 // c'est qu'il a été omis - utilisez une valeur par défaut
121 if (modelPath.empty() || (modelPath[0] >= 'A' && modelPath[0] <= 'Z')) {
122 // Reculer le curseur de lecture pour lire le type de shader à la place
123 iss.seekg(-static_cast<int>(modelPath.length()), std::ios::cur);
124 modelPath = "assets/Model/TXT/cube.txt"; // Valeur par défaut
125 }
126
127 iss >> shaderTypeStr
128 >> boundingRadius >> objectTypeStr
129 >> mass >> physicsEnabled;
130
131 if (iss.fail()) {
132 Logger::Get().Log("Failed to parse entity data: " + line, __FILE__, __LINE__, Logger::LogLevel::Error);
133 continue;
134 }
135
136 // Mettre à jour l'ID d'objet le plus élevé si nécessaire
137 if (id >= object_id_) {
138 object_id_ = id + 1;
139 }
140
141 // Convertir le chemin du modèle en wstring
142 std::wstring wModelPath(modelPath.begin(), modelPath.end());
143
144 // Vérifier si le chemin est relatif
145 if (modelPath != "NoModel" && modelPath.length() > 1 && modelPath[1] != ':') {
146 // C'est un chemin relatif, préfixer avec le répertoire de travail
147 if (currentDirectory.back() != L'/' && currentDirectory.back() != L'\\') {
148 // Ajouter un séparateur si nécessaire
149 wModelPath = currentDirectory + L"\\" + wModelPath;
150 } else {
151 wModelPath = currentDirectory + wModelPath;
152 }
153 }
154
155 // Créer le conteneur de textures pour stocker les chemins
156 TextureContainer objectTextures;
157
158 // Vider les conteneurs de chemins de textures
159 objectTextures.diffusePaths.clear();
160 objectTextures.normalPaths.clear();
161 objectTextures.specularPaths.clear();
162 objectTextures.alphaPaths.clear();
163
164 // Lire les chemins des textures diffuses
165 int diffuseTextureCount;
166 iss >> diffuseTextureCount;
167 for (int i = 0; i < diffuseTextureCount; i++) {
168 std::string texturePath;
169 iss >> texturePath;
170 std::wstring wTexturePath(texturePath.begin(), texturePath.end());
171 objectTextures.diffusePaths.push_back(wTexturePath);
172 }
173
174 // Lire les chemins des textures normales
175 int normalTextureCount;
176 iss >> normalTextureCount;
177 for (int i = 0; i < normalTextureCount; i++) {
178 std::string texturePath;
179 iss >> texturePath;
180 std::wstring wTexturePath(texturePath.begin(), texturePath.end());
181 objectTextures.normalPaths.push_back(wTexturePath);
182 }
183
184 // Lire les chemins des textures spéculaires
185 int specularTextureCount;
186 iss >> specularTextureCount;
187 for (int i = 0; i < specularTextureCount; i++) {
188 std::string texturePath;
189 iss >> texturePath;
190 std::wstring wTexturePath(texturePath.begin(), texturePath.end());
191 objectTextures.specularPaths.push_back(wTexturePath);
192 }
193
194 // Lire les chemins des textures alpha
195 int alphaTextureCount;
196 iss >> alphaTextureCount;
197 for (int i = 0; i < alphaTextureCount; i++) {
198 std::string texturePath;
199 iss >> texturePath;
200 std::wstring wTexturePath(texturePath.begin(), texturePath.end());
201 objectTextures.alphaPaths.push_back(wTexturePath);
202 }
203
204 // Vérifier si on a un modèle à charger
205 if (modelPath == "NoModel") {
206 Logger::Get().Log("Skipping entity without model: " + name, __FILE__, __LINE__, Logger::LogLevel::Warning);
207 continue;
208 }
209
210 // Récupérer le cache de modèles de l'application
211 auto& modelCache = app_->get_model_cache();
212 std::shared_ptr<model_class> sharedModel;
213
214 // Vérifier si le modèle existe déjà dans le cache
215 std::string modelKey = modelPath;
216 auto it = modelCache.find(modelKey);
217 if (it != modelCache.end()) {
218 // Utiliser le modèle existant du cache
219 Logger::Get().Log("Using cached model for: " + modelKey, __FILE__, __LINE__, Logger::LogLevel::Info);
220 sharedModel = it->second;
221 } else {
222 // Créer un nouveau modèle
223 char modelFilename[256];
224 size_t convertedChars = 0;
225 wcstombs_s(&convertedChars, modelFilename, sizeof(modelFilename), wModelPath.c_str(), _TRUNCATE);
226
227 Logger::Get().Log("Loading model: " + std::string(modelFilename), __FILE__, __LINE__, Logger::LogLevel::Info);
228
229 // Créer et initialiser le modèle
230 auto newModel = std::make_shared<model_class>();
231
232 // Précharger les textures
233 if (!newModel->PreloadTextures(direct_3d_->get_device(), direct_3d_->get_device_context(), objectTextures)) {
234 Logger::Get().Log("Failed to preload textures for: " + name, __FILE__, __LINE__, Logger::LogLevel::Error);
235 continue;
236 }
237
238 if (!newModel->Initialize(direct_3d_->get_device(), direct_3d_->get_device_context(), modelFilename, objectTextures)) {
239 Logger::Get().Log("Failed to initialize model: " + name, __FILE__, __LINE__, Logger::LogLevel::Error);
240 continue;
241 }
242
243 // Ajouter le modèle au cache
244 modelCache[modelKey] = newModel;
245 sharedModel = newModel;
246 }
247
248 // Créer une nouvelle entité avec l'EntityManager
249 auto entity = entity_manager->CreateEntity();
250
251 // Ajouter un composant d'identité
252 auto identityComponent = entity->AddComponent<ecs::IdentityComponent>(id);
253 identityComponent->SetName(name);
254 identityComponent->SetType(ecs::IdentityComponent::StringToObjectType(objectTypeStr));
255
256 // Ajouter un composant de transformation
257 auto transformComponent = entity->AddComponent<ecs::TransformComponent>();
258 transformComponent->SetPosition(XMLoadFloat3(&position));
259 transformComponent->SetRotation(XMLoadFloat3(&rotation));
260 transformComponent->SetScale(XMLoadFloat3(&scale));
261 transformComponent->UpdateWorldMatrix();
262
263 // Ajouter un composant de rendu avec le modèle
264 auto renderComponent = entity->AddComponent<ecs::RenderComponent>();
265 renderComponent->InitializeWithModel(sharedModel);
266
267 // Ajouter un composant de shader
268 auto shaderComponent = entity->AddComponent<ecs::ShaderComponent>();
269 shaderComponent->SetActiveShader(ecs::ShaderComponent::StringToShaderType(shaderTypeStr));
270
271 // Ajouter un composant de chemin de modèle
272 auto modelPathComponent = entity->AddComponent<ecs::ModelPathComponent>();
273 modelPathComponent->SetPath(wModelPath);
274
275 // Ajouter un composant de physique si nécessaire
276 auto physicsComponent = entity->AddComponent<ecs::PhysicsComponent>();
277 physicsComponent->Initialize();
278 physicsComponent->SetMass(mass);
279 physicsComponent->SetBoundingRadius(boundingRadius);
280 physicsComponent->SetPhysicsEnabled(physicsEnabled);
281
282 Logger::Get().Log("Entity loaded: " + name + " with ID: " + std::to_string(id), __FILE__, __LINE__, Logger::LogLevel::Info);
283 }
284
285 // Mettre à jour l'ID global dans l'application
286 app_->set_object_id(object_id_);
287
288 // Mettre à jour les statistiques après le chargement
290
291 Logger::Get().Log("Scene loaded successfully from " + scene_path_, __FILE__, __LINE__, Logger::LogLevel::Info);
292 return true;
293}
std::filesystem::path get_w_folder() const
std::map< std::string, std::shared_ptr< model_class > > & get_model_cache()
ecs::EntityManager * get_entity_manager() const
void set_object_id(int object_id)
ID3D11Device * get_device()
Gets the Direct3D device.
ID3D11DeviceContext * get_device_context()
Gets the Direct3D device context.
static ObjectType StringToObjectType(const std::string &str)
void SetName(const std::string &name)
void SetPath(const std::wstring &path)
void Initialize() override
bool InitializeWithModel(std::shared_ptr< model_class > model)
void SetActiveShader(ShaderType shader)
static ShaderType StringToShaderType(const std::string &str)
void SetPosition(XMVECTOR position)
std::string convert_w_string_to_string(const std::wstring &w_str)
std::wstring get_scene_path()

◆ save_scene()

bool scene_manager::save_scene ( )

Function to save the current scene. This function will save the current scene to the path specified in scene_path_. If the scene_path_ is empty, it will call save_scene_as() to prompt the user for a file location.

Returns
True if the scene was saved successfully, otherwise false.

Definition at line 295 of file scene_manager.cpp.

295 {
296
297 entity_ = app_->get_entity_manager()->GetAllEntities();
298
299 if (scene_path_.empty()) {
300 // Si le chemin de la scène est vide, fallback vers la fonction de sauvegarde as
301 if (!save_scene_as()) {
302 Logger::Get().Log("Scene save cancelled by user", __FILE__, __LINE__, Logger::LogLevel::Info);
303 return false;
304 }
305 }
306
307 std::ofstream outFile(scene_path_);
308 if (!outFile.is_open()) {
309 Logger::Get().Log("Failed to open file for saving scene", __FILE__, __LINE__, Logger::LogLevel::Error);
310 return false;
311 }
312
313 for (const auto& object : entity_) {
314 XMFLOAT3 position, scale, rotation;
315 int id = 0;
316 int mass = 0;
317 float boundingRadius = 0;
318 std::string name = "NONE";
319 std::string shaderType = "NONE";
320 std::string objectType = "NONE";
321 std::wstring model_path = L"";
322 bool physics_enabled = false;
323
324 auto transform = object->GetComponent<ecs::TransformComponent>();
325 if (transform) {
326 // convert XMVECTOR to XMFLOAT3
327 XMStoreFloat3(&position, transform->GetPosition());
328 XMStoreFloat3(&rotation, transform->GetRotation());
329 XMStoreFloat3(&scale, transform->GetScale());
330 }
331
332
333 auto identity = object->GetComponent<ecs::IdentityComponent>();
334 if (identity) {
335
336 id = identity->GetId();
337 name = identity->GetName();
338 objectType = identity->ObjectTypeToString(identity->GetType());
339
340 }
341
342 auto model_path_component = object->GetComponent<ecs::ModelPathComponent>();
343 if (model_path_component) {
344
345 model_path = model_path_component->GetPath();
346 }
347
348 auto shader = object->GetComponent<ecs::ShaderComponent>();
349 if (shader)
350 {
351 shaderType = shader->ShaderTypeToString(shader->GetActiveShader());
352 }
353
354 auto physics = object->GetComponent<ecs::PhysicsComponent>();
355 if (physics) {
356 physics_enabled = physics->IsPhysicsEnabled();
357 mass = physics->GetMass();
358 boundingRadius = physics->GetBoundingRadius();
359 }
360
361 // Écrire les données de base de l'objet
362 outFile << id << " "
363 << name << " "
364 << position.x << " " << position.y << " " << position.z << " "
365 << rotation.x << " " << rotation.y << " " << rotation.z << " "
366 << scale.x << " " << scale.y << " " << scale.z << " "
367 << convert_w_string_to_string(model_path) << " "
368 << shaderType << " "
369 << boundingRadius << " "
370 << objectType << " "
371 << mass << " "
372 << physics_enabled;
373
374 // Sauvegarder les chemins des textures_
375 // Format: nombre de textures_ diffuses, puis les chemins
376 // Même chose pour les autres types de textures_
377
378
379 auto render = object->GetComponent<ecs::RenderComponent>();
380 if (render)
381 {
382 const auto& model = render->GetModel();
383
384 const auto& textureContainer = model->GetTextureContainer();
385
386 const auto& diffusePaths = textureContainer.GetPaths(TextureType::Diffuse);
387 outFile << " " << diffusePaths.size();
388 for (const auto& path : diffusePaths) {
389 outFile << " " << convert_w_string_to_string(path);
390 }
391
392 const auto& normalPaths = textureContainer.GetPaths(TextureType::Normal);
393 outFile << " " << normalPaths.size();
394 for (const auto& path : normalPaths) {
395 outFile << " " << convert_w_string_to_string(path);
396 }
397 const auto& specularPaths = textureContainer.GetPaths(TextureType::Specular);
398 outFile << " " << specularPaths.size();
399 for (const auto& path : specularPaths) {
400 outFile << " " << convert_w_string_to_string(path);
401 }
402 const auto& alphaPaths = textureContainer.GetPaths(TextureType::Alpha);
403 outFile << " " << alphaPaths.size();
404 for (const auto& path : alphaPaths) {
405 outFile << " " << convert_w_string_to_string(path);
406 }
407 }
408
409
410 outFile << std::endl;
411 }
412
413 outFile.close();
414 Logger::Get().Log("Scene saved successfully to " + scene_path_, __FILE__, __LINE__, Logger::LogLevel::Info);
415 return true;
416}
std::vector< std::shared_ptr< Entity > > GetAllEntities()

◆ save_scene_as()

bool scene_manager::save_scene_as ( )

Function to save the current scene as a new file. The scene is saved in a .ker file format. This function will prompt the user to choose a file location and name. Then it will call the save_scene function to perform the actual saving.

Returns

Definition at line 30 of file scene_manager.cpp.

30 {
31
32 Logger::Get().Log("Saving scene as...", __FILE__, __LINE__, Logger::LogLevel::Info);
33
34 OPENFILENAME ofn;
35 wchar_t szFile[260] = { 0 };
36
37 ZeroMemory(&ofn, sizeof(ofn));
38 ofn.lStructSize = sizeof(ofn);
39 ofn.hwndOwner = app_->get_hwnd();
40 ofn.lpstrFile = szFile;
41 ofn.nMaxFile = sizeof(szFile);
42 ofn.lpstrFilter = L"Ker Scene\0*.ker\0";
43 ofn.nFilterIndex = 1;
44 ofn.lpstrFileTitle = NULL;
45 ofn.nMaxFileTitle = 0;
46 ofn.lpstrInitialDir = NULL;
47 ofn.Flags = OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;
48 ofn.lpstrDefExt = L"ker";
49
50 if (GetSaveFileName(&ofn) == TRUE) {
51 std::filesystem::path filepath = ofn.lpstrFile;
52
53 // Mettre à jour le chemin de scène
54 scene_path_ = convert_w_string_to_string(filepath.wstring());
55 //object_vec_ = app_->get_kobjects(); // TODO
56
57 // Sauvegarder la scène avec le nouveau chemin
58 save_scene();
59
60 Logger::Get().Log("Scene saved as: " + scene_path_, __FILE__, __LINE__, Logger::LogLevel::Info);
61 return false;
62 }
63
64 return true;
65}

◆ shutdown()

bool scene_manager::shutdown ( )

Shutdown the scene manager and release resources.

Returns
True if shutdown is successful, otherwise false.

Definition at line 24 of file scene_manager.cpp.

25{
26 app_ = nullptr;
27 return true;
28}

The documentation for this class was generated from the following files: