1#include "scene_manager.h"
2#include "application_class.h"
4scene_manager::scene_manager()
8scene_manager::~scene_manager()
16 Logger::Get().Log(
"Application pointer is null", __FILE__, __LINE__, Logger::LogLevel::Error);
24bool scene_manager::shutdown()
30bool scene_manager::save_scene_as() {
32 Logger::Get().Log(
"Saving scene as...", __FILE__, __LINE__, Logger::LogLevel::Info);
35 wchar_t szFile[260] = { 0 };
37 ZeroMemory(&ofn,
sizeof(ofn));
38 ofn.lStructSize =
sizeof(ofn);
40 ofn.lpstrFile = szFile;
41 ofn.nMaxFile =
sizeof(szFile);
42 ofn.lpstrFilter = L
"Ker Scene\0*.ker\0";
44 ofn.lpstrFileTitle = NULL;
45 ofn.nMaxFileTitle = 0;
46 ofn.lpstrInitialDir = NULL;
47 ofn.Flags = OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;
48 ofn.lpstrDefExt = L
"ker";
50 if (GetSaveFileName(&ofn) == TRUE) {
51 std::filesystem::path filepath = ofn.lpstrFile;
54 scene_path_ = convert_w_string_to_string(filepath.wstring());
60 Logger::Get().Log(
"Scene saved as: " + scene_path_, __FILE__, __LINE__, Logger::LogLevel::Info);
67bool scene_manager::load_scene() {
68 Logger::Get().Log(
"Loading scene from " , __FILE__, __LINE__, Logger::LogLevel::Info);
72 direct_3d_ = app_->get_direct_3d();
73 std::wstring scenePath = get_scene_path();
75 if (!scenePath.empty()) {
76 scene_path_ = convert_w_string_to_string(scenePath);
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);
92 entity_manager->
Clear();
95 std::wstring currentDirectory = w_folder_;
98 while (std::getline(inFile, line)) {
99 std::istringstream iss(line);
102 XMFLOAT3 position, rotation, scale;
103 std::string modelPath;
104 std::string shaderTypeStr;
105 float boundingRadius;
106 std::string objectTypeStr;
112 >> position.x >> position.y >> position.z
113 >> rotation.x >> rotation.y >> rotation.z
114 >> scale.x >> scale.y >> scale.z;
121 if (modelPath.empty() || (modelPath[0] >=
'A' && modelPath[0] <=
'Z')) {
123 iss.seekg(-
static_cast<int>(modelPath.length()), std::ios::cur);
124 modelPath =
"assets/Model/TXT/cube.txt";
128 >> boundingRadius >> objectTypeStr
129 >> mass >> physicsEnabled;
132 Logger::Get().Log(
"Failed to parse entity data: " + line, __FILE__, __LINE__, Logger::LogLevel::Error);
137 if (
id >= object_id_) {
142 std::wstring wModelPath(modelPath.begin(), modelPath.end());
145 if (modelPath !=
"NoModel" && modelPath.length() > 1 && modelPath[1] !=
':') {
147 if (currentDirectory.back() != L
'/' && currentDirectory.back() != L
'\\') {
149 wModelPath = currentDirectory + L
"\\" + wModelPath;
151 wModelPath = currentDirectory + wModelPath;
159 objectTextures.diffusePaths.clear();
160 objectTextures.normalPaths.clear();
161 objectTextures.specularPaths.clear();
162 objectTextures.alphaPaths.clear();
165 int diffuseTextureCount;
166 iss >> diffuseTextureCount;
167 for (
int i = 0; i < diffuseTextureCount; i++) {
168 std::string texturePath;
170 std::wstring wTexturePath(texturePath.begin(), texturePath.end());
171 objectTextures.diffusePaths.push_back(wTexturePath);
175 int normalTextureCount;
176 iss >> normalTextureCount;
177 for (
int i = 0; i < normalTextureCount; i++) {
178 std::string texturePath;
180 std::wstring wTexturePath(texturePath.begin(), texturePath.end());
181 objectTextures.normalPaths.push_back(wTexturePath);
185 int specularTextureCount;
186 iss >> specularTextureCount;
187 for (
int i = 0; i < specularTextureCount; i++) {
188 std::string texturePath;
190 std::wstring wTexturePath(texturePath.begin(), texturePath.end());
191 objectTextures.specularPaths.push_back(wTexturePath);
195 int alphaTextureCount;
196 iss >> alphaTextureCount;
197 for (
int i = 0; i < alphaTextureCount; i++) {
198 std::string texturePath;
200 std::wstring wTexturePath(texturePath.begin(), texturePath.end());
201 objectTextures.alphaPaths.push_back(wTexturePath);
205 if (modelPath ==
"NoModel") {
206 Logger::Get().Log(
"Skipping entity without model: " + name, __FILE__, __LINE__, Logger::LogLevel::Warning);
212 std::shared_ptr<model_class> sharedModel;
215 std::string modelKey = modelPath;
216 auto it = modelCache.find(modelKey);
217 if (it != modelCache.end()) {
219 Logger::Get().Log(
"Using cached model for: " + modelKey, __FILE__, __LINE__, Logger::LogLevel::Info);
220 sharedModel = it->second;
223 char modelFilename[256];
224 size_t convertedChars = 0;
225 wcstombs_s(&convertedChars, modelFilename,
sizeof(modelFilename), wModelPath.c_str(), _TRUNCATE);
227 Logger::Get().Log(
"Loading model: " + std::string(modelFilename), __FILE__, __LINE__, Logger::LogLevel::Info);
230 auto newModel = std::make_shared<model_class>();
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);
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);
244 modelCache[modelKey] = newModel;
245 sharedModel = newModel;
249 auto entity = entity_manager->CreateEntity();
253 identityComponent->
SetName(name);
258 transformComponent->
SetPosition(XMLoadFloat3(&position));
259 transformComponent->SetRotation(XMLoadFloat3(&rotation));
260 transformComponent->SetScale(XMLoadFloat3(&scale));
261 transformComponent->UpdateWorldMatrix();
273 modelPathComponent->
SetPath(wModelPath);
278 physicsComponent->SetMass(mass);
279 physicsComponent->SetBoundingRadius(boundingRadius);
280 physicsComponent->SetPhysicsEnabled(physicsEnabled);
282 Logger::Get().Log(
"Entity loaded: " + name +
" with ID: " + std::to_string(
id), __FILE__, __LINE__, Logger::LogLevel::Info);
291 Logger::Get().Log(
"Scene loaded successfully from " + scene_path_, __FILE__, __LINE__, Logger::LogLevel::Info);
295bool scene_manager::save_scene() {
299 if (scene_path_.empty()) {
300 Logger::Get().Log(
"Scene path is empty. Cannot save scene.", __FILE__, __LINE__, Logger::LogLevel::Error);
304 std::ofstream outFile(scene_path_);
305 if (!outFile.is_open()) {
306 Logger::Get().Log(
"Failed to open file for saving scene", __FILE__, __LINE__, Logger::LogLevel::Error);
310 for (
const auto&
object : entity_) {
311 XMFLOAT3 position, scale, rotation;
314 float boundingRadius = 0;
315 std::string name =
"NONE";
316 std::string shaderType =
"NONE";
317 std::string objectType =
"NONE";
318 std::wstring model_path = L
"";
319 bool physics_enabled =
false;
324 XMStoreFloat3(&position, transform->GetPosition());
325 XMStoreFloat3(&rotation, transform->GetRotation());
326 XMStoreFloat3(&scale, transform->GetScale());
333 id = identity->GetId();
334 name = identity->GetName();
335 objectType = identity->ObjectTypeToString(identity->GetType());
340 if (model_path_component) {
342 model_path = model_path_component->GetPath();
348 shaderType = shader->ShaderTypeToString(shader->GetActiveShader());
353 physics_enabled =
physics->IsPhysicsEnabled();
355 boundingRadius =
physics->GetBoundingRadius();
361 << position.x <<
" " << position.y <<
" " << position.z <<
" "
362 << rotation.x <<
" " << rotation.y <<
" " << rotation.z <<
" "
363 << scale.x <<
" " << scale.y <<
" " << scale.z <<
" "
364 << convert_w_string_to_string(model_path) <<
" "
366 << boundingRadius <<
" "
379 const auto& model = render->GetModel();
381 const auto& textureContainer = model->GetTextureContainer();
383 const auto& diffusePaths = textureContainer.GetPaths(TextureType::Diffuse);
384 outFile <<
" " << diffusePaths.size();
385 for (
const auto& path : diffusePaths) {
386 outFile <<
" " << convert_w_string_to_string(path);
389 const auto& normalPaths = textureContainer.GetPaths(TextureType::Normal);
390 outFile <<
" " << normalPaths.size();
391 for (
const auto& path : normalPaths) {
392 outFile <<
" " << convert_w_string_to_string(path);
394 const auto& specularPaths = textureContainer.GetPaths(TextureType::Specular);
395 outFile <<
" " << specularPaths.size();
396 for (
const auto& path : specularPaths) {
397 outFile <<
" " << convert_w_string_to_string(path);
399 const auto& alphaPaths = textureContainer.GetPaths(TextureType::Alpha);
400 outFile <<
" " << alphaPaths.size();
401 for (
const auto& path : alphaPaths) {
402 outFile <<
" " << convert_w_string_to_string(path);
407 outFile << std::endl;
411 Logger::Get().Log(
"Scene saved successfully to " + scene_path_, __FILE__, __LINE__, Logger::LogLevel::Info);
415std::wstring scene_manager::get_scene_path()
420 ZeroMemory(&ofn,
sizeof(ofn));
421 ofn.lStructSize =
sizeof(ofn);
423 ofn.lpstrFile = szFile;
424 ofn.lpstrFile[0] =
'\0';
425 ofn.nMaxFile =
sizeof(szFile);
426 ofn.lpstrFilter = L
"Ker Scene\0*.ker\0";
427 ofn.nFilterIndex = 1;
428 ofn.lpstrFileTitle = NULL;
429 ofn.nMaxFileTitle = 0;
430 ofn.lpstrInitialDir = NULL;
431 ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
433 if (GetOpenFileName(&ofn) == TRUE)
435 std::filesystem::path filepath = ofn.lpstrFile;
436 return filepath.wstring();
441std::string scene_manager::convert_w_string_to_string(
const std::wstring& wstr)
443 if (wstr.empty())
return std::string();
445 int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (
int)wstr.size(), NULL, 0, NULL, NULL);
446 std::string str(size_needed, 0);
447 WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (
int)wstr.size(), &str[0], size_needed, NULL, NULL);
std::filesystem::path get_w_folder() const
int get_object_id() const
std::map< std::string, std::shared_ptr< model_class > > & get_model_cache()
void update_stats_after_modification()
ecs::EntityManager * get_entity_manager() const
void set_object_id(int object_id)
std::vector< std::shared_ptr< Entity > > GetAllEntities()
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)