Scenes now load from file based on application config starting scene id #174
|
@ -0,0 +1,4 @@
|
|||
Start in Fullscreen: false
|
||||
Starting Scene ID: 94283040
|
||||
Window Size: {x: 1920, y: 1080}
|
||||
Window Title: SHADE Engine
|
|
@ -2,7 +2,7 @@
|
|||
FragmentShader: 46377769
|
||||
SubPass: G-Buffer Write
|
||||
Properties:
|
||||
data.color: {x: 1, y: 0.200000003, z: 0.100000001, w: 1}
|
||||
data.color: {x: 1, y: 1, z: 1, w: 1}
|
||||
data.textureIndex: 64651793
|
||||
data.alpha: 0
|
||||
data.beta: {x: 1, y: 1, z: 1}
|
|
@ -0,0 +1,8 @@
|
|||
- VertexShader: 39210065
|
||||
FragmentShader: 46377769
|
||||
SubPass: G-Buffer Write
|
||||
Properties:
|
||||
data.color: {x: 1, y: 1, z: 1, w: 1}
|
||||
data.textureIndex: 0
|
||||
data.alpha: 0
|
||||
data.beta: {x: 1, y: 1, z: 1}
|
|
@ -0,0 +1,3 @@
|
|||
Name: WhiteMat
|
||||
ID: 124370424
|
||||
Type: 7
|
|
@ -0,0 +1,216 @@
|
|||
- EID: 0
|
||||
Name: Default
|
||||
IsActive: true
|
||||
NumberOfChildren: 0
|
||||
Components:
|
||||
Camera Component:
|
||||
Position: {x: 0, y: 0, z: 0}
|
||||
Pitch: 0
|
||||
Yaw: 0
|
||||
Roll: 0
|
||||
Width: 1920
|
||||
Height: 1080
|
||||
Near: 0.00999999978
|
||||
Far: 10000
|
||||
Perspective: true
|
||||
Light Component:
|
||||
Position: {x: 0, y: 0, z: 0}
|
||||
Type: Directional
|
||||
Direction: {x: 1.79999995, y: 0, z: 1}
|
||||
Color: {x: 0.951541841, y: 0.921719015, z: 0.553319454, w: 1}
|
||||
Layer: 4294967295
|
||||
Strength: 0
|
||||
Scripts: ~
|
||||
- EID: 1
|
||||
Name: Default
|
||||
IsActive: true
|
||||
NumberOfChildren: 0
|
||||
Components:
|
||||
Transform Component:
|
||||
Translate: {x: -1.440328, y: -4.41369677, z: -5}
|
||||
Rotate: {x: -0, y: 0, z: -0}
|
||||
Scale: {x: 49.4798889, y: 0.5, z: 17.5}
|
||||
Renderable Component:
|
||||
Mesh: 149697411
|
||||
Material: 126974645
|
||||
RigidBody Component:
|
||||
Type: Static
|
||||
Mass: 1
|
||||
Drag: 0
|
||||
Angular Drag: 0
|
||||
Use Gravity: true
|
||||
Interpolate: true
|
||||
Freeze Position X: false
|
||||
Freeze Position Y: false
|
||||
Freeze Position Z: false
|
||||
Freeze Rotation X: false
|
||||
Freeze Rotation Y: false
|
||||
Freeze Rotation Z: false
|
||||
Collider Component:
|
||||
Colliders:
|
||||
- Is Trigger: false
|
||||
Type: Box
|
||||
Half Extents: {x: 0.0170898438, y: 0.00048828125, z: 0.0170898438}
|
||||
Friction: 0.400000006
|
||||
Bounciness: 0
|
||||
Density: 1
|
||||
Position Offset: {x: 0, y: 0, z: 0}
|
||||
Scripts: ~
|
||||
- EID: 2
|
||||
Name: Player
|
||||
IsActive: true
|
||||
NumberOfChildren: 2
|
||||
Components:
|
||||
Transform Component:
|
||||
Translate: {x: -3.06177855, y: -2, z: -5}
|
||||
Rotate: {x: -0, y: 0, z: -0}
|
||||
Scale: {x: 2, y: 2, z: 2}
|
||||
Renderable Component:
|
||||
Mesh: 149697411
|
||||
Material: 126974645
|
||||
RigidBody Component:
|
||||
Type: Dynamic
|
||||
Mass: 1
|
||||
Drag: 0
|
||||
Angular Drag: 0
|
||||
Use Gravity: true
|
||||
Interpolate: true
|
||||
Freeze Position X: false
|
||||
Freeze Position Y: false
|
||||
Freeze Position Z: false
|
||||
Freeze Rotation X: false
|
||||
Freeze Rotation Y: false
|
||||
Freeze Rotation Z: false
|
||||
Collider Component:
|
||||
Colliders:
|
||||
- Is Trigger: false
|
||||
Type: Box
|
||||
Half Extents: {x: 0.0009765625, y: 0.0009765625, z: 0.0009765625}
|
||||
Friction: 0.400000006
|
||||
Bounciness: 0
|
||||
Density: 1
|
||||
Position Offset: {x: 0, y: 0.5, z: 0}
|
||||
Scripts: ~
|
||||
- EID: 3
|
||||
Name: Default
|
||||
IsActive: true
|
||||
NumberOfChildren: 0
|
||||
Components:
|
||||
Transform Component:
|
||||
Translate: {x: -0.0094268322, y: 0, z: 0}
|
||||
Rotate: {x: -0, y: 0, z: -0}
|
||||
Scale: {x: 1, y: 1, z: 1}
|
||||
Scripts: ~
|
||||
- EID: 4
|
||||
Name: Default
|
||||
IsActive: true
|
||||
NumberOfChildren: 0
|
||||
Components:
|
||||
Transform Component:
|
||||
Translate: {x: 0, y: 0, z: 0}
|
||||
Rotate: {x: 0, y: 0, z: 0}
|
||||
Scale: {x: 1, y: 1, z: 1}
|
||||
Scripts: ~
|
||||
- EID: 5
|
||||
Name: item
|
||||
IsActive: true
|
||||
NumberOfChildren: 0
|
||||
Components:
|
||||
Transform Component:
|
||||
Translate: {x: 0, y: -2, z: -5}
|
||||
Rotate: {x: 0, y: 0, z: 0}
|
||||
Scale: {x: 2, y: 2, z: 2}
|
||||
Renderable Component:
|
||||
Mesh: 149697411
|
||||
Material: 126974645
|
||||
RigidBody Component:
|
||||
Type: Dynamic
|
||||
Mass: 1
|
||||
Drag: 0
|
||||
Angular Drag: 0
|
||||
Use Gravity: true
|
||||
Interpolate: false
|
||||
Freeze Position X: false
|
||||
Freeze Position Y: false
|
||||
Freeze Position Z: false
|
||||
Freeze Rotation X: true
|
||||
Freeze Rotation Y: true
|
||||
Freeze Rotation Z: true
|
||||
Collider Component:
|
||||
Colliders:
|
||||
- Is Trigger: false
|
||||
Type: Box
|
||||
Half Extents: {x: 0.0009765625, y: 0.0009765625, z: 0.0009765625}
|
||||
Friction: 0.400000006
|
||||
Bounciness: 0
|
||||
Density: 1
|
||||
Position Offset: {x: 0, y: 0.5, z: 0}
|
||||
- Is Trigger: true
|
||||
Type: Box
|
||||
Half Extents: {x: 0.001953125, y: 0.001953125, z: 0.001953125}
|
||||
Friction: 0.400000006
|
||||
Bounciness: 0
|
||||
Density: 1
|
||||
Position Offset: {x: 0, y: 0.5, z: 0}
|
||||
Scripts: ~
|
||||
- EID: 6
|
||||
Name: AI
|
||||
IsActive: true
|
||||
NumberOfChildren: 0
|
||||
Components:
|
||||
Transform Component:
|
||||
Translate: {x: -8, y: -2, z: 2.5}
|
||||
Rotate: {x: 0, y: 0, z: 0}
|
||||
Scale: {x: 2, y: 2, z: 2}
|
||||
Renderable Component:
|
||||
Mesh: 149697411
|
||||
Material: 126974645
|
||||
RigidBody Component:
|
||||
Type: Dynamic
|
||||
Mass: 1
|
||||
Drag: 0
|
||||
Angular Drag: 0
|
||||
Use Gravity: true
|
||||
Interpolate: false
|
||||
Freeze Position X: false
|
||||
Freeze Position Y: false
|
||||
Freeze Position Z: false
|
||||
Freeze Rotation X: true
|
||||
Freeze Rotation Y: true
|
||||
Freeze Rotation Z: true
|
||||
Collider Component:
|
||||
Colliders:
|
||||
- Is Trigger: false
|
||||
Type: Box
|
||||
Half Extents: {x: 0.0009765625, y: 0.0009765625, z: 0.0009765625}
|
||||
Friction: 0.400000006
|
||||
Bounciness: 0
|
||||
Density: 1
|
||||
Position Offset: {x: 0, y: 0.5, z: 0}
|
||||
Scripts: ~
|
||||
- EID: 7
|
||||
Name: Default
|
||||
IsActive: true
|
||||
NumberOfChildren: 0
|
||||
Components:
|
||||
Transform Component:
|
||||
Translate: {x: 3, y: -1, z: -1}
|
||||
Rotate: {x: 0, y: 0, z: 0}
|
||||
Scale: {x: 5, y: 5, z: 5}
|
||||
Renderable Component:
|
||||
Mesh: 149697411
|
||||
Material: 126974645
|
||||
Scripts: ~
|
||||
- EID: 8
|
||||
Name: Default
|
||||
IsActive: true
|
||||
NumberOfChildren: 0
|
||||
Components:
|
||||
Light Component:
|
||||
Position: {x: 0, y: 0, z: 0}
|
||||
Type: Ambient
|
||||
Direction: {x: 0, y: 0, z: 1}
|
||||
Color: {x: 1, y: 1, z: 1, w: 1}
|
||||
Layer: 4294967295
|
||||
Strength: 0.25
|
||||
Scripts: ~
|
|
@ -0,0 +1,3 @@
|
|||
Name: M2Scene
|
||||
ID: 94283040
|
||||
Type: 5
|
|
@ -41,6 +41,8 @@
|
|||
|
||||
|
||||
#include "Assets/SHAssetManager.h"
|
||||
#include "Scenes/SBMainScene.h"
|
||||
#include "Serialization/Configurations/SHConfigurationManager.h"
|
||||
|
||||
#include "Tools/SHLogger.h"
|
||||
#include "Tools/SHDebugDraw.h"
|
||||
|
@ -60,8 +62,9 @@ namespace Sandbox
|
|||
{
|
||||
// Set working directory
|
||||
SHFileUtilities::SetWorkDirToExecDir();
|
||||
|
||||
window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
|
||||
WindowData wndData{};
|
||||
auto& appConfig = SHConfigurationManager::LoadApplicationConfig(&wndData);
|
||||
window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow, wndData);
|
||||
|
||||
// Create Systems
|
||||
SHSystemManager::CreateSystem<SHGraphicsSystem>();
|
||||
|
@ -80,7 +83,11 @@ namespace Sandbox
|
|||
SDL_Init(SDL_INIT_VIDEO);
|
||||
sdlWindow = SDL_CreateWindowFrom(window.GetHWND());
|
||||
SHSystemManager::CreateSystem<SHEditor>();
|
||||
SHSystemManager::GetSystem<SHEditor>()->SetSDLWindow(sdlWindow);
|
||||
if(auto editor = SHSystemManager::GetSystem<SHEditor>())
|
||||
{
|
||||
editor->SetSDLWindow(sdlWindow);
|
||||
editor->SetSHWindow(&window);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Create Routines
|
||||
|
@ -128,7 +135,7 @@ namespace Sandbox
|
|||
|
||||
SHSystemManager::Init();
|
||||
|
||||
SHSceneManager::InitSceneManager<SBTestScene>("TestScene");
|
||||
SHSceneManager::InitSceneManager<SBMainScene>(appConfig.startingSceneID);
|
||||
|
||||
SHFrameRateController::UpdateFRC();
|
||||
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
#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()
|
||||
{
|
||||
sceneName = SHSerialization::DeserializeSceneFromFile(sceneAssetID);
|
||||
}
|
||||
|
||||
void SBMainScene::Update(float dt)
|
||||
{
|
||||
}
|
||||
|
||||
void SBMainScene::Render()
|
||||
{
|
||||
}
|
||||
|
||||
void SBMainScene::Unload()
|
||||
{
|
||||
}
|
||||
|
||||
void SBMainScene::Free()
|
||||
{
|
||||
//SHSerialization::SerializeScene("resources/scenes/Scene01.SHADE");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
#pragma once
|
||||
|
||||
#include "Scene/SHScene.h"
|
||||
#include "Scene/SHSceneManager.h"
|
||||
|
||||
namespace Sandbox
|
||||
{
|
||||
class SBMainScene : public SHADE::SHScene
|
||||
{
|
||||
private:
|
||||
EntityID camera;
|
||||
EntityID testObj;
|
||||
std::vector<EntityID> stressTestObjects;
|
||||
|
||||
public:
|
||||
virtual void Load();
|
||||
virtual void Init();
|
||||
virtual void Update(float dt);
|
||||
virtual void Render();
|
||||
virtual void Free();
|
||||
virtual void Unload();
|
||||
|
||||
//TODO: Change to new window DO IT IN CPP TOO
|
||||
void WindowFocusFunc(void* window, int focused);
|
||||
|
||||
SBMainScene(void) = default;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -189,12 +189,17 @@ namespace SHADE
|
|||
switch (file.assetMeta->type)
|
||||
{
|
||||
case AssetType::INVALID: break;
|
||||
case AssetType::SHADER: icon = ICON_FA_FILE_CODE; break;
|
||||
case AssetType::SHADER_BUILT_IN: icon = ICON_FA_FILE_CODE; break;
|
||||
case AssetType::TEXTURE: icon = ICON_FA_IMAGES; break;
|
||||
case AssetType::MESH: icon = ICON_FA_CUBES; break;
|
||||
case AssetType::SCENE: icon = ICON_MD_IMAGE; break;
|
||||
case AssetType::PREFAB: icon = ICON_FA_BOX_OPEN; break;
|
||||
case AssetType::SHADER: break;
|
||||
case AssetType::SHADER_BUILT_IN: break;
|
||||
case AssetType::TEXTURE: break;
|
||||
case AssetType::MESH: break;
|
||||
case AssetType::SCENE:
|
||||
if(auto editor = SHSystemManager::GetSystem<SHEditor>())
|
||||
{
|
||||
editor->LoadScene(file.assetMeta->id);
|
||||
}
|
||||
break;
|
||||
case AssetType::PREFAB: break;
|
||||
case AssetType::MATERIAL:
|
||||
if (auto matInspector = SHEditorWindowManager::GetEditorWindow<SHMaterialInspector>())
|
||||
{
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
#include "Assets/SHAssetManager.h"
|
||||
#include "Editor/IconsMaterialDesign.h"
|
||||
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
||||
#include "Editor/SHEditorWidgets.hpp"
|
||||
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
||||
#include "Resource/SHResourceManager.h"
|
||||
|
||||
namespace SHADE
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
//#==============================================================#
|
||||
//|| SHADE Includes ||
|
||||
//#==============================================================#
|
||||
#include "Editor/SHEditorWidgets.hpp"
|
||||
#include "Editor/SHEditor.h"
|
||||
#include "SHEditorMenuBar.h"
|
||||
#include "Editor/IconsMaterialDesign.h"
|
||||
|
@ -17,7 +18,11 @@
|
|||
#include <imgui_internal.h>
|
||||
#include <rttr/type>
|
||||
|
||||
#include "Assets/SHAssetManager.h"
|
||||
#include "Assets/Asset Types/SHSceneAsset.h"
|
||||
#include "Scene/SHSceneManager.h"
|
||||
#include "Serialization/SHSerialization.h"
|
||||
#include "Serialization/Configurations/SHConfigurationManager.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -75,13 +80,17 @@ namespace SHADE
|
|||
{
|
||||
if (ImGui::BeginMenu("File"))
|
||||
{
|
||||
if(ImGui::Selectable("New Scene"))
|
||||
{
|
||||
SHSystemManager::GetSystem<SHEditor>()->NewScene();
|
||||
}
|
||||
if(ImGui::Selectable("Save"))
|
||||
{
|
||||
SHSerialization::SerializeSceneToFile("../../Assets/Scenes/Test.SHADE");
|
||||
SHSystemManager::GetSystem<SHEditor>()->SaveScene();
|
||||
}
|
||||
if(ImGui::Selectable("Load"))
|
||||
{
|
||||
SHSerialization::DeserializeSceneFromFile("../../Assets/Scenes/Test.SHADE");
|
||||
//SHSystemManager::GetSystem<SHEditor>()->LoadScene()
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
@ -155,6 +164,35 @@ namespace SHADE
|
|||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Application Config"))
|
||||
{
|
||||
auto& appConfig = SHConfigurationManager::applicationConfig;
|
||||
ImGui::InputText("Window Title", &appConfig.windowTitle);
|
||||
ImGui::Checkbox("Start in Fullscreen", &appConfig.startInFullScreen);
|
||||
SHEditorWidgets::DragN<float, 2>("Window Size", { "Width", "Height" }, { &appConfig.windowSize.x, &appConfig.windowSize.y });
|
||||
//ImGui::InputScalar("Starting Scene", ImGuiDataType_U32, &appConfig.startingSceneID);
|
||||
auto sceneAsset = SHAssetManager::GetData<SHSceneAsset>(appConfig.startingSceneID);
|
||||
|
||||
if(ImGui::BeginCombo("Starting Scne", sceneAsset ? sceneAsset->name.data() : ""))
|
||||
{
|
||||
auto scenes = SHAssetManager::GetAllRecordOfType(AssetType::SCENE);
|
||||
for(auto const& scene : scenes)
|
||||
{
|
||||
if(ImGui::Selectable(scene.name.data()))
|
||||
{
|
||||
appConfig.startingSceneID = scene.id;
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
if (ImGui::Button("Save"))
|
||||
{
|
||||
SHConfigurationManager::SaveApplicationConfig();
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
ImGui::EndMainMenuBar();
|
||||
}
|
||||
|
||||
|
@ -175,13 +213,16 @@ namespace SHADE
|
|||
ImGui::BeginDisabled(editor->editorState == SHEditor::State::PLAY);
|
||||
if(ImGui::SmallButton(ICON_MD_PLAY_ARROW))
|
||||
{
|
||||
const SHEditorStateChangeEvent STATE_CHANGE_EVENT
|
||||
if(editor->SaveScene())
|
||||
{
|
||||
.previousState = editor->editorState
|
||||
};
|
||||
editor->editorState = SHEditor::State::PLAY;
|
||||
const SHEditorStateChangeEvent STATE_CHANGE_EVENT
|
||||
{
|
||||
.previousState = editor->editorState
|
||||
};
|
||||
editor->editorState = SHEditor::State::PLAY;
|
||||
|
||||
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_PLAY_EVENT);
|
||||
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_PLAY_EVENT);
|
||||
}
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
ImGui::BeginDisabled(editor->editorState == SHEditor::State::PAUSE);
|
||||
|
@ -206,6 +247,7 @@ namespace SHADE
|
|||
editor->editorState = SHEditor::State::STOP;
|
||||
|
||||
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_STOP_EVENT);
|
||||
editor->LoadScene(SHSceneManager::GetCurrentSceneAssetID());
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
ImGui::EndMenuBar();
|
||||
|
|
|
@ -45,7 +45,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"
|
||||
#include "Tools/SHDebugDraw.h"
|
||||
|
||||
RTTR_REGISTRATION
|
||||
|
@ -147,7 +151,9 @@ namespace SHADE
|
|||
window->Update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RenderSceneNamePrompt();
|
||||
RenderUnsavedChangesPrompt();
|
||||
//PollPicking();
|
||||
|
||||
if(ImGui::IsKeyDown(ImGuiKey_LeftShift) && ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_Z))
|
||||
|
@ -172,6 +178,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))
|
||||
|
@ -470,6 +530,66 @@ namespace SHADE
|
|||
}
|
||||
}
|
||||
|
||||
void SHEditor::NewScene()
|
||||
{
|
||||
if(shWindow->IsUnsavedChanges())
|
||||
{
|
||||
//Unsaved changes prompt
|
||||
sceneToLoad = 0;
|
||||
isUnsavedChangesPromptOpen = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
SHSceneManager::RestartScene(0);
|
||||
shWindow->ToggleUnsavedChanges();
|
||||
}
|
||||
}
|
||||
|
||||
bool 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 false;
|
||||
}
|
||||
//Else We have a new name
|
||||
|
||||
SHSceneManager::SetCurrentSceneName(newSceneName);
|
||||
SHSceneManager::SetCurrentSceneAssetID(SHAssetManager::CreateNewAsset(AssetType::SCENE, newSceneName));
|
||||
}
|
||||
//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
|
||||
if(SHSerialization::SerializeSceneToFile(SHSceneManager::GetCurrentSceneAssetID()))
|
||||
{
|
||||
if(shWindow->IsUnsavedChanges())
|
||||
shWindow->ToggleUnsavedChanges();
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SHEditor::LoadScene(AssetID const& assetID) noexcept
|
||||
{
|
||||
if(shWindow->IsUnsavedChanges())
|
||||
{
|
||||
//Unsaved changes prompt
|
||||
isUnsavedChangesPromptOpen = true;
|
||||
sceneToLoad = assetID;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Load the scene
|
||||
sceneToLoad = 0;
|
||||
SHSceneManager::RestartScene(assetID);
|
||||
}
|
||||
}
|
||||
|
||||
void SHEditor::NewFrame()
|
||||
{
|
||||
SDL_Event event;
|
||||
|
|
|
@ -16,15 +16,18 @@
|
|||
#include "Resource/SHHandle.h"
|
||||
#include "EditorWindow/SHEditorWindow.h"
|
||||
#include "Tools/SHLog.h"
|
||||
#include "Gizmos/SHTransformGizmo.h"`
|
||||
#include "Gizmos/SHTransformGizmo.h"
|
||||
#include "Events/SHEventDefines.h"
|
||||
#include "Events/SHEvent.h"
|
||||
#include "Graphics/Windowing/SHWindow.h"
|
||||
|
||||
//#==============================================================#
|
||||
//|| Library Includes ||
|
||||
//#==============================================================#
|
||||
#include <SDL_video.h>
|
||||
|
||||
#include "Assets/SHAssetMacros.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
//#==============================================================#
|
||||
|
@ -171,9 +174,16 @@ namespace SHADE
|
|||
void InitBackend();
|
||||
|
||||
void SetSDLWindow(SDL_Window* inSDLWindow){sdlWindow = inSDLWindow;};
|
||||
void SetSHWindow(SHWindow* inWindow){shWindow = inWindow;}
|
||||
|
||||
void PollPicking();
|
||||
|
||||
void NewScene();
|
||||
|
||||
bool SaveScene(std::string const& newSceneName = {});
|
||||
|
||||
void LoadScene(AssetID const& assetID) noexcept;
|
||||
|
||||
// List of selected entities
|
||||
std::vector<EntityID> selectedEntities;
|
||||
|
||||
|
@ -191,6 +201,10 @@ namespace SHADE
|
|||
*/
|
||||
void Render();
|
||||
|
||||
void RenderSceneNamePrompt() noexcept;
|
||||
|
||||
void RenderUnsavedChangesPrompt() noexcept;
|
||||
|
||||
void InitLayout() noexcept;
|
||||
|
||||
void InitFonts() noexcept;
|
||||
|
@ -199,12 +213,22 @@ namespace SHADE
|
|||
|
||||
SHEventHandle onEditorStateChanged(SHEventPtr eventPtr);
|
||||
|
||||
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
|
||||
Handle<SHVkCommandBuffer> imguiCommandBuffer;
|
||||
|
||||
SDL_Window* sdlWindow {nullptr};
|
||||
SHWindow* shWindow {nullptr};
|
||||
|
||||
ImGuiIO* io{nullptr};
|
||||
|
||||
|
|
|
@ -88,6 +88,7 @@ namespace SHADE
|
|||
/* Getter Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
Handle<SHVkPipeline> GetPipeline() const noexcept { return pipeline; };
|
||||
bool IsEmpty() const noexcept { return subBatches.empty(); }
|
||||
|
||||
private:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
|
|
@ -68,6 +68,10 @@ namespace SHADE
|
|||
return;
|
||||
|
||||
batch->Remove(renderable);
|
||||
|
||||
// If batch is empty, remove batch
|
||||
if (batch->IsEmpty())
|
||||
batches.erase(batch);
|
||||
}
|
||||
|
||||
void SHSuperBatch::Clear() noexcept
|
||||
|
|
|
@ -270,7 +270,15 @@ namespace SHADE
|
|||
worldRenderer->SetCameraDirector(cameraSystem->CreateDirector());
|
||||
|
||||
// Create default materials
|
||||
std::array<SHTexture::PixelChannel, 4> defaultTexture = { 255, 255, 255, 255 };
|
||||
std::vector<uint32_t> mipOffsets{};
|
||||
mipOffsets.push_back(0);
|
||||
auto tex = AddTexture(4, defaultTexture.data(), 1, 1, SHTexture::TextureFormat::eR8G8B8A8Unorm, mipOffsets);
|
||||
BuildTextures();
|
||||
|
||||
defaultMaterial = AddMaterial(defaultVertShader, defaultFragShader, gBufferSubpass);
|
||||
defaultMaterial->SetProperty("data.textureIndex", tex->TextureArrayIndex);
|
||||
|
||||
|
||||
// Create debug draw pipeline
|
||||
debugDrawPipeline = createDebugDrawPipeline(debugDrawNode->GetRenderpass(), debugDrawSubpass);
|
||||
|
@ -764,6 +772,7 @@ namespace SHADE
|
|||
|
||||
void SHGraphicsSystem::BeginRoutine::Execute(double) noexcept
|
||||
{
|
||||
SHResourceManager::FinaliseChanges();
|
||||
reinterpret_cast<SHGraphicsSystem*>(system)->BeginRender();
|
||||
}
|
||||
|
||||
|
@ -789,7 +798,6 @@ namespace SHADE
|
|||
void SHGraphicsSystem::EndRoutine::Execute(double) noexcept
|
||||
{
|
||||
reinterpret_cast<SHGraphicsSystem*>(system)->EndRender();
|
||||
SHResourceManager::FinaliseChanges();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -806,11 +814,6 @@ namespace SHADE
|
|||
{
|
||||
if (!renderable.HasChanged())
|
||||
continue;
|
||||
|
||||
if (!renderable.GetMesh())
|
||||
{
|
||||
SHLOG_CRITICAL("NULL Mesh provided!");
|
||||
}
|
||||
|
||||
// Remove from the SuperBatch it is previously in (prevMat if mat has changed)
|
||||
Handle<SHMaterialInstance> prevMaterial = renderable.HasMaterialChanged() ? renderable.GetPrevMaterial() : renderable.GetMaterial();
|
||||
|
@ -821,8 +824,9 @@ namespace SHADE
|
|||
}
|
||||
|
||||
// Add to new SuperBatch if there is a material
|
||||
// Add to new SuperBatch if there is a material and a mesh to render
|
||||
Handle<SHMaterialInstance> newMatInstance = renderable.GetMaterial();
|
||||
if (newMatInstance)
|
||||
if (newMatInstance && renderable.GetMesh())
|
||||
{
|
||||
Handle<SHSuperBatch> newSuperBatch = newMatInstance->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpass()->GetSuperBatch();
|
||||
newSuperBatch->Add(&renderable);
|
||||
|
|
|
@ -156,14 +156,15 @@ namespace SHADE
|
|||
/* Build Descriptor Set with all the Textures only if there are textures */
|
||||
if (!texOrder.empty())
|
||||
{
|
||||
if (!texDescriptors)
|
||||
if (texDescriptors)
|
||||
{
|
||||
texDescriptors = descPool->Allocate
|
||||
(
|
||||
{ SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS] },
|
||||
{ static_cast<uint32_t>(texOrder.size()) }
|
||||
);
|
||||
texDescriptors.Free();
|
||||
}
|
||||
texDescriptors = descPool->Allocate
|
||||
(
|
||||
{ SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS] },
|
||||
{ static_cast<uint32_t>(texOrder.size()) }
|
||||
);
|
||||
texDescriptors->ModifyWriteDescImage
|
||||
(
|
||||
SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS,
|
||||
|
|
|
@ -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
|
||||
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);
|
||||
|
|
|
@ -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;
|
||||
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();
|
||||
|
|
|
@ -24,7 +24,7 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include "Graphics/Shaders/SHVkShaderModule.h"
|
||||
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
||||
#include "Serialization/SHSerializationHelper.hpp"
|
||||
#include "Serialization/SHYAMLConverters.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -282,6 +282,9 @@ namespace SHADE
|
|||
case SHADE::SHShaderBlockInterface::Variable::Type::INT:
|
||||
{
|
||||
Handle<SHTexture> texture = LoadOrGet<SHTexture>(PROP_NODE.as<int>());
|
||||
// HACK: Need to split this out to a separate pass before loading the materials and subsequently, the scenes
|
||||
gfxSystem->BuildTextures();
|
||||
|
||||
if (texture)
|
||||
{
|
||||
matHandle->SetProperty(VARIABLE->offset, texture->TextureArrayIndex);
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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,16 +107,18 @@ 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;
|
||||
//cleanReload = true;
|
||||
cleanReload = false;
|
||||
//newSceneName = sceneName;
|
||||
}
|
||||
else
|
||||
cleanReload = false;
|
||||
|
||||
currentScene->sceneAssetID = assetID;
|
||||
nextSceneID = currentSceneID;
|
||||
sceneChanged = true;
|
||||
}
|
||||
|
@ -151,4 +153,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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
||||
|
||||
};
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
#include "SHpch.h"
|
||||
|
||||
#include <yaml-cpp/yaml.h>
|
||||
#include "SHSerializationHelper.hpp"
|
||||
#include "SHSerialization.h"
|
||||
#include "SHSerializationHelper.hpp"
|
||||
|
||||
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||
#include "Scene/SHSceneManager.h"
|
||||
|
@ -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"
|
||||
|
@ -17,19 +18,23 @@
|
|||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
#include "Graphics/MiddleEnd/Lights/SHLightComponent.h"
|
||||
#include "Scripting/SHScriptEngine.h"
|
||||
#include "Tools/FileIO/SHFileIO.h"
|
||||
|
||||
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 +96,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,15 +116,24 @@ namespace SHADE
|
|||
if (createdEntities.empty())
|
||||
{
|
||||
SHLOG_ERROR("Failed to create entities from deserializaiton")
|
||||
return;
|
||||
return NewSceneName.data();
|
||||
}
|
||||
//Initialize Entity
|
||||
auto entityVecIt = createdEntities.begin();
|
||||
AssetQueue assetQueue;
|
||||
for (auto it = entities.begin(); it != entities.end(); ++it)
|
||||
{
|
||||
SHSerializationHelper::FetchAssetsFromComponent<SHRenderable>((*it)[ComponentsNode], *entityVecIt, assetQueue);
|
||||
}
|
||||
LoadAssetsFromAssetQueue(assetQueue);
|
||||
//Initialize Entity
|
||||
entityVecIt = createdEntities.begin();
|
||||
for (auto it = entities.begin(); it != entities.end(); ++it)
|
||||
{
|
||||
InitializeEntity(*it, *entityVecIt++);
|
||||
}
|
||||
}
|
||||
|
||||
return assetData->name;
|
||||
}
|
||||
|
||||
void SHSerialization::EmitEntity(SHSceneNode* entityNode, YAML::Emitter& out)
|
||||
{
|
||||
|
@ -264,6 +263,33 @@ namespace SHADE
|
|||
return componentIDList;
|
||||
}
|
||||
|
||||
void SHSerialization::LoadAssetsFromAssetQueue(AssetQueue& assetQueue)
|
||||
{
|
||||
for (auto& [assetId, assetType] : assetQueue)
|
||||
{
|
||||
switch(assetType)
|
||||
{
|
||||
case AssetType::INVALID: break;
|
||||
case AssetType::SHADER: break;
|
||||
case AssetType::SHADER_BUILT_IN: break;
|
||||
case AssetType::TEXTURE:
|
||||
SHResourceManager::LoadOrGet<SHTexture>(assetId);
|
||||
break;
|
||||
case AssetType::MESH:
|
||||
SHResourceManager::LoadOrGet<SHMesh>(assetId);
|
||||
break;
|
||||
case AssetType::SCENE: break;
|
||||
case AssetType::PREFAB: break;
|
||||
case AssetType::MATERIAL:
|
||||
SHResourceManager::LoadOrGet<SHMaterial>(assetId);
|
||||
break;
|
||||
case AssetType::MAX_COUNT: break;
|
||||
default: ;
|
||||
}
|
||||
}
|
||||
SHResourceManager::FinaliseChanges();
|
||||
}
|
||||
|
||||
void SHSerialization::InitializeEntity(YAML::Node const& entityNode, EntityID const& eid)
|
||||
{
|
||||
auto const componentsNode = entityNode[ComponentsNode];
|
||||
|
|
|
@ -4,7 +4,10 @@
|
|||
#include <string>
|
||||
#include <filesystem>
|
||||
|
||||
#include <ECS_Base/Components/SHComponent.h>
|
||||
|
||||
#include "ECS_Base/SHECSMacros.h"
|
||||
#include <Assets/SHAssetMacros.h>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
|
@ -25,12 +28,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);
|
||||
|
@ -42,7 +44,11 @@ namespace SHADE
|
|||
static EntityID DeserializeEntitiesFromString(std::string const& data, EntityID const& parentEID = MAX_EID) noexcept;
|
||||
|
||||
static std::vector<ComponentTypeID> GetComponentIDList(YAML::Node const& componentsNode);
|
||||
|
||||
static void LoadAssetsFromAssetQueue(std::unordered_map<AssetID, AssetType>& assetQueue);
|
||||
private:
|
||||
static void InitializeEntity(YAML::Node const& entityNode, EntityID const& eid);
|
||||
|
||||
static constexpr std::string_view NewSceneName = "New Scene";
|
||||
};
|
||||
}
|
|
@ -1,329 +1,20 @@
|
|||
#pragma once
|
||||
|
||||
#include "SHYAMLConverters.h"
|
||||
#include <yaml-cpp/yaml.h>
|
||||
#include "ECS_Base/Components/SHComponent.h"
|
||||
|
||||
#include <rttr/registration>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||
#include "Math/Vector/SHVec2.h"
|
||||
#include "Math/Vector/SHVec3.h"
|
||||
#include "Math/Vector/SHVec4.h"
|
||||
#include "Resource/SHResourceManager.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHMaterial.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
|
||||
#include "SHSerializationTools.h"
|
||||
#include "Physics/Components/SHColliderComponent.h"
|
||||
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
||||
#include "Tools/SHLog.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
using namespace SHADE;
|
||||
|
||||
template<>
|
||||
struct convert<SHVec4>
|
||||
{
|
||||
static constexpr const char* x = "x";
|
||||
static constexpr const char* y = "y";
|
||||
static constexpr const char* z = "z";
|
||||
static constexpr const char* w = "w";
|
||||
|
||||
static Node encode(SHVec4 const& rhs)
|
||||
{
|
||||
Node node;
|
||||
node.SetStyle(EmitterStyle::Flow);
|
||||
node[x] = rhs.x;
|
||||
node[y] = rhs.y;
|
||||
node[z] = rhs.z;
|
||||
node[w] = rhs.w;
|
||||
return node;
|
||||
}
|
||||
static bool decode(Node const& node, SHVec4& rhs)
|
||||
{
|
||||
if (node[x].IsDefined())
|
||||
rhs.x = node[x].as<float>();
|
||||
if (node[y].IsDefined())
|
||||
rhs.y = node[y].as<float>();
|
||||
if (node[z].IsDefined())
|
||||
rhs.z = node[z].as<float>();
|
||||
if (node[w].IsDefined())
|
||||
rhs.w = node[w].as<float>();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct convert<SHVec3>
|
||||
{
|
||||
static constexpr const char* x = "x";
|
||||
static constexpr const char* y = "y";
|
||||
static constexpr const char* z = "z";
|
||||
|
||||
static Node encode(SHVec3 const& rhs)
|
||||
{
|
||||
Node node;
|
||||
node.SetStyle(EmitterStyle::Flow);
|
||||
node[x] = rhs.x;
|
||||
node[y] = rhs.y;
|
||||
node[z] = rhs.z;
|
||||
return node;
|
||||
}
|
||||
static bool decode(Node const& node, SHVec3& rhs)
|
||||
{
|
||||
if (node[x].IsDefined())
|
||||
rhs.x = node[x].as<float>();
|
||||
if (node[y].IsDefined())
|
||||
rhs.y = node[y].as<float>();
|
||||
if (node[z].IsDefined())
|
||||
rhs.z = node[z].as<float>();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct convert<SHVec2>
|
||||
{
|
||||
static constexpr const char* x = "x";
|
||||
static constexpr const char* y = "y";
|
||||
|
||||
static Node encode(SHVec2 const& rhs)
|
||||
{
|
||||
Node node;
|
||||
node.SetStyle(EmitterStyle::Flow);
|
||||
node[x] = rhs.x;
|
||||
node[y] = rhs.y;
|
||||
return node;
|
||||
}
|
||||
static bool decode(Node const& node, SHVec2& rhs)
|
||||
{
|
||||
if (node[x].IsDefined())
|
||||
rhs.x = node[x].as<float>();
|
||||
if (node[y].IsDefined())
|
||||
rhs.y = node[y].as<float>();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct convert<SHCollider>
|
||||
{
|
||||
static constexpr const char* IsTrigger = "Is Trigger";
|
||||
|
||||
static constexpr const char* Type = "Type";
|
||||
static constexpr const char* HalfExtents = "Half Extents";
|
||||
static constexpr const char* Radius = "Radius";
|
||||
|
||||
static constexpr const char* Friction = "Friction";
|
||||
static constexpr const char* Bounciness = "Bounciness";
|
||||
static constexpr const char* Density = "Density";
|
||||
static constexpr const char* PositionOffset = "Position Offset";
|
||||
|
||||
static Node encode(SHCollider& rhs)
|
||||
{
|
||||
Node node;
|
||||
|
||||
node[IsTrigger] = rhs.IsTrigger();
|
||||
|
||||
rttr::type const shapeRttrType = rttr::type::get<SHCollider::Type>();
|
||||
rttr::enumeration const enumAlign = shapeRttrType.get_enumeration();
|
||||
SHCollider::Type colliderType = rhs.GetType();
|
||||
|
||||
node[Type] = enumAlign.value_to_name(colliderType).data();
|
||||
|
||||
switch (colliderType)
|
||||
{
|
||||
case SHCollider::Type::BOX:
|
||||
{
|
||||
auto const bb = reinterpret_cast<SHBoundingBox*>(rhs.GetShape());
|
||||
node[HalfExtents] = bb->GetHalfExtents();
|
||||
}
|
||||
break;
|
||||
case SHCollider::Type::SPHERE:
|
||||
{
|
||||
auto const bs = reinterpret_cast<SHBoundingSphere*>(rhs.GetShape());
|
||||
node[Radius] = bs->GetRadius();
|
||||
}
|
||||
break;
|
||||
case SHCollider::Type::CAPSULE: break;
|
||||
default:;
|
||||
}
|
||||
|
||||
node[Friction] = rhs.GetFriction();
|
||||
node[Bounciness] = rhs.GetBounciness();
|
||||
node[Density] = rhs.GetDensity();
|
||||
node[PositionOffset] = rhs.GetPositionOffset();
|
||||
|
||||
return node;
|
||||
}
|
||||
static bool decode(Node const& node, SHCollider& rhs)
|
||||
{
|
||||
if (node[IsTrigger].IsDefined())
|
||||
rhs.SetIsTrigger(node[IsTrigger].as<bool>());
|
||||
if (!node[Type].IsDefined())
|
||||
return false;
|
||||
rttr::type const shapeRttrType = rttr::type::get<SHCollider::Type>();
|
||||
rttr::enumeration const enumAlign = shapeRttrType.get_enumeration();
|
||||
bool ok;
|
||||
const SHCollider::Type colliderType = enumAlign.name_to_value(node[Type].as<std::string>()).convert<SHCollider::Type>(&ok);
|
||||
if (!ok)
|
||||
return false;
|
||||
switch (colliderType)
|
||||
{
|
||||
case SHCollider::Type::BOX:
|
||||
{
|
||||
if (node[HalfExtents].IsDefined())
|
||||
rhs.SetBoundingBox(node[HalfExtents].as<SHVec3>());
|
||||
}
|
||||
break;
|
||||
case SHCollider::Type::SPHERE:
|
||||
{
|
||||
if (node[Radius].IsDefined())
|
||||
rhs.SetBoundingSphere(node[Radius].as<float>());
|
||||
}
|
||||
break;
|
||||
case SHCollider::Type::CAPSULE: break;
|
||||
default:;
|
||||
}
|
||||
if (node[Friction].IsDefined())
|
||||
rhs.SetFriction(node[Friction].as<float>());
|
||||
if (node[Bounciness].IsDefined())
|
||||
rhs.SetBounciness(rhs.GetBounciness());
|
||||
if (node[Density].IsDefined())
|
||||
rhs.SetDensity(node[Density].as<float>());
|
||||
if (node[PositionOffset].IsDefined())
|
||||
rhs.SetPositionOffset(node[PositionOffset].as<SHVec3>());
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct convert<SHColliderComponent>
|
||||
{
|
||||
static constexpr const char* Colliders = "Colliders";
|
||||
static Node encode(SHColliderComponent& rhs)
|
||||
{
|
||||
Node node, collidersNode;
|
||||
auto const& colliders = rhs.GetColliders();
|
||||
int const numColliders = static_cast<int>(colliders.size());
|
||||
for (int i = 0; i < numColliders; ++i)
|
||||
{
|
||||
auto& collider = rhs.GetCollider(i);
|
||||
Node colliderNode = convert<SHCollider>::encode(collider);
|
||||
if (colliderNode.IsDefined())
|
||||
collidersNode[i] = colliderNode;
|
||||
}
|
||||
node[Colliders] = collidersNode;
|
||||
return node;
|
||||
}
|
||||
static bool decode(Node const& node, SHColliderComponent& rhs)
|
||||
{
|
||||
if (node[Colliders].IsDefined())
|
||||
{
|
||||
int numColliders{};
|
||||
for (auto const& colliderNode : node[Colliders])
|
||||
{
|
||||
rttr::type const shapeRttrType = rttr::type::get<SHCollider::Type>();
|
||||
rttr::enumeration const enumAlign = shapeRttrType.get_enumeration();
|
||||
bool ok = false;
|
||||
const SHCollider::Type colliderType = enumAlign.name_to_value(colliderNode[convert<SHCollider>::Type].as<std::string>()).convert<SHCollider::Type>(&ok);
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
switch (colliderType)
|
||||
{
|
||||
case SHCollider::Type::BOX: rhs.AddBoundingBox(); break;
|
||||
case SHCollider::Type::SPHERE: rhs.AddBoundingSphere(); break;
|
||||
case SHCollider::Type::CAPSULE: break;
|
||||
default:;
|
||||
}
|
||||
YAML::convert<SHCollider>::decode(colliderNode, rhs.GetCollider(numColliders++));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct convert<SHMaterialSpec>
|
||||
{
|
||||
static constexpr std::string_view VERT_SHADER_YAML_TAG = "VertexShader";
|
||||
static constexpr std::string_view FRAG_SHADER_YAML_TAG = "FragmentShader";
|
||||
static constexpr std::string_view SUBPASS_YAML_TAG = "SubPass";
|
||||
static constexpr std::string_view PROPS_YAML_TAG = "Properties";
|
||||
|
||||
static YAML::Node encode(SHMaterialSpec const& rhs)
|
||||
{
|
||||
YAML::Node node;
|
||||
node[VERT_SHADER_YAML_TAG.data()] = rhs.vertexShader;
|
||||
node[FRAG_SHADER_YAML_TAG.data()] = rhs.fragShader;
|
||||
node[SUBPASS_YAML_TAG.data()] = rhs.subpassName;
|
||||
node[PROPS_YAML_TAG.data()] = rhs.properties;
|
||||
return node;
|
||||
}
|
||||
|
||||
static bool decode(YAML::Node const& node, SHMaterialSpec& rhs)
|
||||
{
|
||||
// Retrieve Shader Asset IDs
|
||||
if (node[VERT_SHADER_YAML_TAG.data()].IsDefined())
|
||||
rhs.vertexShader = node[VERT_SHADER_YAML_TAG.data()].as<AssetID>();
|
||||
if (node[FRAG_SHADER_YAML_TAG.data()].IsDefined())
|
||||
rhs.fragShader = node[FRAG_SHADER_YAML_TAG.data()].as<AssetID>();
|
||||
|
||||
// Retrieve Subpass
|
||||
if (node[SUBPASS_YAML_TAG.data()].IsDefined())
|
||||
rhs.subpassName = node[SUBPASS_YAML_TAG.data()].as<std::string>();
|
||||
|
||||
// Retrieve
|
||||
if (node[PROPS_YAML_TAG.data()].IsDefined())
|
||||
rhs.properties = node[PROPS_YAML_TAG.data()];
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct convert<SHRenderable>
|
||||
{
|
||||
static constexpr std::string_view MESH_YAML_TAG = "Mesh";
|
||||
static constexpr std::string_view MAT_YAML_TAG = "Material";
|
||||
|
||||
static YAML::Node encode(SHRenderable const& rhs)
|
||||
{
|
||||
YAML::Node node;
|
||||
node[MESH_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHMesh>(rhs.GetMesh()).value_or(0);
|
||||
node[MAT_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHMaterial>(rhs.GetMaterial()->GetBaseMaterial()).value_or(0);
|
||||
return node;
|
||||
}
|
||||
static bool decode(YAML::Node const& node, SHRenderable& rhs)
|
||||
{
|
||||
if (node[MESH_YAML_TAG.data()].IsDefined())
|
||||
{
|
||||
rhs.SetMesh(SHResourceManager::LoadOrGet<SHMesh>(node[MESH_YAML_TAG.data()].as<AssetID>()));
|
||||
}
|
||||
if (node[MAT_YAML_TAG.data()].IsDefined())
|
||||
{
|
||||
// Temporarily, use default material
|
||||
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||
if (!gfxSystem)
|
||||
return false;
|
||||
Handle<SHMaterial> baseMat = SHResourceManager::LoadOrGet<SHMaterial>(node[MAT_YAML_TAG.data()].as<AssetID>());
|
||||
if (!baseMat)
|
||||
{
|
||||
baseMat = gfxSystem->GetDefaultMaterial();
|
||||
SHLog::Warning("[SHSerializationHelper] Unable to load specified material. Falling back to default material.");
|
||||
}
|
||||
rhs.SetMaterial(gfxSystem->AddOrGetBaseMaterialInstance(baseMat));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
using AssetQueue = std::unordered_map<AssetID, AssetType>;
|
||||
struct SHSerializationHelper
|
||||
{
|
||||
|
||||
|
@ -397,6 +88,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();
|
||||
|
@ -432,63 +125,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()]);
|
||||
if(propertyNode[property.get_name().data()].IsDefined())
|
||||
InitializeProperty(object, property, propertyNode[property.get_name().data()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -513,18 +208,73 @@ namespace SHADE
|
|||
}
|
||||
}
|
||||
|
||||
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||
static YAML::Node GetComponentNode(YAML::Node const& componentsNode, EntityID const& eid)
|
||||
{
|
||||
auto component = SHComponentManager::GetComponent_s<ComponentType>(eid);
|
||||
if (componentsNode.IsNull() && !component)
|
||||
return {};
|
||||
auto rttrType = rttr::type::get<ComponentType>();
|
||||
auto componentNode = componentsNode[rttrType.get_name().data()];
|
||||
if (!componentNode.IsDefined())
|
||||
return {};
|
||||
return componentNode;
|
||||
}
|
||||
|
||||
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||
static void ConvertNodeToComponent(YAML::Node const& componentsNode, EntityID const& eid)
|
||||
{
|
||||
auto component = SHComponentManager::GetComponent_s<ComponentType>(eid);
|
||||
if (componentsNode.IsNull() && !component)
|
||||
return;
|
||||
auto rttrType = rttr::type::get<ComponentType>();
|
||||
auto componentNode = componentsNode[rttrType.get_name().data()];
|
||||
if (!componentNode.IsDefined())
|
||||
return;
|
||||
YAML::convert<ComponentType>::decode(componentNode, *component);
|
||||
|
||||
YAML::convert<ComponentType>::decode(GetComponentNode<ComponentType>(componentsNode, eid), *component);
|
||||
}
|
||||
|
||||
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||
static void FetchAssetsFromComponent(YAML::Node const& componentsNode, EntityID const& eid, AssetQueue& assetQueue)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
static void FetchAssetsFromComponent<SHRenderable>(YAML::Node const& componentsNode, EntityID const& eid, AssetQueue& assetQueue)
|
||||
{
|
||||
auto node = GetComponentNode<SHRenderable>(componentsNode, eid);
|
||||
if(!node.IsDefined())
|
||||
return;
|
||||
if (auto const& meshNode = node[YAML::convert<SHRenderable>::MESH_YAML_TAG.data()]; meshNode.IsDefined())
|
||||
{
|
||||
assetQueue.insert({meshNode.as<AssetID>(), AssetType::MESH});
|
||||
//SHResourceManager::LoadOrGet<SHMesh>(node[YAML::convert<SHRenderable>::MESH_YAML_TAG.data()].as<AssetID>());
|
||||
}
|
||||
if (auto const& matNode = node[YAML::convert<SHRenderable>::MAT_YAML_TAG.data()]; matNode.IsDefined())
|
||||
{
|
||||
auto const matAsset = SHAssetManager::GetData<SHMaterialAsset>(matNode.as<AssetID>());
|
||||
if(matAsset)
|
||||
{
|
||||
SHMaterialSpec spec;
|
||||
YAML::convert<SHMaterialSpec>::decode(*YAML::Load(matAsset->data).begin(), spec);
|
||||
if(spec.properties.IsDefined())
|
||||
{
|
||||
auto fragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(spec.fragShader);
|
||||
auto interface = fragShader->GetReflectedData().GetDescriptorBindingInfo().GetShaderBlockInterface(SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA);
|
||||
int const varCount = static_cast<int>(interface->GetVariableCount());
|
||||
|
||||
for (int i = 0; i < varCount; ++i)
|
||||
{
|
||||
auto variable = interface->GetVariable(i);
|
||||
if(variable->type != SHShaderBlockInterface::Variable::Type::INT)
|
||||
continue;
|
||||
const std::string& VAR_NAME = interface->GetVariableName(i);
|
||||
if(VAR_NAME.empty())
|
||||
continue;
|
||||
assetQueue.insert({spec.properties[VAR_NAME.data()].as<AssetID>(), AssetType::TEXTURE});
|
||||
}
|
||||
}
|
||||
}
|
||||
//assetQueue.insert({matNode.as<AssetID>(), AssetType::MATERIAL});
|
||||
//SHResourceManager::LoadOrGet<SHMaterial>(node[YAML::convert<SHRenderable>::MAT_YAML_TAG.data()].as<AssetID>());
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,317 @@
|
|||
#pragma once
|
||||
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
||||
#include "Math/Geometry/SHBoundingBox.h"
|
||||
#include "Math/Geometry/SHBoundingSphere.h"
|
||||
#include "Physics/SHCollider.h"
|
||||
#include "Resource/SHResourceManager.h"
|
||||
#include "Math/Vector/SHVec2.h"
|
||||
#include "Math/Vector/SHVec3.h"
|
||||
#include "Math/Vector/SHVec4.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHMaterial.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
|
||||
#include "SHSerializationTools.h"
|
||||
#include "Physics/Components/SHColliderComponent.h"
|
||||
namespace YAML
|
||||
{
|
||||
using namespace SHADE;
|
||||
|
||||
template<>
|
||||
struct convert<SHVec4>
|
||||
{
|
||||
static constexpr const char* x = "x";
|
||||
static constexpr const char* y = "y";
|
||||
static constexpr const char* z = "z";
|
||||
static constexpr const char* w = "w";
|
||||
|
||||
static Node encode(SHVec4 const& rhs)
|
||||
{
|
||||
Node node;
|
||||
node.SetStyle(EmitterStyle::Flow);
|
||||
node[x] = rhs.x;
|
||||
node[y] = rhs.y;
|
||||
node[z] = rhs.z;
|
||||
node[w] = rhs.w;
|
||||
return node;
|
||||
}
|
||||
static bool decode(Node const& node, SHVec4& rhs)
|
||||
{
|
||||
if (node[x].IsDefined())
|
||||
rhs.x = node[x].as<float>();
|
||||
if (node[y].IsDefined())
|
||||
rhs.y = node[y].as<float>();
|
||||
if (node[z].IsDefined())
|
||||
rhs.z = node[z].as<float>();
|
||||
if (node[w].IsDefined())
|
||||
rhs.w = node[w].as<float>();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct convert<SHVec3>
|
||||
{
|
||||
static constexpr const char* x = "x";
|
||||
static constexpr const char* y = "y";
|
||||
static constexpr const char* z = "z";
|
||||
|
||||
static Node encode(SHVec3 const& rhs)
|
||||
{
|
||||
Node node;
|
||||
node.SetStyle(EmitterStyle::Flow);
|
||||
node[x] = rhs.x;
|
||||
node[y] = rhs.y;
|
||||
node[z] = rhs.z;
|
||||
return node;
|
||||
}
|
||||
static bool decode(Node const& node, SHVec3& rhs)
|
||||
{
|
||||
if (node[x].IsDefined())
|
||||
rhs.x = node[x].as<float>();
|
||||
if (node[y].IsDefined())
|
||||
rhs.y = node[y].as<float>();
|
||||
if (node[z].IsDefined())
|
||||
rhs.z = node[z].as<float>();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct convert<SHVec2>
|
||||
{
|
||||
static constexpr const char* x = "x";
|
||||
static constexpr const char* y = "y";
|
||||
|
||||
static Node encode(SHVec2 const& rhs)
|
||||
{
|
||||
Node node;
|
||||
node.SetStyle(EmitterStyle::Flow);
|
||||
node[x] = rhs.x;
|
||||
node[y] = rhs.y;
|
||||
return node;
|
||||
}
|
||||
static bool decode(Node const& node, SHVec2& rhs)
|
||||
{
|
||||
if (node[x].IsDefined())
|
||||
rhs.x = node[x].as<float>();
|
||||
if (node[y].IsDefined())
|
||||
rhs.y = node[y].as<float>();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct convert<SHCollider>
|
||||
{
|
||||
static constexpr const char* IsTrigger = "Is Trigger";
|
||||
|
||||
static constexpr const char* Type = "Type";
|
||||
static constexpr const char* HalfExtents = "Half Extents";
|
||||
static constexpr const char* Radius = "Radius";
|
||||
|
||||
static constexpr const char* Friction = "Friction";
|
||||
static constexpr const char* Bounciness = "Bounciness";
|
||||
static constexpr const char* Density = "Density";
|
||||
static constexpr const char* PositionOffset = "Position Offset";
|
||||
|
||||
static Node encode(SHCollider& rhs)
|
||||
{
|
||||
Node node;
|
||||
|
||||
node[IsTrigger] = rhs.IsTrigger();
|
||||
|
||||
rttr::type const shapeRttrType = rttr::type::get<SHCollider::Type>();
|
||||
rttr::enumeration const enumAlign = shapeRttrType.get_enumeration();
|
||||
SHCollider::Type colliderType = rhs.GetType();
|
||||
|
||||
node[Type] = enumAlign.value_to_name(colliderType).data();
|
||||
|
||||
switch (colliderType)
|
||||
{
|
||||
case SHCollider::Type::BOX:
|
||||
{
|
||||
auto const bb = reinterpret_cast<SHBoundingBox*>(rhs.GetShape());
|
||||
node[HalfExtents] = bb->GetHalfExtents();
|
||||
}
|
||||
break;
|
||||
case SHCollider::Type::SPHERE:
|
||||
{
|
||||
auto const bs = reinterpret_cast<SHBoundingSphere*>(rhs.GetShape());
|
||||
node[Radius] = bs->GetRadius();
|
||||
}
|
||||
break;
|
||||
case SHCollider::Type::CAPSULE: break;
|
||||
default:;
|
||||
}
|
||||
|
||||
node[Friction] = rhs.GetFriction();
|
||||
node[Bounciness] = rhs.GetBounciness();
|
||||
node[Density] = rhs.GetDensity();
|
||||
node[PositionOffset] = rhs.GetPositionOffset();
|
||||
|
||||
return node;
|
||||
}
|
||||
static bool decode(Node const& node, SHCollider& rhs)
|
||||
{
|
||||
if (node[IsTrigger].IsDefined())
|
||||
rhs.SetIsTrigger(node[IsTrigger].as<bool>());
|
||||
if (!node[Type].IsDefined())
|
||||
return false;
|
||||
rttr::type const shapeRttrType = rttr::type::get<SHCollider::Type>();
|
||||
rttr::enumeration const enumAlign = shapeRttrType.get_enumeration();
|
||||
bool ok;
|
||||
const SHCollider::Type colliderType = enumAlign.name_to_value(node[Type].as<std::string>()).convert<SHCollider::Type>(&ok);
|
||||
if (!ok)
|
||||
return false;
|
||||
switch (colliderType)
|
||||
{
|
||||
case SHCollider::Type::BOX:
|
||||
{
|
||||
if (node[HalfExtents].IsDefined())
|
||||
rhs.SetBoundingBox(node[HalfExtents].as<SHVec3>());
|
||||
}
|
||||
break;
|
||||
case SHCollider::Type::SPHERE:
|
||||
{
|
||||
if (node[Radius].IsDefined())
|
||||
rhs.SetBoundingSphere(node[Radius].as<float>());
|
||||
}
|
||||
break;
|
||||
case SHCollider::Type::CAPSULE: break;
|
||||
default:;
|
||||
}
|
||||
if (node[Friction].IsDefined())
|
||||
rhs.SetFriction(node[Friction].as<float>());
|
||||
if (node[Bounciness].IsDefined())
|
||||
rhs.SetBounciness(rhs.GetBounciness());
|
||||
if (node[Density].IsDefined())
|
||||
rhs.SetDensity(node[Density].as<float>());
|
||||
if (node[PositionOffset].IsDefined())
|
||||
rhs.SetPositionOffset(node[PositionOffset].as<SHVec3>());
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct convert<SHColliderComponent>
|
||||
{
|
||||
static constexpr const char* Colliders = "Colliders";
|
||||
static Node encode(SHColliderComponent& rhs)
|
||||
{
|
||||
Node node, collidersNode;
|
||||
auto const& colliders = rhs.GetColliders();
|
||||
int const numColliders = static_cast<int>(colliders.size());
|
||||
for (int i = 0; i < numColliders; ++i)
|
||||
{
|
||||
auto& collider = rhs.GetCollider(i);
|
||||
Node colliderNode = convert<SHCollider>::encode(collider);
|
||||
if (colliderNode.IsDefined())
|
||||
collidersNode[i] = colliderNode;
|
||||
}
|
||||
node[Colliders] = collidersNode;
|
||||
return node;
|
||||
}
|
||||
static bool decode(Node const& node, SHColliderComponent& rhs)
|
||||
{
|
||||
if (node[Colliders].IsDefined())
|
||||
{
|
||||
int numColliders{};
|
||||
for (auto const& colliderNode : node[Colliders])
|
||||
{
|
||||
rttr::type const shapeRttrType = rttr::type::get<SHCollider::Type>();
|
||||
rttr::enumeration const enumAlign = shapeRttrType.get_enumeration();
|
||||
bool ok = false;
|
||||
const SHCollider::Type colliderType = enumAlign.name_to_value(colliderNode[convert<SHCollider>::Type].as<std::string>()).convert<SHCollider::Type>(&ok);
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
switch (colliderType)
|
||||
{
|
||||
case SHCollider::Type::BOX: rhs.AddBoundingBox(); break;
|
||||
case SHCollider::Type::SPHERE: rhs.AddBoundingSphere(); break;
|
||||
case SHCollider::Type::CAPSULE: break;
|
||||
default:;
|
||||
}
|
||||
YAML::convert<SHCollider>::decode(colliderNode, rhs.GetCollider(numColliders++));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct convert<SHMaterialSpec>
|
||||
{
|
||||
static constexpr std::string_view VERT_SHADER_YAML_TAG = "VertexShader";
|
||||
static constexpr std::string_view FRAG_SHADER_YAML_TAG = "FragmentShader";
|
||||
static constexpr std::string_view SUBPASS_YAML_TAG = "SubPass";
|
||||
static constexpr std::string_view PROPS_YAML_TAG = "Properties";
|
||||
|
||||
static YAML::Node encode(SHMaterialSpec const& rhs)
|
||||
{
|
||||
YAML::Node node;
|
||||
node[VERT_SHADER_YAML_TAG.data()] = rhs.vertexShader;
|
||||
node[FRAG_SHADER_YAML_TAG.data()] = rhs.fragShader;
|
||||
node[SUBPASS_YAML_TAG.data()] = rhs.subpassName;
|
||||
node[PROPS_YAML_TAG.data()] = rhs.properties;
|
||||
return node;
|
||||
}
|
||||
|
||||
static bool decode(YAML::Node const& node, SHMaterialSpec& rhs)
|
||||
{
|
||||
// Retrieve Shader Asset IDs
|
||||
if (node[VERT_SHADER_YAML_TAG.data()].IsDefined())
|
||||
rhs.vertexShader = node[VERT_SHADER_YAML_TAG.data()].as<AssetID>();
|
||||
if (node[FRAG_SHADER_YAML_TAG.data()].IsDefined())
|
||||
rhs.fragShader = node[FRAG_SHADER_YAML_TAG.data()].as<AssetID>();
|
||||
|
||||
// Retrieve Subpass
|
||||
if (node[SUBPASS_YAML_TAG.data()].IsDefined())
|
||||
rhs.subpassName = node[SUBPASS_YAML_TAG.data()].as<std::string>();
|
||||
|
||||
// Retrieve
|
||||
if (node[PROPS_YAML_TAG.data()].IsDefined())
|
||||
rhs.properties = node[PROPS_YAML_TAG.data()];
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct convert<SHRenderable>
|
||||
{
|
||||
static constexpr std::string_view MESH_YAML_TAG = "Mesh";
|
||||
static constexpr std::string_view MAT_YAML_TAG = "Material";
|
||||
|
||||
static YAML::Node encode(SHRenderable const& rhs)
|
||||
{
|
||||
YAML::Node node;
|
||||
node[MESH_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHMesh>(rhs.GetMesh()).value_or(0);
|
||||
node[MAT_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHMaterial>(rhs.GetMaterial()->GetBaseMaterial()).value_or(0);
|
||||
return node;
|
||||
}
|
||||
static bool decode(YAML::Node const& node, SHRenderable& rhs)
|
||||
{
|
||||
if (node[MESH_YAML_TAG.data()].IsDefined())
|
||||
{
|
||||
rhs.SetMesh(SHResourceManager::LoadOrGet<SHMesh>(node[MESH_YAML_TAG.data()].as<AssetID>()));
|
||||
}
|
||||
if (node[MAT_YAML_TAG.data()].IsDefined())
|
||||
{
|
||||
// Temporarily, use default material
|
||||
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||
if (!gfxSystem)
|
||||
return false;
|
||||
Handle<SHMaterial> baseMat = SHResourceManager::LoadOrGet<SHMaterial>(node[MAT_YAML_TAG.data()].as<AssetID>());
|
||||
if (!baseMat)
|
||||
{
|
||||
baseMat = gfxSystem->GetDefaultMaterial();
|
||||
SHLog::Warning("[SHSerializationHelper] Unable to load specified material. Falling back to default material.");
|
||||
}
|
||||
rhs.SetMaterial(gfxSystem->AddOrGetBaseMaterialInstance(baseMat));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
};
|
||||
}
|
|
@ -38,6 +38,7 @@ project "SHADE_Managed"
|
|||
"%{IncludeDir.RTTR}/include",
|
||||
"%{IncludeDir.dotnet}\\include",
|
||||
"%{IncludeDir.reactphysics3d}\\include",
|
||||
"%{IncludeDir.VULKAN}\\include",
|
||||
"%{wks.location}/SHADE_Engine/src"
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue