Scene loading

This commit is contained in:
Sri Sham Haran 2022-10-31 22:04:19 +08:00
parent 18093433fa
commit 917009a5cb
21 changed files with 541 additions and 294 deletions

View File

@ -0,0 +1,4 @@
Start in Fullscreen: false
Starting Scene ID: 0
Window Size: {x: 1920, y: 1080}
Window Title: SHADE Engine

View File

@ -22,7 +22,7 @@
// Managers
#include "ECS_Base/Managers/SHEntityManager.h"
#include "Scene/SHSceneManager.h"
#include "Serialization/Configurations/SHConfigurationManager.h"
// Systems
#include "Scripting/SHScriptEngine.h"
#include "Physics/SHPhysicsSystem.h"
@ -36,7 +36,7 @@
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
#include "Math/Transform/SHTransformComponent.h"
#include "Scenes/SBTestScene.h"
#include "Scenes/SBMainScene.h"
#include "Assets/SHAssetManager.h"
@ -58,8 +58,9 @@ namespace Sandbox
{
// Set working directory
SHFileUtilities::SetWorkDirToExecDir();
window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
WindowData wndData{};
auto const& applicationConfig = SHConfigurationManager::LoadApplicationConfig(&wndData);
window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow, wndData);
// Create Systems
SHSystemManager::CreateSystem<SHGraphicsSystem>();
@ -71,6 +72,7 @@ namespace Sandbox
SHSystemManager::CreateSystem<SHCameraSystem>();
#ifdef SHEDITOR
SDL_Init(SDL_INIT_VIDEO);
sdlWindow = SDL_CreateWindowFrom(window.GetHWND());
SHSystemManager::CreateSystem<SHEditor>();
@ -123,7 +125,7 @@ namespace Sandbox
SHSystemManager::Init();
SHSceneManager::InitSceneManager<SBTestScene>("TestScene");
SHSceneManager::InitSceneManager<SBMainScene>(applicationConfig.startingSceneID);
SHFrameRateController::UpdateFRC();
}

View File

@ -0,0 +1,91 @@
#include "SBpch.h"
#include "SBMainScene.h"
#include "ECS_Base/Managers/SHSystemManager.h"
#include "Graphics/MiddleEnd/Meshes/SHPrimitiveGenerator.h"
#include "ECS_Base/Managers/SHEntityManager.h"
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
#include "Scene/SHSceneManager.h"
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
#include "Scripting/SHScriptEngine.h"
#include "Math/Transform/SHTransformComponent.h"
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
#include "Physics/Components/SHRigidBodyComponent.h"
#include "Physics/Components/SHColliderComponent.h"
#include "Graphics/MiddleEnd/Lights/SHLightComponent.h"
#include "Assets/SHAssetManager.h"
#include "Camera/SHCameraComponent.h"
#include "Resource/SHResourceManager.h"
#include "Serialization/SHSerialization.h"
using namespace SHADE;
namespace Sandbox
{
void SBMainScene::WindowFocusFunc([[maybe_unused]] void* window, int focused)
{
if (focused)
{
}
else
{
}
}
void SBMainScene::Load()
{
}
void SBMainScene::Init()
{
SHADE::SHGraphicsSystem* graphicsSystem = static_cast<SHADE::SHGraphicsSystem*>(SHADE::SHSystemManager::GetSystem<SHADE::SHGraphicsSystem>());
// Create temp meshes
const auto CUBE_MESH = SHADE::SHPrimitiveGenerator::Cube(*graphicsSystem);
//Test Racoon mesh
std::vector<Handle<SHMesh>> handles;
std::vector<Handle<SHTexture>> texHandles;
for (const auto& asset : SHAssetManager::GetAllAssets())
{
switch (asset.type)
{
case AssetType::MESH:
if (asset.name == "Cube.012")
handles.emplace_back(SHResourceManager::LoadOrGet<SHMesh>(asset.id));
break;
case AssetType::TEXTURE:
if (asset.name == "RaccoonPreTexturedVer1_Base9")
texHandles.emplace_back(SHResourceManager::LoadOrGet<SHTexture>(asset.id));
break;
}
}
SHResourceManager::FinaliseChanges();
// Create Materials
auto matInst = graphicsSystem->AddOrGetBaseMaterialInstance();
auto customMat = graphicsSystem->AddMaterialInstanceCopy(matInst);
customMat->SetProperty("data.color", SHVec4(0.0f, 1.0f, 1.0f, 1.0f));
customMat->SetProperty("data.textureIndex", 0);
customMat->SetProperty("data.alpha", 0.1f);
sceneName = SHSerialization::DeserializeSceneFromFile(sceneAssetID);
}
void SBMainScene::Update(float dt)
{
}
void SBMainScene::Render()
{
}
void SBMainScene::Unload()
{
}
void SBMainScene::Free()
{
//SHSerialization::SerializeScene("resources/scenes/Scene01.SHADE");
}
}

View File

@ -5,7 +5,7 @@
namespace Sandbox
{
class SBTestScene : public SHADE::SHScene
class SBMainScene : public SHADE::SHScene
{
private:
EntityID camera;
@ -23,7 +23,7 @@ namespace Sandbox
//TODO: Change to new window DO IT IN CPP TOO
void WindowFocusFunc(void* window, int focused);
SBTestScene(void) = default;
SBMainScene(void) = default;
};
}

View File

@ -1,205 +0,0 @@
#include "SBpch.h"
#include "SBTestScene.h"
#include "ECS_Base/Managers/SHSystemManager.h"
#include "Graphics/MiddleEnd/Meshes/SHPrimitiveGenerator.h"
#include "ECS_Base/Managers/SHEntityManager.h"
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
#include "Scene/SHSceneManager.h"
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
#include "Scripting/SHScriptEngine.h"
#include "Math/Transform/SHTransformComponent.h"
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
#include "Physics/Components/SHRigidBodyComponent.h"
#include "Physics/Components/SHColliderComponent.h"
#include "Graphics/MiddleEnd/Lights/SHLightComponent.h"
#include "Assets/SHAssetManager.h"
#include "Camera/SHCameraComponent.h"
#include "Resource/SHResourceManager.h"
using namespace SHADE;
namespace Sandbox
{
void SBTestScene::WindowFocusFunc([[maybe_unused]] void* window, int focused)
{
if (focused)
{
}
else
{
}
}
void SBTestScene::Load()
{
}
void SBTestScene::Init()
{
SHADE::SHGraphicsSystem* graphicsSystem = static_cast<SHADE::SHGraphicsSystem*>(SHADE::SHSystemManager::GetSystem<SHADE::SHGraphicsSystem>());
// Create temp meshes
const auto CUBE_MESH = SHADE::SHPrimitiveGenerator::Cube(*graphicsSystem);
//Test Racoon mesh
std::vector<Handle<SHMesh>> handles;
std::vector<Handle<SHTexture>> texHandles;
for (const auto& asset : SHAssetManager::GetAllAssets())
{
switch (asset.type)
{
case AssetType::MESH:
if (asset.name == "Cube.012")
handles.emplace_back(SHResourceManager::LoadOrGet<SHMesh>(asset.id));
break;
case AssetType::TEXTURE:
if (asset.name == "RaccoonPreTexturedVer1_Base9")
texHandles.emplace_back(SHResourceManager::LoadOrGet<SHTexture>(asset.id));
break;
}
}
SHResourceManager::FinaliseChanges();
// Create Materials
auto matInst = graphicsSystem->AddOrGetBaseMaterialInstance();
auto customMat = graphicsSystem->AddMaterialInstanceCopy(matInst);
customMat->SetProperty("data.color", SHVec4(0.0f, 1.0f, 1.0f, 1.0f));
customMat->SetProperty("data.textureIndex", 0);
customMat->SetProperty("data.alpha", 0.1f);
// Create Stress Test Objects
static const SHVec3 TEST_OBJ_SCALE = SHVec3::One;
constexpr int NUM_ROWS = 3;
constexpr int NUM_COLS = 1;
static const SHVec3 TEST_OBJ_SPACING = { 0.1f, 0.1f, 0.1f };
static const SHVec3 TEST_OBJ_START_POS = { -(NUM_COLS / 2 * TEST_OBJ_SPACING.x) + 1.0f, -2.0f, -1.0f };
for (int y = 0; y < NUM_ROWS; ++y)
for (int x = 0; x < NUM_COLS; ++x)
{
auto entity = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent, SHRigidBodyComponent, SHColliderComponent>();
auto& renderable = *SHComponentManager::GetComponent_s<SHRenderable>(entity);
auto& transform = *SHComponentManager::GetComponent_s<SHTransformComponent>(entity);
auto& collider = *SHComponentManager::GetComponent_s<SHColliderComponent>(entity);
//renderable.Mesh = handles.front();
renderable.SetMesh(CUBE_MESH);
renderable.SetMaterial(customMat);
if (y == 50)
renderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(1.0f, 0.0f, 0.0f, 1.0f));
//Set initial positions
transform.SetWorldPosition(TEST_OBJ_START_POS + SHVec3{ x * TEST_OBJ_SPACING.x, y * TEST_OBJ_SPACING.y, SHMath::GenerateRandomNumber(-3.5f, -5.0f) });
//transform.SetWorldPosition({-1.0f, -1.0f, -1.0f});
transform.SetWorldRotation(SHMath::GenerateRandomNumber(0.0f, 360.0f), SHMath::GenerateRandomNumber(0.0f, 360.0f), SHMath::GenerateRandomNumber(0.0f, 360.0f));
transform.SetWorldScale(TEST_OBJ_SCALE);
collider.AddBoundingBox(SHVec3::One, SHVec3::Zero);
stressTestObjects.emplace_back(entity);
}
auto raccoonSpin = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
auto& renderable = *SHComponentManager::GetComponent_s<SHRenderable>(raccoonSpin);
auto& transform = *SHComponentManager::GetComponent_s<SHTransformComponent>(raccoonSpin);
renderable.SetMesh(handles.front());
renderable.SetMaterial(customMat);
renderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f));
renderable.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f);
renderable.GetModifiableMaterial()->SetProperty("data.textureIndex", 0);
transform.SetWorldPosition({ -3.0f, -1.0f, -1.0f });
transform.SetLocalScale({ 5.0f, 5.0f, 5.0f });
auto floor = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent, SHRigidBodyComponent, SHColliderComponent>();
auto& floorRenderable = *SHComponentManager::GetComponent_s<SHRenderable>(floor);
auto& floorTransform = *SHComponentManager::GetComponent_s<SHTransformComponent>(floor);
auto& floorRigidBody = *SHComponentManager::GetComponent_s<SHRigidBodyComponent>(floor);
auto& floorCollider = *SHComponentManager::GetComponent_s<SHColliderComponent>(floor);
floorRenderable.SetMesh(CUBE_MESH);
floorRenderable.SetMaterial(graphicsSystem->GetDefaultMaterialInstance());
floorTransform.SetWorldScale({ 7.5f, 0.5f, 7.5 });
floorTransform.SetWorldPosition({ 0.0f, -3.0f, -5.0f });
floorRigidBody.SetType(SHRigidBodyComponent::Type::STATIC);
auto* floorBox = floorCollider.AddBoundingBox();
floorBox->SetHalfExtents(floorTransform.GetWorldScale() * 0.5f);
// Create blank entity with a script
//testObj = SHADE::SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
//auto& testObjRenderable = *SHComponentManager::GetComponent<SHRenderable>(testObj);
//testObjRenderable.Mesh = CUBE_MESH;
//testObjRenderable.SetMaterial(matInst);
SHADE::SHScriptEngine* scriptEngine = static_cast<SHADE::SHScriptEngine*>(SHADE::SHSystemManager::GetSystem<SHADE::SHScriptEngine>());
scriptEngine->AddScript(raccoonSpin, "RaccoonSpin");
auto raccoonShowcase = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
auto& renderableShowcase = *SHComponentManager::GetComponent_s<SHRenderable>(raccoonShowcase);
auto& transformShowcase = *SHComponentManager::GetComponent_s<SHTransformComponent>(raccoonShowcase);
renderableShowcase.SetMesh(handles.front());
renderableShowcase.SetMaterial(customMat);
renderableShowcase.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f));
renderableShowcase.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f);
renderableShowcase.GetModifiableMaterial()->SetProperty("data.textureIndex", 0);
transformShowcase.SetWorldPosition({ 3.0f, -1.0f, -1.0f });
transformShowcase.SetLocalScale({ 5.0f, 5.0f, 5.0f });
scriptEngine->AddScript(raccoonShowcase, "RaccoonShowcase");
SHComponentManager::AddComponent<SHCameraComponent>(0);
SHComponentManager::AddComponent<SHLightComponent>(0);
SHComponentManager::RemoveComponent <SHRigidBodyComponent>(0);
SHComponentManager::RemoveComponent <SHColliderComponent>(0);
auto ambientLight = SHEntityManager::CreateEntity<SHLightComponent>();
SHComponentManager::GetComponent<SHLightComponent>(ambientLight)->SetColor(SHVec4(1.0f, 1.0f, 1.0f, 1.0f));
SHComponentManager::GetComponent<SHLightComponent>(ambientLight)->SetStrength(0.25f);
SHComponentManager::GetComponent<SHLightComponent>(ambientLight)->SetType(SH_LIGHT_TYPE::AMBIENT);
}
void SBTestScene::Update(float dt)
{
static float rotation = 0.0f;
SHVec3 direction{0.0f, 0.0f, 1.0f};
direction = SHVec3::RotateY(direction, rotation);
auto* lightComp =SHComponentManager::GetComponent<SHLightComponent>(0);
lightComp->SetDirection (direction);
rotation += 0.005f;
//auto& transform = *SHADE::SHComponentManager::GetComponent_s<SHADE::SHTransformComponent>(testObj);
//transform.SetWorldPosition({1.0f, 1.0f, -1.0f});
//transform.SetWorldRotation(0.0f, 0.0f + rotation, 0.0f);
//rotation += dt * 0.2f;
// Destroy entity if space is pressed
if (GetKeyState(VK_SPACE) & 0x8000)
{
rotation = 0.0f;
SHADE::SHScriptEngine* scriptEngine = static_cast<SHADE::SHScriptEngine*>(SHADE::SHSystemManager::GetSystem<SHADE::SHScriptEngine>());
scriptEngine->RemoveAllScripts(testObj);
}
}
void SBTestScene::Render()
{
}
void SBTestScene::Unload()
{
}
void SBTestScene::Free()
{
//SHSerialization::SerializeScene("resources/scenes/Scene01.SHADE");
}
}

View File

@ -17,6 +17,7 @@
#include <imgui_internal.h>
#include <rttr/type>
#include "Scene/SHSceneManager.h"
#include "Serialization/SHSerialization.h"
namespace SHADE
@ -75,13 +76,19 @@ namespace SHADE
{
if (ImGui::BeginMenu("File"))
{
if(ImGui::Selectable("New"))
{
auto editor = SHSystemManager::GetSystem<SHEditor>();
editor->NewScene();
}
if(ImGui::Selectable("Save"))
{
SHSerialization::SerializeSceneToFile("../../Assets/Scenes/Test.SHADE");
auto editor = SHSystemManager::GetSystem<SHEditor>();
editor->SaveScene();
}
if(ImGui::Selectable("Load"))
{
SHSerialization::DeserializeSceneFromFile("../../Assets/Scenes/Test.SHADE");
SHSerialization::DeserializeSceneFromFile(SHSceneManager::GetCurrentSceneAssetID());
}
ImGui::EndMenu();
}

View File

@ -37,7 +37,7 @@ namespace SHADE
proj(1, 1) *= -1;
static SHMatrix gridMat = SHMatrix::Translate(0, -0.5f, 0.f) * SHMatrix::Identity;
if (selectedEntityTransformComponent == nullptr)
{
SHEditor* editor = SHSystemManager::GetSystem<SHEditor>();

View File

@ -25,6 +25,7 @@
#include "SHEditorWidgets.hpp"
#include "Math/Transform/SHTransformSystem.h"
#include "Graphics/Windowing/SHWindow.h"
//#==============================================================#
//|| Editor Window Includes ||
@ -45,8 +46,11 @@
#include <backends/imgui_impl_sdl.h>
#include <backends/imgui_impl_vulkan.h>
#include "Assets/SHAssetManager.h"
#include "Assets/Asset Types/SHSceneAsset.h"
#include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h"
#include "Scene/SHSceneManager.h"
#include "Serialization/SHSerialization.h"
RTTR_REGISTRATION
{
using namespace SHADE;
@ -145,6 +149,11 @@ namespace SHADE
{
SHCommandManager::UndoCommand();
}
if(ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_S))
{
SaveScene();
}
Render();
}
@ -159,6 +168,60 @@ namespace SHADE
}
}
void SHEditor::RenderSceneNamePrompt() noexcept
{
if(isSceneNamePromptOpen)
{
ImGui::OpenPopup(sceneNamePromptName.data());
}
if(ImGui::BeginPopupModal(sceneNamePromptName.data(), &isSceneNamePromptOpen))
{
static std::string newSceneName{};
ImGui::Text("Enter new scene name");
ImGui::InputText("##name", &newSceneName);
ImGui::BeginDisabled(newSceneName.empty());
if(ImGui::Button("Save"))
{
SaveScene(newSceneName);
newSceneName.clear();
isSceneNamePromptOpen = false;
ImGui::CloseCurrentPopup();
}
ImGui::EndDisabled();
ImGui::SameLine();
if(ImGui::Button("Cancel"))
{
isSceneNamePromptOpen = false;
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
}
void SHEditor::RenderUnsavedChangesPrompt() noexcept
{
if(isUnsavedChangesPromptOpen)
{
ImGui::OpenPopup(unsavedChangesPromptName.data());
}
if(ImGui::BeginPopupModal(unsavedChangesPromptName.data(), &isUnsavedChangesPromptOpen))
{
ImGui::Text("You have unsaved changes!");
if(ImGui::Button("Save"))
{
isSceneNamePromptOpen = true;
}
ImGui::SameLine();
if(ImGui::Button("Cancel"))
{
isUnsavedChangesPromptOpen = false;
ImGui::CloseCurrentPopup();
}
}
}
void SHEditor::InitLayout() noexcept
{
if(!std::filesystem::exists(io->IniFilename))
@ -366,6 +429,59 @@ namespace SHADE
}
}
void SHEditor::NewScene()
{
if(windowMap.GetMainWindow()->IsUnsavedChanges())
{
//Unsaved changes prompt
sceneToLoad = 0;
isUnsavedChangesPromptOpen = true;
}
else
{
SHSceneManager::RestartScene(0);
}
}
void SHEditor::SaveScene(std::string const& newSceneName)
{
auto const data = SHAssetManager::GetData<SHSceneAsset>(SHSceneManager::GetCurrentSceneAssetID());
if (!data)
{
if (newSceneName.empty())
{
//Prompt for scene name
isSceneNamePromptOpen = true;
return;
}
//Else We have a new name
SHSceneManager::SetCurrentSceneName(newSceneName.data());
SHSceneManager::SetCurrentSceneAssetID(SHAssetManager::CreateNewAsset(AssetType::SCENE, newSceneName.data()));
}
//Get data, if data is null, asset doesn't exist, prompt for a name and create a new asset with the name
//serialize the scene
SHSerialization::SerializeSceneToFile(SHSceneManager::GetCurrentSceneAssetID());
windowMap.GetMainWindow()->ToggleUnsavedChanges();
}
void SHEditor::LoadScene(AssetID const& assetID) noexcept
{
if(windowMap.GetMainWindow()->IsUnsavedChanges())
{
//Unsaved changes prompt
isUnsavedChangesPromptOpen = true;
sceneToLoad = assetID;
}
else
{
//Load the scene
sceneToLoad = 0;
SHSceneManager::RestartScene(assetID);
}
}
void SHEditor::NewFrame()
{
SDL_Event event;

View File

@ -24,6 +24,8 @@
//#==============================================================#
#include <SDL_video.h>
#include "Assets/SHAssetMacros.h"
namespace SHADE
{
//#==============================================================#
@ -173,6 +175,12 @@ namespace SHADE
void PollPicking();
void NewScene();
void SaveScene(std::string const& newSceneName = {});
void LoadScene(AssetID const& assetID) noexcept;
// List of selected entities
std::vector<EntityID> selectedEntities;
@ -190,10 +198,23 @@ namespace SHADE
*/
void Render();
void RenderSceneNamePrompt() noexcept;
void RenderUnsavedChangesPrompt() noexcept;
void InitLayout() noexcept;
void InitFonts() noexcept;
bool isSceneNamePromptOpen = false;
bool isUnsavedChangesPromptOpen = false;
static constexpr std::string_view sceneNamePromptName = "Save scene as...";
static constexpr std::string_view unsavedChangesPromptName = "Unsaved Changes";
AssetID sceneToLoad = 0;
// Handle to command pool used for ImGui Vulkan Backend
Handle<SHVkCommandPool> imguiCommandPool;
// Handle to command buffer used for ImGui Vulkan Backend

View File

@ -4,7 +4,6 @@
#include "ECS_Base/Managers/SHSystemManager.h"
#include "Input/SHInputManager.h"
namespace SHADE
{
SHWindow::SHWindow()
@ -151,11 +150,11 @@ namespace SHADE
SetWindowText(wndHWND, LPCWSTR(wndData.title.c_str()));
}
SHWindow::SHVec2 SHWindow::GetPosition() const
SHWindow::WindowSize SHWindow::GetPosition() const
{
RECT rect;
GetWindowRect(wndHWND, &rect);
return SHVec2(static_cast<uint32_t>(rect.left), static_cast<uint32_t>(rect.top));
return WindowSize(static_cast<uint32_t>(rect.left), static_cast<uint32_t>(rect.top));
}
void SHWindow::SetPosition(unsigned x, unsigned y)
@ -165,18 +164,18 @@ namespace SHADE
wndData.y = y;
}
SHWindow::SHVec2 SHWindow::GetWindowSize() const
SHWindow::WindowSize SHWindow::GetWindowSize() const
{
RECT rect;
GetClientRect(wndHWND, &rect);
return SHVec2(static_cast<uint32_t>(rect.right - rect.left), static_cast<uint32_t>(rect.bottom - rect.top));
return WindowSize(static_cast<uint32_t>(rect.right - rect.left), static_cast<uint32_t>(rect.bottom - rect.top));
}
SHWindow::SHVec2 SHWindow::GetCurrentDisplaySize() const
SHWindow::WindowSize SHWindow::GetCurrentDisplaySize() const
{
unsigned screenWidth = GetSystemMetrics(SM_CXSCREEN);
unsigned screenHeight = GetSystemMetrics(SM_CYSCREEN);
return SHVec2(screenWidth, screenHeight);
return WindowSize(screenWidth, screenHeight);
}
void SHWindow::SetMouseVisible(bool show)
@ -260,7 +259,7 @@ namespace SHADE
return wndHWND;
}
const WindowData SHWindow::GetWindowData()
const WindowData SHWindow::GetWindowData() const noexcept
{
return wndData;
}
@ -287,6 +286,15 @@ namespace SHADE
windowCloseCallbacks.erase(callbackid);
}
void SHWindow::ToggleUnsavedChanges() noexcept
{
unsavedChanges = !unsavedChanges;
std::wstring title = wndData.title;
if(unsavedChanges)
title.append(L"*");
SetWindowText(wndHWND, title.data());
}
LRESULT SHWindow::WndProcStatic(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
auto window = windowMap.GetWindow(hwnd);

View File

@ -74,7 +74,7 @@ namespace SHADE
class SH_API SHWindow
{
public:
using SHVec2 = std::pair<uint32_t, uint32_t>;
using WindowSize = std::pair<uint32_t, uint32_t>;
typedef std::function<void(uint32_t width, uint32_t height)> WindowResizeCallbackFn;
typedef std::function<void(void)> WindowCloseCallbackFn;
typedef uint16_t CALLBACKID;
@ -92,15 +92,15 @@ namespace SHADE
void SetTitle(std::wstring title);
SHVec2 GetPosition() const;
WindowSize GetPosition() const;
void SetPosition(unsigned x, unsigned y);
//void SetPosition(SHMathVec2U);
SHVec2 GetWindowSize() const;
WindowSize GetWindowSize() const;
//Get size of display the window is in (whichever window contains the window origin)
SHVec2 GetCurrentDisplaySize() const;
WindowSize GetCurrentDisplaySize() const;
void SetMouseVisible(bool show);
@ -123,7 +123,7 @@ namespace SHADE
HWND GetHWND();
const WindowData GetWindowData();
const WindowData GetWindowData() const noexcept;
CALLBACKID RegisterWindowSizeCallback(WindowResizeCallbackFn);
void UnregisterWindowSizeCallback(CALLBACKID const& callbackid);
@ -131,6 +131,8 @@ namespace SHADE
void UnregisterWindowCloseCallback(CALLBACKID const& callbackid);
bool IsMinimized() const { return wndData.isMinimised; }
void ToggleUnsavedChanges() noexcept;
bool IsUnsavedChanges() const noexcept{return unsavedChanges;}
protected:
static LRESULT CALLBACK WndProcStatic(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
@ -164,7 +166,8 @@ namespace SHADE
std::unordered_map<CALLBACKID, WindowCloseCallbackFn> windowCloseCallbacks;
CALLBACKID windowResizeCallbackCount{};
CALLBACKID windowCloseCallbackCount{};
//TODO: Shift to events abstraction
bool unsavedChanges = false;
void OnCreate(HWND hwnd, LPCREATESTRUCT create_struct);
void OnClose();

View File

@ -13,6 +13,7 @@
#include <string>
#include "SHSceneGraph.h"
#include "Assets/SHAssetMacros.h"
#include "ECS_Base/General/SHFamily.h"
namespace SHADE
@ -32,6 +33,7 @@ namespace SHADE
virtual ~SHScene() = default;
std::string sceneName;
AssetID sceneAssetID;
SHSceneGraph& GetSceneGraph() noexcept { return sceneGraph; }

View File

@ -29,7 +29,7 @@ namespace SHADE
std::string SHSceneManager::newSceneName{};
uint32_t SHSceneManager::currentSceneID = UINT32_MAX;
uint32_t SHSceneManager::nextSceneID = UINT32_MAX;
AssetID SHSceneManager::currentSceneAssetID{};
SHScene* SHSceneManager::currentScene = nullptr;
//SHScene* SHSceneManager::nextScene = nullptr;
@ -107,12 +107,12 @@ namespace SHADE
}
}
void SHSceneManager::RestartScene(std::string const& sceneName) noexcept
void SHSceneManager::RestartScene(AssetID const& assetID ) noexcept
{
if (currentScene->sceneName != sceneName)
if (currentScene->sceneAssetID != assetID)
{
cleanReload = true;
newSceneName = sceneName;
//newSceneName = sceneName;
}
else
cleanReload = false;
@ -151,4 +151,20 @@ namespace SHADE
{
return currentScene->sceneName;
}
void SHSceneManager::SetCurrentSceneName(std::string const& sceneName) noexcept
{
currentScene->sceneName = sceneName;
}
AssetID SHSceneManager::GetCurrentSceneAssetID() noexcept
{
return currentScene->sceneAssetID;
}
void SHSceneManager::SetCurrentSceneAssetID(AssetID const& newAssetID)
{
currentScene->sceneAssetID = newAssetID;
currentSceneAssetID = newAssetID;
}
}

View File

@ -20,6 +20,7 @@
//Project Headers
#include "SH_API.h"
#include "ECS_Base/General/SHFamily.h"
#include "Assets/SHAssetMacros.h"
namespace SHADE
{
@ -47,6 +48,9 @@ namespace SHADE
//pointer to the current scene
static SHScene* currentScene;
//Scene AssetID of the current scene
static AssetID currentSceneAssetID;
//Used in reloading scene.
static std::string newSceneName;
@ -80,10 +84,10 @@ namespace SHADE
* None.
***************************************************************************/
template<typename T>
static std::enable_if_t<std::is_base_of_v<SHScene, T>, void> InitSceneManager(std::string const& sceneName) noexcept
static std::enable_if_t<std::is_base_of_v<SHScene, T>, void> InitSceneManager(AssetID const& sceneAssetID) noexcept
{
//prevSceneCreate = newScene;
newScene = [sceneName]() { currentScene = new T(); currentScene->sceneName = sceneName; };
newScene = [sceneAssetID]() { currentScene = new T(); currentScene->sceneAssetID = sceneAssetID; };
//nextSceneID = SHFamilyID<SHScene>::GetID<T>();
nextSceneID = 0;
@ -99,7 +103,7 @@ namespace SHADE
* None.
***************************************************************************/
template<typename T>
static std::enable_if_t<std::is_base_of_v<SHScene, T>, void> ChangeScene(std::string const& sceneName) noexcept
static std::enable_if_t<std::is_base_of_v<SHScene, T>, void> ChangeScene(AssetID const& sceneAssetID) noexcept
{
//check if this new Scene is current Scene (Use RestartScene instead)
if (currentSceneID == SHFamilyID<SHScene>::GetID<T>())
@ -107,7 +111,7 @@ namespace SHADE
return;
}
//prevSceneCreate = newScene;
newScene = [sceneName]() { currentScene = new T(); currentScene->sceneName; };
newScene = [sceneAssetID]() { currentScene = new T(); currentScene->sceneAssetID = sceneAssetID; };
nextSceneID = SHFamilyID<SHScene>::GetID<T>();
sceneChanged = true;
}
@ -137,11 +141,11 @@ namespace SHADE
* Restarts current scene. Only Scene::Init() and Scene::Free()
* Scene::Load() and Scene::Unload() will not be called.
* Edit: allows for RestartScene to restart the scene with a different
* scene name.
* If a sceneName is different from the current one, Load and Unload will
* scene asset ID.
* If a scene asset id is different from the current one, Load and Unload will
* run.
***************************************************************************/
static void RestartScene(std::string const& sceneName ) noexcept;
static void RestartScene(AssetID const& assetID ) noexcept;
/*!*************************************************************************
* \brief
@ -164,7 +168,10 @@ namespace SHADE
static void Exit() noexcept;
static std::string GetSceneName() noexcept;
static void SetCurrentSceneName(std::string const& sceneName) noexcept;
static AssetID GetCurrentSceneAssetID() noexcept;
//Only if scene doesn't exist, and scene asset id needs to be updated to the new one
static void SetCurrentSceneAssetID(AssetID const& newAssetID);
};

View File

@ -0,0 +1,89 @@
#include "SHpch.h"
#include "SHConfigurationManager.h"
#include "Tools/FileIO/SHFileIO.h"
#include "Serialization/SHSerializationHelper.hpp"
namespace SHADE
{
SHApplicationConfig SHConfigurationManager::applicationConfig;
#ifdef SHEDITOR
SHEditorConfig SHConfigurationManager::editorConfig;
#endif
void SHConfigurationManager::SaveApplicationConfig()
{
YAML::Emitter out;
out << SHSerializationHelper::RTTRToNode(applicationConfig);
SHFileIO::WriteStringToFile(applicationConfigPath, out.c_str());
}
SHApplicationConfig& SHConfigurationManager::LoadApplicationConfig(WindowData* wndData)
{
if(!std::filesystem::exists(applicationConfigPath))
{
SaveApplicationConfig();
return applicationConfig;
}
auto const node = YAML::Load(SHFileIO::GetStringFromFile(applicationConfigPath));
auto properties = rttr::type::get<SHApplicationConfig>().get_properties();
for(auto const& property : properties)
{
if(node[property.get_name().data()].IsDefined())
SHSerializationHelper::InitializeProperty(&applicationConfig, property, node[property.get_name().data()]);
}
if(wndData != nullptr)
{
wndData->isFullscreen = applicationConfig.startInFullScreen;
wndData->title = std::wstring(applicationConfig.windowTitle.begin(), applicationConfig.windowTitle.end());
wndData->width = static_cast<uint32_t>(applicationConfig.windowSize.x);
wndData->height = static_cast<uint32_t>(applicationConfig.windowSize.y);
}
return applicationConfig;
}
#ifdef SHEDITOR
void SHConfigurationManager::SaveEditorConfig()
{
YAML::Emitter out;
out << SHSerializationHelper::RTTRToNode(editorConfig);
SHFileIO::WriteStringToFile(editorConfigPath, out.c_str());
}
SHEditorConfig& SHConfigurationManager::LoadEditorConfig()
{
auto const node = YAML::Load(SHFileIO::GetStringFromFile(editorConfigPath));
auto properties = rttr::type::get<SHApplicationConfig>().get_properties();
for(auto const& property : properties)
{
if(node[property.get_name().data()].IsDefined())
SHSerializationHelper::InitializeProperty(&editorConfig, property, node[property.get_name().data()]);
}
return editorConfig;
}
void SHConfigurationManager::FetchEditorCameraData()
{
}
void SHConfigurationManager::SetEditorCameraData()
{
}
#endif
}
RTTR_REGISTRATION
{
using namespace rttr;
using namespace SHADE;
registration::class_<SHApplicationConfig>("Application Config")
.property("Start in Fullscreen", &SHApplicationConfig::startInFullScreen)
.property("Starting Scene ID", &SHApplicationConfig::startingSceneID)
.property("Window Size", &SHApplicationConfig::windowSize)
.property("Window Title", &SHApplicationConfig::windowTitle);
}

View File

@ -0,0 +1,44 @@
#pragma once
#include <rttr/registration>
#include "Assets/SHAssetMacros.h"
#include "Graphics/Windowing/SHWindow.h"
#include "SH_API.h"
#include "Math/Vector/SHVec2.h"
namespace SHADE
{
struct SHApplicationConfig
{
bool startInFullScreen{ false };
AssetID startingSceneID{};
SHVec2 windowSize {1920, 1080};
std::string windowTitle {"SHADE Engine"};
RTTR_ENABLE()
};
struct SHEditorConfig
{
};
class SH_API SHConfigurationManager
{
public:
static constexpr std::string_view applicationConfigPath{"../../Assets/Application.SHConfig"};
static constexpr std::string_view editorConfigPath{"../../Assets/Editor/Editor.SHConfig"};
static void SaveApplicationConfig();
static SHApplicationConfig& LoadApplicationConfig(WindowData* wndData = nullptr);
static SHApplicationConfig applicationConfig;
#ifdef SHEDITOR
static void SaveEditorConfig();
static SHEditorConfig& LoadEditorConfig();
static SHEditorConfig editorConfig;
private:
static void FetchEditorCameraData();
static void SetEditorCameraData();
#endif
};
}

View File

@ -10,6 +10,7 @@
#include "Assets/SHAssetManager.h"
#include <fstream>
#include "Assets/Asset Types/SHSceneAsset.h"
#include "Camera/SHCameraComponent.h"
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
#include "Math/Transform/SHTransformComponent.h"
@ -20,16 +21,19 @@
namespace SHADE
{
void SHSerialization::SerializeSceneToFile(std::filesystem::path const& path)
bool SHSerialization::SerializeSceneToFile(AssetID const& sceneAssetID)
{
auto assetData = SHAssetManager::GetData<SHSceneAsset>(sceneAssetID);
if(!assetData)
{
SHLOG_ERROR("Asset does not exist: {}", sceneAssetID);
return false;
}
YAML::Emitter out;
SerializeSceneToEmitter(out);
std::ofstream file(path.c_str());
if (file.good())
{
file << out.c_str();
file.close();
}
assetData->data = out.c_str();
return SHAssetManager::SaveAsset(sceneAssetID);
}
std::string SHSerialization::SerializeSceneToString()
@ -91,31 +95,16 @@ namespace SHADE
return eid;
}
void SHSerialization::DeserializeSceneFromFile(std::filesystem::path const& path)
std::string SHSerialization::DeserializeSceneFromFile(AssetID const& sceneAssetID) noexcept
{
//TODO:Shift to using XQ's FileIO
std::ifstream iFile;
iFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
std::string fileContent = "";
try
auto assetData = SHAssetManager::GetData<SHSceneAsset>(sceneAssetID);
if(!assetData)
{
// Open file
// Read file's buffer contents into streams
iFile.open(path);
std::stringstream fileStream;
fileStream << iFile.rdbuf();
fileContent = fileStream.str();
// Close file handler
iFile.close();
SHLOG_ERROR("Attempted to load scene that doesn't exist {}", sceneAssetID)
SHSceneManager::SetCurrentSceneAssetID(0);
return NewSceneName.data();
}
catch (std::ifstream::failure e)
{
SHLOG_ERROR("Could not read file");
}
YAML::Node entities = YAML::Load(fileContent);
YAML::Node entities = YAML::Load(assetData->data);
std::vector<EntityID> createdEntities{};
//Create Entities
@ -126,7 +115,7 @@ namespace SHADE
if (createdEntities.empty())
{
SHLOG_ERROR("Failed to create entities from deserializaiton")
return;
return NewSceneName.data();
}
//Initialize Entity
auto entityVecIt = createdEntities.begin();
@ -134,7 +123,9 @@ namespace SHADE
{
InitializeEntity(*it, *entityVecIt++);
}
}
return assetData->name;
}
void SHSerialization::EmitEntity(SHSceneNode* entityNode, YAML::Emitter& out)
{

View File

@ -5,6 +5,7 @@
#include <filesystem>
#include <ECS_Base/Components/SHComponent.h>
#include <Assets/SHAssetMacros.h>
namespace YAML
{
@ -25,12 +26,11 @@ namespace SHADE
struct SH_API SHSerialization
{
//TODO: change paths to resource ID
static void SerializeSceneToFile(std::filesystem::path const& path);
static bool SerializeSceneToFile(AssetID const& sceneAssetID);
static std::string SerializeSceneToString();
static void SerializeSceneToEmitter(YAML::Emitter& out);
static void DeserializeSceneFromFile(std::filesystem::path const& path);
static std::string DeserializeSceneFromFile(AssetID const& sceneAssetID) noexcept;
static void EmitEntity(SHSceneNode* entityNode, YAML::Emitter& out);
@ -44,5 +44,7 @@ namespace SHADE
static std::vector<ComponentTypeID> GetComponentIDList(YAML::Node const& componentsNode);
private:
static void InitializeEntity(YAML::Node const& entityNode, EntityID const& eid);
static constexpr std::string_view NewSceneName = "New Scene";
};
}

View File

@ -511,6 +511,8 @@ namespace SHADE
node = YAML::Null;
}
}
else if (varType == rttr::type::get<std::string>())
node = var.to_string();
else
{
auto properties = var.get_type().get_properties();
@ -546,63 +548,65 @@ namespace SHADE
return node;
}
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
static void InitializeProperty(ComponentType* component, rttr::property const& prop, YAML::Node const& propertyNode)
template <typename Type>
static void InitializeProperty(Type* object, rttr::property const& prop, YAML::Node const& propertyNode)
{
auto propType = prop.get_type();
if (propType == rttr::type::get<SHVec4>())
{
SHVec4 vec = propertyNode.as<SHVec4>();
prop.set_value(component, vec);
prop.set_value(object, vec);
}
else if (propType == rttr::type::get<SHVec3>())
{
SHVec3 vec = propertyNode.as<SHVec3>();
prop.set_value(component, vec);
prop.set_value(object, vec);
}
else if (propType == rttr::type::get<SHVec2>())
{
SHVec2 vec = propertyNode.as<SHVec2>();
prop.set_value(component, vec);
prop.set_value(object, vec);
}
else if (propType.is_arithmetic())
{
bool ok = false;
if (propType == rttr::type::get<bool>())
prop.set_value(component, propertyNode.as<bool>());
prop.set_value(object, propertyNode.as<bool>());
else if (propType == rttr::type::get<int8_t>())
prop.set_value(component, propertyNode.as<int8_t>());
prop.set_value(object, propertyNode.as<int8_t>());
else if (propType == rttr::type::get<int16_t>())
prop.set_value(component, propertyNode.as<int16_t>());
prop.set_value(object, propertyNode.as<int16_t>());
else if (propType == rttr::type::get<int32_t>())
prop.set_value(component, propertyNode.as<int32_t>());
prop.set_value(object, propertyNode.as<int32_t>());
else if (propType == rttr::type::get<int64_t>())
prop.set_value(component, propertyNode.as<int64_t>());
prop.set_value(object, propertyNode.as<int64_t>());
else if (propType == rttr::type::get<uint8_t>())
prop.set_value(component, propertyNode.as<uint8_t>());
prop.set_value(object, propertyNode.as<uint8_t>());
else if (propType == rttr::type::get<uint16_t>())
prop.set_value(component, propertyNode.as<uint16_t>());
prop.set_value(object, propertyNode.as<uint16_t>());
else if (propType == rttr::type::get<uint32_t>())
prop.set_value(component, propertyNode.as<uint32_t>());
prop.set_value(object, propertyNode.as<uint32_t>());
else if (propType == rttr::type::get<uint64_t>())
prop.set_value(component, propertyNode.as<uint64_t>());
prop.set_value(object, propertyNode.as<uint64_t>());
else if (propType == rttr::type::get<float>())
prop.set_value(component, propertyNode.as<float>());
prop.set_value(object, propertyNode.as<float>());
else if (propType == rttr::type::get<double>())
prop.set_value(component, propertyNode.as<double>());
prop.set_value(object, propertyNode.as<double>());
}
else if (propType.is_enumeration())
{
auto enumAlign = prop.get_enumeration();
prop.set_value(component, enumAlign.name_to_value(propertyNode.as<std::string>()));
prop.set_value(object, enumAlign.name_to_value(propertyNode.as<std::string>()));
}
else if (propType == rttr::type::get<std::string>())
prop.set_value(object, propertyNode.as<std::string>());
else
{
auto properties = propType.get_properties();
for (auto const& property : properties)
{
if(propertyNode[property.get_name().data()].IsDefined())
InitializeProperty(component, property, propertyNode[property.get_name().data()]);
InitializeProperty(object, property, propertyNode[property.get_name().data()]);
}
}
}

View File

@ -0,0 +1,31 @@
#include "SHpch.h"
#include "SHFileIO.h"
#include <fstream>
namespace SHADE
{
int SHFileIO::WriteStringToFile(std::filesystem::path const& filePath, std::string_view const& strView)
{
std::ofstream file(filePath);
if(file.good())
{
file << strView;
file.close();
return 1;
}
return 0;
}
std::string SHFileIO::GetStringFromFile(std::filesystem::path const& filePath)
{
std::ifstream iFile;
iFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
std::string fileData{};
iFile.open(filePath, std::iostream::binary);
std::stringstream ss;
ss << iFile.rdbuf();
fileData = ss.str();
iFile.close();
return fileData;
}
}

View File

@ -0,0 +1,14 @@
#pragma once
#include <filesystem>
#include <string>
#include <string_view>
#include <SH_API.h>
namespace SHADE
{
struct SH_API SHFileIO
{
static int WriteStringToFile(std::filesystem::path const& filePath, std::string_view const& strView);
static std::string GetStringFromFile(std::filesystem::path const& file);
};
}