diff --git a/.idea/.idea.KhaoticEngineReborn/.idea/workspace.xml b/.idea/.idea.KhaoticEngineReborn/.idea/workspace.xml
index 6cf7b6f..c97c5e2 100644
--- a/.idea/.idea.KhaoticEngineReborn/.idea/workspace.xml
+++ b/.idea/.idea.KhaoticEngineReborn/.idea/workspace.xml
@@ -5,11 +5,17 @@
+
+
-
-
+
+
+
+
+
+
@@ -24,11 +30,13 @@
+
+
@@ -241,6 +249,10 @@
+
+
+
+
diff --git a/enginecustom/DemoScene_V12.9.0.ker b/enginecustom/DemoScene_V12.9.0.ker
new file mode 100644
index 0000000..5942868
--- /dev/null
+++ b/enginecustom/DemoScene_V12.9.0.ker
@@ -0,0 +1,8 @@
+Entity:0:86
+IdentityComponent:0:86:Unknown
+TransformComponent:0:50:0:0:-0:0:1:1:1
+RenderComponent:HasModel
+ShaderComponent:LIGHTING
+ModelPathComponent:Content/Assets/Kobject/86.obj
+TextureData:1:assets/Texture/Bricks2K.png:1:assets/Texture/BricksNRM2K.png:1:assets/Texture/BricksGLOSS2K.png:0
+EndEntity
diff --git a/enginecustom/enginecustom.vcxproj b/enginecustom/enginecustom.vcxproj
index d899b40..fe972bb 100644
--- a/enginecustom/enginecustom.vcxproj
+++ b/enginecustom/enginecustom.vcxproj
@@ -120,6 +120,7 @@
+
diff --git a/enginecustom/imgui.ini b/enginecustom/imgui.ini
index 6dbab2a..dac9d77 100644
--- a/enginecustom/imgui.ini
+++ b/enginecustom/imgui.ini
@@ -16,7 +16,7 @@ DockId=0x00000005,0
[Window][render Stats]
Pos=0,630
-Size=792,231
+Size=1584,231
Collapsed=0
DockId=0x00000009,0
@@ -27,14 +27,14 @@ Collapsed=0
DockId=0x0000000B,0
[Window][Terrain]
-Pos=236,19
+Pos=0,19
Size=266,842
Collapsed=0
DockId=0x00000007,0
[Window][Log Window]
-Pos=794,630
-Size=790,231
+Pos=0,630
+Size=1584,231
Collapsed=0
DockId=0x0000000A,0
@@ -42,11 +42,11 @@ DockId=0x0000000A,0
Pos=0,19
Size=234,609
Collapsed=0
-DockId=0x0000000B,1
+DockId=0x0000000B,0
[Window][Engine Settings]
-Pos=1267,631
-Size=317,230
+Pos=1267,462
+Size=317,166
Collapsed=0
DockId=0x00000006,0
diff --git a/enginecustom/src/inc/system/ecs/ComponentFactory.h b/enginecustom/src/inc/system/ecs/ComponentFactory.h
new file mode 100644
index 0000000..98f17d3
--- /dev/null
+++ b/enginecustom/src/inc/system/ecs/ComponentFactory.h
@@ -0,0 +1,54 @@
+// ComponentFactory.h
+#pragma once
+#include
+#include
+#include
+#include
+
+#include "entity.h"
+#include "component.h"
+#include "components/identity_component.h"
+#include "components/render_component.h"
+#include "components/transform_component.h"
+#include "components/physics_component.h"
+#include "components/shader_component.h"
+#include "components/model_path_component.h"
+
+class ComponentFactory {
+public:
+ static ComponentFactory& Get() {
+ static ComponentFactory instance;
+ return instance;
+ }
+
+ template
+ void EnregistrerComposant(const std::string& typeName) {
+ m_creators[typeName] = [](std::shared_ptr entity) -> std::shared_ptr {
+ return entity->AddComponent();
+ };
+ }
+
+ std::shared_ptr CreerComposant(const std::string& typeName,
+ std::shared_ptr entity) {
+ auto it = m_creators.find(typeName);
+ if (it != m_creators.end()) {
+ return it->second(entity);
+ }
+ return nullptr;
+ }
+
+private:
+ std::unordered_map(std::shared_ptr)>> m_creators;
+};
+
+// Fonction d'initialisation pour enregistrer tous les composants
+inline void EnregistrerTousLesComposants() {
+ auto& factory = ComponentFactory::Get();
+ factory.EnregistrerComposant("TransformComponent");
+ factory.EnregistrerComposant("PhysicsComponent");
+ factory.EnregistrerComposant("ShaderComponent");
+ factory.EnregistrerComposant("ModelPathComponent");
+ factory.EnregistrerComposant("IdentityComponent");
+ factory.EnregistrerComposant("RenderComponent");
+ // Ajouter d'autres composants ici
+}
diff --git a/enginecustom/src/inc/system/ecs/components/identity_component.h b/enginecustom/src/inc/system/ecs/components/identity_component.h
index 4bfc595..6b00b4a 100644
--- a/enginecustom/src/inc/system/ecs/components/identity_component.h
+++ b/enginecustom/src/inc/system/ecs/components/identity_component.h
@@ -1,4 +1,6 @@
#pragma once
+#include
+
#include "../component.h"
#include
@@ -94,13 +96,15 @@ public:
/**
* Serialize the component to a string.
- * Format: "id:name:type"
+ * Format: "IdentityComponent:id:name:type"
* @return A string representation of the component.
*/
- std::string Serialize() const override
- {
+ std::string Serialize() const override {
std::stringstream ss;
- ss << m_id << ":" << m_name << ":" << ObjectTypeToString(m_type);
+ ss << "IdentityComponent:"
+ << GetId() << ":"
+ << GetName() << ":"
+ << ObjectTypeToString(GetType());
return ss.str();
}
@@ -110,31 +114,24 @@ public:
* @param data The string data to deserialize from.
* @return True if deserialization was successful, otherwise false.
*/
- bool Deserialize(const std::string& data) override
- {
+ bool Deserialize(const std::string& data) override {
std::stringstream ss(data);
- std::string segment;
- std::vector segments;
-
- while (std::getline(ss, segment, ':'))
- {
- segments.push_back(segment);
- }
-
- if (segments.empty()) return false;
- if (segments.size() != 3) return false;
-
- try
- {
- m_id = std::stoi(segments[0]);
- m_name = segments[1];
- m_type = StringToObjectType(segments[2]);
- return true;
- } catch (const std::exception&)
- {
- return false;
- }
-
+ std::string type;
+ std::getline(ss, type, ':');
+
+ if (type != "IdentityComponent") return false;
+
+ std::string token, name, objectTypeStr;
+ int id;
+
+ std::getline(ss, token, ':'); id = std::stoi(token);
+ std::getline(ss, name, ':');
+ std::getline(ss, objectTypeStr);
+
+ SetId(id);
+ SetName(name);
+ SetType(StringToObjectType(objectTypeStr));
+ return true;
}
diff --git a/enginecustom/src/inc/system/ecs/components/model_path_component.h b/enginecustom/src/inc/system/ecs/components/model_path_component.h
index 44360dd..a6576c3 100644
--- a/enginecustom/src/inc/system/ecs/components/model_path_component.h
+++ b/enginecustom/src/inc/system/ecs/components/model_path_component.h
@@ -23,6 +23,37 @@ public:
* @param path The path to set as a std::wstring.
*/
void SetPath(const std::wstring& path) { m_path = path; }
+
+ std::string convert_w_string_to_string(const std::wstring& wstr) const
+ {
+ if (wstr.empty()) return std::string();
+
+ int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
+ std::string str(size_needed, 0);
+ WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &str[0], size_needed, NULL, NULL);
+ return str;
+ }
+
+ std::string Serialize() const override {
+ std::stringstream ss;
+ ss << "ModelPathComponent:"
+ << convert_w_string_to_string(m_path);
+ return ss.str();
+ }
+
+ bool Deserialize(const std::string& data) override {
+ std::stringstream ss(data);
+ std::string type;
+ std::getline(ss, type, ':');
+
+ if (type != "ModelPathComponent") return false;
+
+ std::string modelPath;
+ std::getline(ss, modelPath);
+
+ SetPath(std::wstring(modelPath.begin(), modelPath.end()));
+ return true;
+ }
private:
std::wstring m_path;
diff --git a/enginecustom/src/inc/system/ecs/components/physics_component.h b/enginecustom/src/inc/system/ecs/components/physics_component.h
index b840c6d..66e04db 100644
--- a/enginecustom/src/inc/system/ecs/components/physics_component.h
+++ b/enginecustom/src/inc/system/ecs/components/physics_component.h
@@ -195,6 +195,44 @@ public:
* @return The current position as an XMVECTOR.
*/
+ std::string Serialize() const override
+ {
+ std::stringstream ss;
+ ss << "PhysicsComponent:"
+ << GetMass() << ":"
+ << GetBoundingRadius() << ":"
+ << (IsPhysicsEnabled() ? "1" : "0") << ":"
+ << (IsGravityEnabled() ? "1" : "0") << ":"
+ << (IsGrounded() ? "1" : "0");
+ return ss.str();
+ }
+
+ bool Deserialize(const std::string& data) override
+ {
+ std::stringstream ss(data);
+ std::string type;
+ std::getline(ss, type, ':');
+
+ if (type != "PhysicsComponent") return false;
+
+ std::string token;
+ float mass, boundingRadius;
+ bool physicsEnabled, gravityEnabled, isGrounded;
+
+ std::getline(ss, token, ':'); mass = std::stof(token);
+ std::getline(ss, token, ':'); boundingRadius = std::stof(token);
+ std::getline(ss, token, ':'); physicsEnabled = (token == "1");
+ std::getline(ss, token, ':'); gravityEnabled = (token == "1");
+ std::getline(ss, token, ':'); isGrounded = (token == "1");
+
+ SetMass(mass);
+ SetBoundingRadius(boundingRadius);
+ SetPhysicsEnabled(physicsEnabled);
+ SetGravityEnabled(gravityEnabled);
+ SetGrounded(isGrounded);
+ return true;
+ }
+
private:
XMVECTOR m_Velocity;
XMVECTOR m_Acceleration;
diff --git a/enginecustom/src/inc/system/ecs/components/render_component.h b/enginecustom/src/inc/system/ecs/components/render_component.h
index dbb200b..220eb99 100644
--- a/enginecustom/src/inc/system/ecs/components/render_component.h
+++ b/enginecustom/src/inc/system/ecs/components/render_component.h
@@ -186,6 +186,28 @@ public:
}
}
+ std::string Serialize() const override {
+ if (!m_model) return "RenderComponent:NoModel";
+
+ std::stringstream ss;
+ ss << "RenderComponent:HasModel";
+ return ss.str();
+ }
+
+ bool Deserialize(const std::string& data) override {
+ std::stringstream ss(data);
+ std::string type;
+ std::getline(ss, type, ':');
+
+ if (type != "RenderComponent") return false;
+
+ std::string hasModel;
+ std::getline(ss, hasModel);
+
+ // Le modèle sera chargé séparément
+ return true;
+ }
+
private:
std::shared_ptr m_model;
std::string m_modelFilePath;
diff --git a/enginecustom/src/inc/system/ecs/components/shader_component.h b/enginecustom/src/inc/system/ecs/components/shader_component.h
index eb961f7..8443004 100644
--- a/enginecustom/src/inc/system/ecs/components/shader_component.h
+++ b/enginecustom/src/inc/system/ecs/components/shader_component.h
@@ -88,6 +88,28 @@ public:
}
}
+ std::string Serialize() const override
+ {
+ std::stringstream ss;
+ ss << "ShaderComponent:"
+ << ShaderTypeToString(GetActiveShader());
+ return ss.str();
+ }
+
+ bool Deserialize(const std::string& data) override {
+ std::stringstream ss(data);
+ std::string type;
+ std::getline(ss, type, ':');
+
+ if (type != "ShaderComponent") return false;
+
+ std::string shaderTypeStr;
+ std::getline(ss, shaderTypeStr);
+
+ SetActiveShader(StringToShaderType(shaderTypeStr));
+ return true;
+ }
+
private:
ShaderType m_activeShader;
};
diff --git a/enginecustom/src/inc/system/ecs/components/transform_component.h b/enginecustom/src/inc/system/ecs/components/transform_component.h
index d4bcf65..4634d1a 100644
--- a/enginecustom/src/inc/system/ecs/components/transform_component.h
+++ b/enginecustom/src/inc/system/ecs/components/transform_component.h
@@ -153,6 +153,50 @@ public:
*/
void SetTranslateMatrix(XMMATRIX matrix) { m_TranslateMatrix = matrix; UpdateWorldMatrix(); }
+ std::string Serialize() const override
+ {
+ XMFLOAT3 position, rotation, scale;
+ XMStoreFloat3(&position, GetPosition());
+ XMStoreFloat3(&rotation, GetRotation());
+ XMStoreFloat3(&scale, GetScale());
+
+ std::stringstream ss;
+ ss << "TransformComponent:"
+ << position.x << ":" << position.y << ":" << position.z << ":"
+ << rotation.x << ":" << rotation.y << ":" << rotation.z << ":"
+ << scale.x << ":" << scale.y << ":" << scale.z;
+ return ss.str();
+ }
+
+ bool Deserialize(const std::string& data) override
+ {
+ std::stringstream ss(data);
+ std::string type;
+ std::getline(ss, type, ':');
+
+ if (type != "TransformComponent") return false;
+
+ std::string token;
+ XMFLOAT3 position, rotation, scale;
+
+ std::getline(ss, token, ':'); position.x = std::stof(token);
+ std::getline(ss, token, ':'); position.y = std::stof(token);
+ std::getline(ss, token, ':'); position.z = std::stof(token);
+
+ std::getline(ss, token, ':'); rotation.x = std::stof(token);
+ std::getline(ss, token, ':'); rotation.y = std::stof(token);
+ std::getline(ss, token, ':'); rotation.z = std::stof(token);
+
+ std::getline(ss, token, ':'); scale.x = std::stof(token);
+ std::getline(ss, token, ':'); scale.y = std::stof(token);
+ std::getline(ss, token, ':'); scale.z = std::stof(token);
+
+ SetPosition(XMLoadFloat3(&position));
+ SetRotation(XMLoadFloat3(&rotation));
+ SetScale(XMLoadFloat3(&scale));
+ return true;
+ }
+
private:
XMMATRIX m_ScaleMatrix;
XMMATRIX m_RotateMatrix;
diff --git a/enginecustom/src/inc/system/scene_manager.h b/enginecustom/src/inc/system/scene_manager.h
index 0e04952..0d8e514 100644
--- a/enginecustom/src/inc/system/scene_manager.h
+++ b/enginecustom/src/inc/system/scene_manager.h
@@ -4,11 +4,18 @@
#include
#include "ecs/entity.h"
+#include "ecs/ComponentFactory.h"
class d_3d_class;
class object;
class application_class;
+static inline std::string trim(const std::string& s) {
+ size_t start = s.find_first_not_of(" \t\r\n");
+ size_t end = s.find_last_not_of(" \t\r\n");
+ return (start == std::string::npos) ? "" : s.substr(start, end - start + 1);
+}
+
class scene_manager
{
public:
diff --git a/enginecustom/src/src/system/scene_manager.cpp b/enginecustom/src/src/system/scene_manager.cpp
index 2356246..5d5ecc1 100644
--- a/enginecustom/src/src/system/scene_manager.cpp
+++ b/enginecustom/src/src/system/scene_manager.cpp
@@ -18,6 +18,18 @@ bool scene_manager::initialize(application_class* app)
}
app_ = app;
+
+ if (app_ == nullptr) {
+ Logger::Get().Log("Application pointer is null", __FILE__, __LINE__, Logger::LogLevel::Error);
+ return false;
+ }
+
+ direct_3d_ = app_->get_direct_3d();
+ if (!direct_3d_) {
+ Logger::Get().Log("Direct3D pointer is null", __FILE__, __LINE__, Logger::LogLevel::Error);
+ return false;
+ }
+
return true;
}
@@ -65,368 +77,264 @@ bool scene_manager::save_scene_as() {
}
bool scene_manager::load_scene() {
- Logger::Get().Log("Loading scene from " , __FILE__, __LINE__, Logger::LogLevel::Info);
- object_id_ = app_->get_object_id();
+ // Ouvrir une boîte de dialogue pour sélectionner un fichier .ker
+ OPENFILENAME ofn;
+ wchar_t szFile[260] = { 0 };
+ ZeroMemory(&ofn, sizeof(ofn));
+ ofn.lStructSize = sizeof(ofn);
+ ofn.hwndOwner = app_->get_hwnd();
+ ofn.lpstrFile = szFile;
+ ofn.nMaxFile = sizeof(szFile);
+ ofn.lpstrFilter = L"Ker Scene\0*.ker\0";
+ ofn.nFilterIndex = 1;
+ ofn.lpstrFileTitle = NULL;
+ ofn.nMaxFileTitle = 0;
+ ofn.lpstrInitialDir = NULL;
+ ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
+ ofn.lpstrDefExt = L"ker";
+ if (GetOpenFileName(&ofn) != TRUE) {
+ Logger::Get().Log("Load scene canceled or failed", __FILE__, __LINE__, Logger::LogLevel::Warning);
+ return false; // L'utilisateur a annulé la boîte de dialogue
+ }
+ std::filesystem::path filepath = ofn.lpstrFile;
+ scene_path_ = convert_w_string_to_string(filepath.wstring());
+ if (scene_path_.empty()) {
+ Logger::Get().Log("Invalid scene path", __FILE__, __LINE__, Logger::LogLevel::Error);
+ return false;
+ }
+ Logger::Get().Log("Loading scene from: " + scene_path_, __FILE__, __LINE__, Logger::LogLevel::Info);
+
+
w_folder_ = app_->get_w_folder();
- direct_3d_ = app_->get_direct_3d();
- std::wstring scenePath = get_scene_path();
+ std::filesystem::current_path(w_folder_);
+
- if (!scenePath.empty()) {
- scene_path_ = convert_w_string_to_string(scenePath);
- }
-
- std::ifstream inFile(scene_path_);
- if (!inFile.is_open()) {
- Logger::Get().Log("Failed to open file for loading scene: " + scene_path_, __FILE__, __LINE__, Logger::LogLevel::Error);
- return false;
- }
+ // S'assurer que les composants sont enregistrés
+ EnregistrerTousLesComposants();
- // Réinitialiser l'ID d'objet le plus élevé
- object_id_ = 0;
-
- // Récupérer l'EntityManager pour créer de nouvelles entités
- auto entity_manager = app_->get_entity_manager();
-
- // Supprimer toutes les entités existantes
- entity_manager->Clear();
-
- // Sauvegarder le répertoire de travail actuel
- std::wstring currentDirectory = w_folder_;
-
- std::string line;
- while (std::getline(inFile, line)) {
- std::istringstream iss(line);
- int id;
- std::string name;
- XMFLOAT3 position, rotation, scale;
- std::string modelPath;
- std::string shaderTypeStr;
- float boundingRadius;
- std::string objectTypeStr;
- float mass;
- bool physicsEnabled;
-
- // Lire les données de base de l'entité
- iss >> id >> name
- >> position.x >> position.y >> position.z
- >> rotation.x >> rotation.y >> rotation.z
- >> scale.x >> scale.y >> scale.z;
-
- // Lire le chemin du modèle - vérifier s'il est vide
- iss >> modelPath;
-
- // Si le chemin du modèle est vide ou commence par une lettre majuscule (probablement un type de shader),
- // c'est qu'il a été omis - utilisez une valeur par défaut
- if (modelPath.empty() || (modelPath[0] >= 'A' && modelPath[0] <= 'Z')) {
- // Reculer le curseur de lecture pour lire le type de shader à la place
- iss.seekg(-static_cast(modelPath.length()), std::ios::cur);
- modelPath = "assets/Model/TXT/cube.txt"; // Valeur par défaut
- }
-
- iss >> shaderTypeStr
- >> boundingRadius >> objectTypeStr
- >> mass >> physicsEnabled;
-
- if (iss.fail()) {
- Logger::Get().Log("Failed to parse entity data: " + line, __FILE__, __LINE__, Logger::LogLevel::Error);
- continue;
- }
-
- // Mettre à jour l'ID d'objet le plus élevé si nécessaire
- if (id >= object_id_) {
- object_id_ = id + 1;
- }
-
- // Convertir le chemin du modèle en wstring
- std::wstring wModelPath(modelPath.begin(), modelPath.end());
-
- // Vérifier si le chemin est relatif
- if (modelPath != "NoModel" && modelPath.length() > 1 && modelPath[1] != ':') {
- // C'est un chemin relatif, préfixer avec le répertoire de travail
- if (currentDirectory.back() != L'/' && currentDirectory.back() != L'\\') {
- // Ajouter un séparateur si nécessaire
- wModelPath = currentDirectory + L"\\" + wModelPath;
- } else {
- wModelPath = currentDirectory + wModelPath;
- }
- }
-
- // Créer le conteneur de textures pour stocker les chemins
- TextureContainer objectTextures;
-
- // Vider les conteneurs de chemins de textures
- objectTextures.diffusePaths.clear();
- objectTextures.normalPaths.clear();
- objectTextures.specularPaths.clear();
- objectTextures.alphaPaths.clear();
-
- // Lire les chemins des textures diffuses
- int diffuseTextureCount;
- iss >> diffuseTextureCount;
- for (int i = 0; i < diffuseTextureCount; i++) {
- std::string texturePath;
- iss >> texturePath;
- std::wstring wTexturePath(texturePath.begin(), texturePath.end());
- objectTextures.diffusePaths.push_back(wTexturePath);
- }
-
- // Lire les chemins des textures normales
- int normalTextureCount;
- iss >> normalTextureCount;
- for (int i = 0; i < normalTextureCount; i++) {
- std::string texturePath;
- iss >> texturePath;
- std::wstring wTexturePath(texturePath.begin(), texturePath.end());
- objectTextures.normalPaths.push_back(wTexturePath);
- }
-
- // Lire les chemins des textures spéculaires
- int specularTextureCount;
- iss >> specularTextureCount;
- for (int i = 0; i < specularTextureCount; i++) {
- std::string texturePath;
- iss >> texturePath;
- std::wstring wTexturePath(texturePath.begin(), texturePath.end());
- objectTextures.specularPaths.push_back(wTexturePath);
- }
-
- // Lire les chemins des textures alpha
- int alphaTextureCount;
- iss >> alphaTextureCount;
- for (int i = 0; i < alphaTextureCount; i++) {
- std::string texturePath;
- iss >> texturePath;
- std::wstring wTexturePath(texturePath.begin(), texturePath.end());
- objectTextures.alphaPaths.push_back(wTexturePath);
- }
-
- // Vérifier si on a un modèle à charger
- if (modelPath == "NoModel") {
- Logger::Get().Log("Skipping entity without model: " + name, __FILE__, __LINE__, Logger::LogLevel::Warning);
- continue;
- }
-
- // Récupérer le cache de modèles de l'application
- auto& modelCache = app_->get_model_cache();
- std::shared_ptr sharedModel;
-
- // Vérifier si le modèle existe déjà dans le cache
- std::string modelKey = modelPath;
- auto it = modelCache.find(modelKey);
- if (it != modelCache.end()) {
- // Utiliser le modèle existant du cache
- Logger::Get().Log("Using cached model for: " + modelKey, __FILE__, __LINE__, Logger::LogLevel::Info);
- sharedModel = it->second;
- } else {
- // Créer un nouveau modèle
- char modelFilename[256];
- size_t convertedChars = 0;
- wcstombs_s(&convertedChars, modelFilename, sizeof(modelFilename), wModelPath.c_str(), _TRUNCATE);
-
- Logger::Get().Log("Loading model: " + std::string(modelFilename), __FILE__, __LINE__, Logger::LogLevel::Info);
-
- // Créer et initialiser le modèle
- auto newModel = std::make_shared();
-
- // Précharger les textures
- if (!newModel->PreloadTextures(direct_3d_->get_device(), direct_3d_->get_device_context(), objectTextures)) {
- Logger::Get().Log("Failed to preload textures for: " + name, __FILE__, __LINE__, Logger::LogLevel::Error);
- continue;
- }
-
- if (!newModel->Initialize(direct_3d_->get_device(), direct_3d_->get_device_context(), modelFilename, objectTextures)) {
- Logger::Get().Log("Failed to initialize model: " + name, __FILE__, __LINE__, Logger::LogLevel::Error);
- continue;
- }
-
- // Ajouter le modèle au cache
- modelCache[modelKey] = newModel;
- sharedModel = newModel;
- }
-
- // Créer une nouvelle entité avec l'EntityManager
- auto entity = entity_manager->CreateEntity();
-
- // Ajouter un composant d'identité
- auto identityComponent = entity->AddComponent(id);
- identityComponent->SetName(name);
- identityComponent->SetType(ecs::IdentityComponent::StringToObjectType(objectTypeStr));
-
- // Ajouter un composant de transformation
- auto transformComponent = entity->AddComponent();
- transformComponent->SetPosition(XMLoadFloat3(&position));
- transformComponent->SetRotation(XMLoadFloat3(&rotation));
- transformComponent->SetScale(XMLoadFloat3(&scale));
- transformComponent->UpdateWorldMatrix();
-
- // Ajouter un composant de rendu avec le modèle
- auto renderComponent = entity->AddComponent();
- renderComponent->InitializeWithModel(sharedModel);
-
- // Ajouter un composant de shader
- auto shaderComponent = entity->AddComponent();
- shaderComponent->SetActiveShader(ecs::ShaderComponent::StringToShaderType(shaderTypeStr));
-
- // Ajouter un composant de chemin de modèle
- auto modelPathComponent = entity->AddComponent();
- modelPathComponent->SetPath(wModelPath);
-
- // Ajouter un composant de physique si nécessaire
- auto physicsComponent = entity->AddComponent();
- physicsComponent->Initialize();
- physicsComponent->SetMass(mass);
- physicsComponent->SetBoundingRadius(boundingRadius);
- physicsComponent->SetPhysicsEnabled(physicsEnabled);
-
- Logger::Get().Log("Entity loaded: " + name + " with ID: " + std::to_string(id), __FILE__, __LINE__, Logger::LogLevel::Info);
+ std::ifstream inFile(scene_path_);
+ if (!inFile.is_open()) {
+ Logger::Get().Log("Échec de l'ouverture du fichier", __FILE__, __LINE__, Logger::LogLevel::Error);
+ return false;
}
- // Mettre à jour l'ID global dans l'application
- app_->set_object_id(object_id_);
+ auto entity_manager = app_->get_entity_manager();
+ entity_manager->Clear();
+
+ std::string line;
+ std::shared_ptr currentEntity = nullptr;
+ TextureContainer currentTextures;
- // Mettre à jour les statistiques après le chargement
- app_->update_stats_after_modification();
-
- Logger::Get().Log("Scene loaded successfully from " + scene_path_, __FILE__, __LINE__, Logger::LogLevel::Info);
+ // Cache de modèle pour éviter de charger plusieurs fois le même modèle
+ auto& modelCache = app_->get_model_cache();
+
+ while (std::getline(inFile, line)) {
+ line = trim(line);
+
+ if (line.substr(0, 7) == "Entity:") {
+ // Format: Entity:id:name
+ std::stringstream ss(line.substr(7));
+ std::string idStr, name;
+ std::getline(ss, idStr, ':');
+ std::getline(ss, name);
+
+ int id = std::stoi(idStr);
+ currentEntity = entity_manager->CreateEntity();
+
+ // Ajouter IdentityComponent en premier
+ auto identity = currentEntity->AddComponent(id);
+ identity->SetName(name);
+
+ // Réinitialiser les données de texture pour cette entité
+ currentTextures = TextureContainer();
+ }
+ else if (line == "EndEntity") {
+ // Finaliser l'entité - chargement du modèle si nécessaire
+ if (currentEntity) {
+ auto modelPathComponent = currentEntity->GetComponent();
+ if (modelPathComponent && !modelPathComponent->GetPath().empty()) {
+ std::wstring modelPath = modelPathComponent->GetPath();
+ std::string modelKey = convert_w_string_to_string(modelPath);
+
+ // Vérifier si le modèle existe dans le cache
+ std::shared_ptr model;
+ auto it = modelCache.find(modelKey);
+ if (it != modelCache.end()) {
+ model = it->second;
+ } else {
+ // Créer et initialiser un nouveau modèle
+ model = std::make_shared();
+
+ // Précharger les textures
+ if (!model->PreloadTextures(direct_3d_->get_device(), direct_3d_->get_device_context(), currentTextures)) {
+ Logger::Get().Log("Échec du préchargement des textures", __FILE__, __LINE__, Logger::LogLevel::Error);
+ }
+
+ char modelFilename[256];
+ size_t convertedChars = 0;
+ wcstombs_s(&convertedChars, modelFilename, sizeof(modelFilename), modelPath.c_str(), _TRUNCATE);
+
+ if (!model->Initialize(direct_3d_->get_device(), direct_3d_->get_device_context(), modelFilename, currentTextures)) {
+ Logger::Get().Log("Échec d'initialisation du modèle", __FILE__, __LINE__, Logger::LogLevel::Error);
+ } else {
+ // Ajouter au cache
+ modelCache[modelKey] = model;
+ }
+ }
+
+ // Ajouter le composant de rendu avec le modèle
+ if (model) {
+ auto renderComponent = currentEntity->GetComponent();
+ if (!renderComponent) {
+ renderComponent = currentEntity->AddComponent();
+ }
+ renderComponent->InitializeWithModel(model);
+ }
+ }
+ }
+
+ currentEntity = nullptr;
+ }
+ else if (!line.empty() && line.find("TextureData:") == 0) {
+ Logger::Get().Log(line.substr(11), __FILE__, __LINE__, Logger::LogLevel::Info);
+ if (currentEntity) {
+ std::stringstream ss(line.substr(11));
+ std::string token;
+
+ // log the token values for debugging
+ Logger::Get().Log( token, __FILE__, __LINE__, Logger::LogLevel::Info);
+
+ std::getline(ss, token, ':');
+ // Diffuse
+ int diffuseCount = 0;
+ if (std::getline(ss, token, ':') && !token.empty())
+ diffuseCount = std::stoi(token);
+ for (int i = 0; i < diffuseCount; i++) {
+ if (std::getline(ss, token, ':'))
+ currentTextures.diffusePaths.push_back(std::wstring(token.begin(), token.end()));
+ }
+
+ // Normal
+ int normalCount = 0;
+ if (std::getline(ss, token, ':') && !token.empty())
+ normalCount = std::stoi(token);
+ for (int i = 0; i < normalCount; i++) {
+ if (std::getline(ss, token, ':'))
+ currentTextures.normalPaths.push_back(std::wstring(token.begin(), token.end()));
+ }
+
+ // Textures spéculaires
+ int specularCount = 0;
+ if (std::getline(ss, token, ':') && !token.empty())
+ specularCount = std::stoi(token);
+ for (int i = 0; i < specularCount; i++) {
+ if (std::getline(ss, token, ':'))
+ currentTextures.specularPaths.push_back(std::wstring(token.begin(), token.end()));
+ }
+
+ // Textures alpha
+ int alphaCount = 0;
+ if (std::getline(ss, token, ':') && !token.empty())
+ alphaCount = std::stoi(token);
+ for (int i = 0; i < alphaCount; i++) {
+ if (std::getline(ss, token, ':'))
+ currentTextures.alphaPaths.push_back(std::wstring(token.begin(), token.end()));
+ }
+ }
+ }
+ else if (currentEntity) {
+ // Déterminer le type de composant
+ std::string componentType = line.substr(0, line.find(':'));
+
+ // Créer le composant via la factory et le désérialiser
+ auto& factory = ComponentFactory::Get();
+ auto component = factory.CreerComposant(componentType, currentEntity);
+
+ if (component) {
+ component->Deserialize(line);
+ }
+ }
+ }
+
+ Logger::Get().Log("Scène chargée avec succès", __FILE__, __LINE__, Logger::LogLevel::Info);
return true;
}
-bool scene_manager::save_scene() {
+bool scene_manager::save_scene() {
entity_ = app_->get_entity_manager()->GetAllEntities();
-
- if (scene_path_.empty()) {
- // Si le chemin de la scène est vide, fallback vers la fonction de sauvegarde as
- if (!save_scene_as()) {
- Logger::Get().Log("Scene save cancelled by user", __FILE__, __LINE__, Logger::LogLevel::Info);
- return false;
- }
+
+ if (scene_path_.empty() && !save_scene_as()) {
+ return false;
}
std::ofstream outFile(scene_path_);
if (!outFile.is_open()) {
- Logger::Get().Log("Failed to open file for saving scene", __FILE__, __LINE__, Logger::LogLevel::Error);
+ Logger::Get().Log("Échec de l'ouverture du fichier", __FILE__, __LINE__, Logger::LogLevel::Error);
return false;
}
- outFile << entity_.size() << std::endl;
+ for (const auto& entity : entity_) {
+ // Récupérer l'ID de l'entité via IdentityComponent
+ auto identity = entity->GetComponent();
+ if (!identity) continue;
- for (const auto& entity : entity_)
- {
- const auto& components = entity->GetAllComponents();
+ // Écrire l'en-tête de l'entité
+ outFile << "Entity:" << identity->GetId() << ":" << identity->GetName() << std::endl;
- outFile << components.size() << std::endl;
-
- for (const auto& component : components)
- {
- outFile << typeid(*component).name() << std::endl;
- outFile << component->Serialize() << std::endl;
+ // Sérialiser tous les composants
+ for (const auto& [typeId, component] : entity->GetAllComponents()) {
+ std::string serializedData = component->Serialize();
+ if (!serializedData.empty()) {
+ outFile << serializedData << std::endl;
+ }
}
+
+ // Sérialiser les textures pour les composants de rendu
+ auto renderComponent = entity->GetComponent();
+ if (renderComponent && renderComponent->GetModel()) {
+ const auto& model = renderComponent->GetModel();
+ const auto& textureContainer = model->GetTextureContainer();
+
+ outFile << "TextureData:";
+
+ // Textures diffuses
+ const auto& diffusePaths = textureContainer.GetPaths(TextureType::Diffuse);
+ outFile << diffusePaths.size();
+ for (const auto& path : diffusePaths) {
+ outFile << ":" << convert_w_string_to_string(path);
+ }
+
+ // Textures normales
+ const auto& normalPaths = textureContainer.GetPaths(TextureType::Normal);
+ outFile << ":" << normalPaths.size();
+ for (const auto& path : normalPaths) {
+ outFile << ":" << convert_w_string_to_string(path);
+ }
+
+ // Textures spéculaires
+ const auto& specularPaths = textureContainer.GetPaths(TextureType::Specular);
+ outFile << ":" << specularPaths.size();
+ for (const auto& path : specularPaths) {
+ outFile << ":" << convert_w_string_to_string(path);
+ }
+
+ // Textures alpha
+ const auto& alphaPaths = textureContainer.GetPaths(TextureType::Alpha);
+ outFile << ":" << alphaPaths.size();
+ for (const auto& path : alphaPaths) {
+ outFile << ":" << convert_w_string_to_string(path);
+ }
+
+ outFile << std::endl;
+ }
+
+ outFile << "EndEntity" << std::endl;
}
- // for (const auto& object : entity_) {
- // XMFLOAT3 position, scale, rotation;
- // int id = 0;
- // int mass = 0;
- // float boundingRadius = 0;
- // std::string name = "NONE";
- // std::string shaderType = "NONE";
- // std::string objectType = "NONE";
- // std::wstring model_path = L"";
- // bool physics_enabled = false;
- //
- // auto transform = object->GetComponent();
- // if (transform) {
- // // convert XMVECTOR to XMFLOAT3
- // XMStoreFloat3(&position, transform->GetPosition());
- // XMStoreFloat3(&rotation, transform->GetRotation());
- // XMStoreFloat3(&scale, transform->GetScale());
- // }
- //
- //
- // auto identity = object->GetComponent();
- // if (identity) {
- //
- // id = identity->GetId();
- // name = identity->GetName();
- // objectType = identity->ObjectTypeToString(identity->GetType());
- //
- // }
- //
- // auto model_path_component = object->GetComponent();
- // if (model_path_component) {
- //
- // model_path = model_path_component->GetPath();
- // }
- //
- // auto shader = object->GetComponent();
- // if (shader)
- // {
- // shaderType = shader->ShaderTypeToString(shader->GetActiveShader());
- // }
- //
- // auto physics = object->GetComponent();
- // if (physics) {
- // physics_enabled = physics->IsPhysicsEnabled();
- // mass = physics->GetMass();
- // boundingRadius = physics->GetBoundingRadius();
- // }
- //
- // // Écrire les données de base de l'objet
- // outFile << id << " "
- // << name << " "
- // << position.x << " " << position.y << " " << position.z << " "
- // << rotation.x << " " << rotation.y << " " << rotation.z << " "
- // << scale.x << " " << scale.y << " " << scale.z << " "
- // << convert_w_string_to_string(model_path) << " "
- // << shaderType << " "
- // << boundingRadius << " "
- // << objectType << " "
- // << mass << " "
- // << physics_enabled;
- //
- // // Sauvegarder les chemins des textures_
- // // Format: nombre de textures_ diffuses, puis les chemins
- // // Même chose pour les autres types de textures_
- //
- //
- // auto render = object->GetComponent();
- // if (render)
- // {
- // const auto& model = render->GetModel();
- //
- // const auto& textureContainer = model->GetTextureContainer();
- //
- // const auto& diffusePaths = textureContainer.GetPaths(TextureType::Diffuse);
- // outFile << " " << diffusePaths.size();
- // for (const auto& path : diffusePaths) {
- // outFile << " " << convert_w_string_to_string(path);
- // }
- //
- // const auto& normalPaths = textureContainer.GetPaths(TextureType::Normal);
- // outFile << " " << normalPaths.size();
- // for (const auto& path : normalPaths) {
- // outFile << " " << convert_w_string_to_string(path);
- // }
- // const auto& specularPaths = textureContainer.GetPaths(TextureType::Specular);
- // outFile << " " << specularPaths.size();
- // for (const auto& path : specularPaths) {
- // outFile << " " << convert_w_string_to_string(path);
- // }
- // const auto& alphaPaths = textureContainer.GetPaths(TextureType::Alpha);
- // outFile << " " << alphaPaths.size();
- // for (const auto& path : alphaPaths) {
- // outFile << " " << convert_w_string_to_string(path);
- // }
- // }
- //
- //
- // outFile << std::endl;
- // }
-
outFile.close();
- Logger::Get().Log("Scene saved successfully to " + scene_path_, __FILE__, __LINE__, Logger::LogLevel::Info);
+ Logger::Get().Log("Scène sauvegardée avec succès: " + scene_path_, __FILE__, __LINE__, Logger::LogLevel::Info);
return true;
}