Major Update - V9.0.0

[FEAT] :

+ Add Save and Load system for scene but only for kobject
This commit is contained in:
2025-03-18 22:43:23 +01:00
parent 6583f74a5f
commit eea7b4c067
10 changed files with 240 additions and 55 deletions

View File

@@ -93,7 +93,7 @@ public:
std::vector<Object*> GetCubes() const { return m_cubes; };
std::vector<Object*> GetTerrainCubes() const { return m_terrainChunk; };
std::vector<Object*> GetKobjects() const { return m_object; };
void AddKobject(WCHAR* filepath);
void AddKobject(std::wstring& filepath);
void SetPath(WCHAR* path) { m_path = path; };
void SetWFolder(std::filesystem::path WFolder) { m_WFolder = WFolder; };
@@ -152,6 +152,9 @@ public:
void LoadScene();
void SetScenePath(std::string path) { m_scenePath = path; };
std::wstring GetScenePath();
std::string ConvertWStringToString(const std::wstring& wstr);
private:
bool Render(float, float, float, float, float);
@@ -167,6 +170,7 @@ private:
void ConstructSkybox(); // Construct the skybox
void UpdateSkyboxPosition(); // Update the skybox position
bool RenderSkybox(XMMATRIX view, XMMATRIX projection); // Render the skybox
public :
std::vector<ID3D11ShaderResourceView*> textures;

View File

@@ -86,6 +86,9 @@ public:
float GetBoundingRadius() const;
void SetModelPath(std::wstring& path) { m_modelPath = path; }
std::wstring& GetModelPath() { return m_modelPath; }
public :
bool m_demoSpinning = false;
XMVECTOR m_previousPosition;
@@ -110,4 +113,5 @@ private:
ShaderType m_activeShader = LIGHTING;
float m_boundingRadius;
std::wstring m_modelPath;
};

View File

@@ -149,11 +149,68 @@ void SystemClass::Run()
done = false;
// Ask For the scene file
GetScenePath();
m_Application->LoadScene();
// Ask if the user wants to load a scene or create a new one
int result_scene = MessageBox(NULL, L"Do you want to load a saved scene?", L"Load Scene", MB_YESNO | MB_ICONQUESTION);
if (result_scene == IDYES)
{
std::wstring scenePath = m_Application->GetScenePath();
if (!scenePath.empty())
{
m_Application->SetScenePath(m_Application->ConvertWStringToString(scenePath));
m_Application->LoadScene();
}
}
else
{
OPENFILENAME ofn;
wchar_t szFile[260] = L"";
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = m_hwnd;
ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof(szFile);
// Allow multiple extensions
ofn.lpstrFilter = L"Ker Scene (*.ker)\0*.ker\0All Files (*.*)\0*.*\0";
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;
if (GetSaveFileName(&ofn) == TRUE)
{
std::filesystem::path filepath = ofn.lpstrFile;
std::string path = filepath.string();
// Add the selected extension if not already present
switch (ofn.nFilterIndex)
{
case 1:
if (filepath.extension() != L".ker")
path += ".ker";
break;
case 2:
if (filepath.extension() != L".txt")
path += ".txt";
break;
}
m_Application->SetScenePath(path);
// Create a new scene file
std::ofstream outFile(path);
if (outFile.is_open())
{
// Initialize the new scene file with default content if needed
outFile.close();
Logger::Get().Log("New scene file created successfully", __FILE__, __LINE__, Logger::LogLevel::Info);
}
else
{
Logger::Get().Log("Failed to create new scene file", __FILE__, __LINE__, Logger::LogLevel::Error);
}
}
}
while (!done)
{
// Handle the windows messages.
@@ -305,7 +362,7 @@ LRESULT CALLBACK SystemClass::MessageHandler(HWND hwnd, UINT umsg, WPARAM wparam
if (extension == L"txt" || extension == L"kobj") {
// Handle dropped files with valid extensions
std::wcout << L"File dropped: " << filePath << std::endl;
m_Application->AddKobject(filePath);
m_Application->AddKobject(fileName);
}
else {
// Handle files with invalid extensions (optional)

View File

@@ -1429,9 +1429,8 @@ void ApplicationClass::GenerateTerrain()
}
void ApplicationClass::AddKobject(WCHAR* filepath)
void ApplicationClass::AddKobject(std::wstring& filepath)
{
Logger::Get().Log("Adding object", __FILE__, __LINE__);
char modelFilename[128];
@@ -1442,7 +1441,7 @@ void ApplicationClass::AddKobject(WCHAR* filepath)
string filename = p.stem().string();
size_t convertedChars = 0;
wcstombs_s(&convertedChars, modelFilename, sizeof(modelFilename), filepath, _TRUNCATE);
wcstombs_s(&convertedChars, modelFilename, sizeof(modelFilename), filepath.c_str(), _TRUNCATE);
filesystem::current_path(m_WFolder);
@@ -1460,23 +1459,7 @@ void ApplicationClass::AddKobject(WCHAR* filepath)
result = DirectX::CreateWICTextureFromFile(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), textureFilename.c_str(), nullptr, &texture);
if (FAILED(result))
{
// Utiliser _com_error pour obtenir des informations d<>taill<6C>es sur l'erreur
_com_error err(result);
LPCTSTR errMsg = err.ErrorMessage();
//convertie errMessage en std::wstring
std::wstring ws(errMsg);
std::string str(ws.begin(), ws.end());
// Log the current working directory
std::filesystem::path cwd = std::filesystem::current_path();
Logger::Get().Log("Current working directory: " + cwd.string(), __FILE__, __LINE__, Logger::LogLevel::Error);
Logger::Get().Log("Failed to load texture: " + std::string(textureFilename.begin(), textureFilename.end()) +
"\nError: " + std::to_string(result) +
"\nDescription: " + str,
__FILE__, __LINE__, Logger::LogLevel::Error);
return; // Assurez-vous de retourner false ou de g<>rer l'erreur de mani<6E>re appropri<72>e
// Handle error
}
textures.push_back(texture);
}
@@ -1487,12 +1470,12 @@ void ApplicationClass::AddKobject(WCHAR* filepath)
newObject->SetTranslateMatrix(XMMatrixTranslation(0.0f, 50.0f, 0.0f));
newObject->SetName(filename);
newObject->SetId(m_ObjectId);
newObject->SetModelPath(filepath); // Store the path as std::wstring
m_ObjectId++;
m_object.push_back(newObject);
// V<>rifiez que l'objet a bien re<72>u les textures
if (newObject->GetTexture(0) == nullptr)
{
@@ -2245,18 +2228,117 @@ bool ApplicationClass::RenderSkybox(XMMATRIX view, XMMATRIX projection) {
return true;
}
std::string ApplicationClass::ConvertWStringToString(const std::wstring& wstr)
{
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;
}
void ApplicationClass::SaveScene()
{
if (m_scenePath.empty())
{
Logger::Get().Log("Scene path is empty. Cannot save scene.", __FILE__, __LINE__, Logger::LogLevel::Error);
return;
}
std::ofstream outFile(m_scenePath);
if (!outFile.is_open())
{
Logger::Get().Log("Failed to open file for saving scene", __FILE__, __LINE__, Logger::LogLevel::Error);
return;
}
for (const auto& object : m_object)
{
XMFLOAT3 position, scale;
XMStoreFloat3(&position, object->GetPosition());
XMStoreFloat3(&scale, object->GetScale());
outFile << object->GetId() << " " << object->GetName() << " "
<< position.x << " " << position.y << " " << position.z << " "
<< scale.x << " " << scale.y << " " << scale.z << " "
<< ConvertWStringToString(object->GetModelPath()) << std::endl; // Convert model path to std::string
}
outFile.close();
Logger::Get().Log("Scene saved successfully", __FILE__, __LINE__, Logger::LogLevel::Info);
}
void ApplicationClass::LoadScene()
{
// Read the file and load the scene
// File is in a custom format
// every object is defined by a line with the following format:
// m_id,m_scaleMatrix,m_rotateMatrix,m_translateMatrix,m_srMatrix,
// m_worldMatrix,m_mass,m_isPhysicsEnabled,m_name,m_type,m_activeShader,
// m_boundingRadius,m_texture[n],m_demoSpinning
std::wstring scenePath = GetScenePath();
if (!scenePath.empty())
{
SetScenePath(ConvertWStringToString(scenePath));
}
if (m_scenePath.empty())
{
Logger::Get().Log("Scene path is empty. Cannot load scene.", __FILE__, __LINE__, Logger::LogLevel::Error);
return;
}
std::ifstream inFile(m_scenePath);
if (!inFile.is_open())
{
Logger::Get().Log("Failed to open file for loading scene", __FILE__, __LINE__, Logger::LogLevel::Error);
return;
}
m_object.clear();
int id;
std::string name;
float posX, posY, posZ;
float scaleX, scaleY, scaleZ;
std::string modelPath;
while (inFile >> id >> name >> posX >> posY >> posZ >> scaleX >> scaleY >> scaleZ >> modelPath)
{
int size_needed = MultiByteToWideChar(CP_UTF8, 0, modelPath.c_str(), (int)modelPath.size(), NULL, 0);
std::wstring wModelPath(size_needed, 0);
MultiByteToWideChar(CP_UTF8, 0, modelPath.c_str(), (int)modelPath.size(), &wModelPath[0], size_needed);
AddKobject(wModelPath);
Object* newObject = m_object.back();
newObject->SetId(id);
newObject->SetName(name);
newObject->SetPosition(XMVectorSet(posX, posY, posZ, 0.0f));
newObject->SetScale(XMVectorSet(scaleX, scaleY, scaleZ, 0.0f));
}
inFile.close();
Logger::Get().Log("Scene loaded successfully", __FILE__, __LINE__, Logger::LogLevel::Info);
}
std::wstring ApplicationClass::GetScenePath()
{
OPENFILENAME ofn;
wchar_t szFile[260];
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = m_hwnd;
ofn.lpstrFile = szFile;
ofn.lpstrFile[0] = '\0';
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;
if (GetOpenFileName(&ofn) == TRUE)
{
std::filesystem::path filepath = ofn.lpstrFile;
return filepath.wstring();
}
return L"";
}

View File

@@ -171,7 +171,8 @@ void imguiManager::WidgetAddObject(ApplicationClass* app)
if (GetOpenFileName(&ofn))
{
app->AddKobject(ofn.lpstrFile);
std::wstring wstr(ofn.lpstrFile);
app->AddKobject(wstr);
}
}

View File

@@ -1,6 +1,6 @@
#include "object.h"
Object::Object() : ModelClass()
Object::Object()// Initialize the reference here
{
m_scaleMatrix = XMMatrixIdentity();
m_rotateMatrix = XMMatrixIdentity();