Merge remote-tracking branch 'origin/main' into SP3-16-Math
This commit is contained in:
commit
b8224771d2
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
|
@ -18,10 +18,11 @@ echo "K - RTTR"
|
||||||
echo "L - yamlcpp"
|
echo "L - yamlcpp"
|
||||||
echo "M - SDL"
|
echo "M - SDL"
|
||||||
echo "N - dotnet"
|
echo "N - dotnet"
|
||||||
|
echo "O - tinyddsloader"
|
||||||
echo ---------------------------------------------------
|
echo ---------------------------------------------------
|
||||||
echo.
|
echo.
|
||||||
|
|
||||||
choice /C ABCDEFGHIJKLMN /T 10 /D A
|
choice /C ABCDEFGHIJKLMNO /T 10 /D A
|
||||||
set _e=%ERRORLEVEL%
|
set _e=%ERRORLEVEL%
|
||||||
|
|
||||||
if %_e%==1 goto VMA
|
if %_e%==1 goto VMA
|
||||||
|
@ -38,6 +39,7 @@ if %_e%==11 goto RTTR
|
||||||
if %_e%==12 goto yamlcpp
|
if %_e%==12 goto yamlcpp
|
||||||
if %_e%==13 goto SDL
|
if %_e%==13 goto SDL
|
||||||
if %_e%==14 goto dotnet
|
if %_e%==14 goto dotnet
|
||||||
|
if %_e%==15 goto tinyddsloader
|
||||||
|
|
||||||
:VMA
|
:VMA
|
||||||
echo -----------------------VMA----------------------------
|
echo -----------------------VMA----------------------------
|
||||||
|
@ -136,6 +138,13 @@ robocopy "Dependencies/dotnet/tmp/shared/Microsoft.NETCore.App/6.0.8/" "Dependen
|
||||||
rmdir "Dependencies/dotnet/tmp/" /s /q
|
rmdir "Dependencies/dotnet/tmp/" /s /q
|
||||||
del "Dependencies/dotnet/dotnet.zip"
|
del "Dependencies/dotnet/dotnet.zip"
|
||||||
powershell -Command "& {Remove-Item "Dependencies/dotnet/dotnet.zip"}"
|
powershell -Command "& {Remove-Item "Dependencies/dotnet/dotnet.zip"}"
|
||||||
|
if %_e%==14 (goto :done) else (goto :tinyddsloader)
|
||||||
|
|
||||||
|
|
||||||
|
:tinyddsloader
|
||||||
|
echo --------------------tinyddsloader-------------------------
|
||||||
|
rmdir "Dependencies/tinyddsloader" /S /Q
|
||||||
|
git clone https://github.com/SHADE-DP/tinyddsloader.git "Dependencies/tinyddsloader"
|
||||||
|
|
||||||
:done
|
:done
|
||||||
echo DONE!
|
echo DONE!
|
||||||
|
|
|
@ -14,3 +14,4 @@ IncludeDir["reactphysics3d"] = "%{wks.location}\\Dependencies\\reactphysics3d"
|
||||||
IncludeDir["SDL"] = "%{wks.location}\\Dependencies\\SDL"
|
IncludeDir["SDL"] = "%{wks.location}\\Dependencies\\SDL"
|
||||||
IncludeDir["VULKAN"] = "$(VULKAN_SDK)"
|
IncludeDir["VULKAN"] = "$(VULKAN_SDK)"
|
||||||
IncludeDir["dotnet"] = "%{wks.location}\\Dependencies\\dotnet"
|
IncludeDir["dotnet"] = "%{wks.location}\\Dependencies\\dotnet"
|
||||||
|
IncludeDir["tinyddsloader"] = "%{wks.location}\\Dependencies\\tinyddsloader"
|
||||||
|
|
|
@ -30,10 +30,12 @@ project "SHADE_Application"
|
||||||
|
|
||||||
externalincludedirs
|
externalincludedirs
|
||||||
{
|
{
|
||||||
"%{IncludeDir.spdlog}/include",
|
"%{IncludeDir.spdlog}/include",
|
||||||
"%{IncludeDir.VULKAN}/include",
|
"%{IncludeDir.VULKAN}/include",
|
||||||
"%{IncludeDir.VMA}/include",
|
"%{IncludeDir.VMA}/include",
|
||||||
"%{IncludeDir.VULKAN}/Source/SPIRV-Reflect"
|
"%{IncludeDir.VULKAN}/Source/SPIRV-Reflect",
|
||||||
|
"%{IncludeDir.RTTR}/include",
|
||||||
|
"%{IncludeDir.tinyddsloader}"
|
||||||
}
|
}
|
||||||
|
|
||||||
externalwarnings "Off"
|
externalwarnings "Off"
|
||||||
|
@ -71,8 +73,12 @@ project "SHADE_Application"
|
||||||
|
|
||||||
filter "configurations:Debug"
|
filter "configurations:Debug"
|
||||||
symbols "On"
|
symbols "On"
|
||||||
defines {"_DEBUG"}
|
defines {"_DEBUG", "SHEDITOR"}
|
||||||
|
|
||||||
filter "configurations:Release"
|
filter "configurations:Release"
|
||||||
|
optimize "On"
|
||||||
|
defines{"_RELEASE", "SHEDITOR"}
|
||||||
|
|
||||||
|
filter "configurations:Publish"
|
||||||
optimize "On"
|
optimize "On"
|
||||||
defines{"_RELEASE"}
|
defines{"_RELEASE"}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
//#define SHEDITOR
|
//#define SHEDITOR
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
#include "Editor/SHEditor.h"
|
#include "Editor/SHEditor.hpp"
|
||||||
//#include "Scenes/SBEditorScene.h"
|
//#include "Scenes/SBEditorScene.h"
|
||||||
#endif // SHEDITOR
|
#endif // SHEDITOR
|
||||||
|
|
||||||
|
@ -28,6 +28,8 @@
|
||||||
#include "Scenes/SBTestScene.h"
|
#include "Scenes/SBTestScene.h"
|
||||||
#include "Math/Transform/SHTransformComponent.h"
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
|
|
||||||
|
#include "Assets/SHAssetManager.h"
|
||||||
|
|
||||||
using namespace SHADE;
|
using namespace SHADE;
|
||||||
|
|
||||||
namespace Sandbox
|
namespace Sandbox
|
||||||
|
@ -44,14 +46,13 @@ namespace Sandbox
|
||||||
// Set working directory
|
// Set working directory
|
||||||
SHADE::SHFileUtilities::SetWorkDirToExecDir();
|
SHADE::SHFileUtilities::SetWorkDirToExecDir();
|
||||||
|
|
||||||
SDL_Init(SDL_INIT_EVERYTHING);
|
|
||||||
window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
|
window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
|
||||||
|
|
||||||
// Create Systems
|
// Create Systems
|
||||||
|
SHADE::SHSystemManager::CreateSystem<SHADE::SHGraphicsSystem>();
|
||||||
SHADE::SHSystemManager::CreateSystem<SHADE::SHScriptEngine>();
|
SHADE::SHSystemManager::CreateSystem<SHADE::SHScriptEngine>();
|
||||||
// TODO(Diren): Create Physics System here
|
// TODO(Diren): Create Physics System here
|
||||||
SHADE::SHSystemManager::CreateSystem<SHADE::SHTransformSystem>();
|
SHADE::SHSystemManager::CreateSystem<SHADE::SHTransformSystem>();
|
||||||
SHADE::SHSystemManager::CreateSystem<SHADE::SHGraphicsSystem>();
|
|
||||||
SHADE::SHGraphicsSystem* graphicsSystem = static_cast<SHADE::SHGraphicsSystem*>(SHADE::SHSystemManager::GetSystem<SHADE::SHGraphicsSystem>());
|
SHADE::SHGraphicsSystem* graphicsSystem = static_cast<SHADE::SHGraphicsSystem*>(SHADE::SHSystemManager::GetSystem<SHADE::SHGraphicsSystem>());
|
||||||
SHADE::SHSystemManager::CreateSystem<SHADE::SHInputManagerSystem>();
|
SHADE::SHSystemManager::CreateSystem<SHADE::SHInputManagerSystem>();
|
||||||
|
|
||||||
|
@ -76,14 +77,19 @@ namespace Sandbox
|
||||||
|
|
||||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHInputManagerSystem, SHADE::SHInputManagerSystem::InputManagerRoutine>();
|
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHInputManagerSystem, SHADE::SHInputManagerSystem::InputManagerRoutine>();
|
||||||
|
|
||||||
|
//TODO: REMOVE AFTER PRESENTATION
|
||||||
|
SHADE::SHAssetManager::LoadDataTemp("../../Assets/racoon.gltf");
|
||||||
|
SHADE::SHAssetManager::LoadDataTemp("../../Assets/RaccoonBag_Color_Ver4.dds");
|
||||||
|
SHADE::SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.dds");
|
||||||
|
//TODO: REMOVE AFTER PRESENTATION
|
||||||
|
|
||||||
// Set up graphics system and windows
|
// Set up graphics system and windows
|
||||||
graphicsSystem->SetWindow(&window);
|
graphicsSystem->SetWindow(&window);
|
||||||
sdlWindow = SDL_CreateWindowFrom(window.GetHWND());
|
|
||||||
//auto [w, h] = window.GetWindowSize();
|
|
||||||
//SDL_SetWindowSize(sdlWindow, w, h);
|
|
||||||
|
|
||||||
SHADE::SHSystemManager::Init();
|
SHADE::SHSystemManager::Init();
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
|
SDL_Init(SDL_INIT_VIDEO);
|
||||||
|
sdlWindow = SDL_CreateWindowFrom(window.GetHWND());
|
||||||
SHADE::SHEditor::Initialise(sdlWindow);
|
SHADE::SHEditor::Initialise(sdlWindow);
|
||||||
#else
|
#else
|
||||||
#endif
|
#endif
|
||||||
|
@ -104,13 +110,9 @@ namespace Sandbox
|
||||||
graphicsSystem->BeginRender();
|
graphicsSystem->BeginRender();
|
||||||
|
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
SHADE::SHEditor::PreRender();
|
SHADE::SHEditor::Update(0.16f);
|
||||||
//SHADE::SHEditor::Render();
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SHEDITOR
|
|
||||||
SHADE::SHEditor::Render();
|
|
||||||
#endif
|
|
||||||
graphicsSystem->Run(1.0f);
|
graphicsSystem->Run(1.0f);
|
||||||
graphicsSystem->EndRender();
|
graphicsSystem->EndRender();
|
||||||
|
|
||||||
|
@ -123,11 +125,12 @@ namespace Sandbox
|
||||||
{
|
{
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
SHADE::SHEditor::Exit();
|
SHADE::SHEditor::Exit();
|
||||||
#endif
|
|
||||||
SHSceneManager::Exit();
|
|
||||||
SHADE::SHSystemManager::Exit();
|
|
||||||
SDL_DestroyWindow(sdlWindow);
|
SDL_DestroyWindow(sdlWindow);
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SHSceneManager::Exit();
|
||||||
|
SHADE::SHSystemManager::Exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#include "Scripting/SHScriptEngine.h"
|
#include "Scripting/SHScriptEngine.h"
|
||||||
#include "Math/Transform/SHTransformComponent.h"
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
|
|
||||||
|
#include "Assets/SHAssetManager.h"
|
||||||
|
|
||||||
using namespace SHADE;
|
using namespace SHADE;
|
||||||
|
|
||||||
namespace Sandbox
|
namespace Sandbox
|
||||||
|
@ -33,8 +35,31 @@ namespace Sandbox
|
||||||
SHADE::SHGraphicsSystem* graphicsSystem = static_cast<SHADE::SHGraphicsSystem*>(SHADE::SHSystemManager::GetSystem<SHADE::SHGraphicsSystem>());
|
SHADE::SHGraphicsSystem* graphicsSystem = static_cast<SHADE::SHGraphicsSystem*>(SHADE::SHSystemManager::GetSystem<SHADE::SHGraphicsSystem>());
|
||||||
// Create temp meshes
|
// Create temp meshes
|
||||||
const auto CUBE_MESH = SHADE::SHPrimitiveGenerator::Cube(*graphicsSystem);
|
const auto CUBE_MESH = SHADE::SHPrimitiveGenerator::Cube(*graphicsSystem);
|
||||||
|
//graphicsSystem->BuildMeshBuffers();
|
||||||
|
|
||||||
|
//Test Racoon mesh
|
||||||
|
auto meshes = SHADE::SHAssetManager::GetAllMeshes();
|
||||||
|
std::vector<Handle<SHMesh>> handles;
|
||||||
|
for (auto const& mesh : meshes)
|
||||||
|
{
|
||||||
|
if (mesh.meshName == "Cube.012")
|
||||||
|
{
|
||||||
|
handles.push_back(graphicsSystem->AddMesh(
|
||||||
|
mesh.header.vertexCount,
|
||||||
|
mesh.vertexPosition.data(),
|
||||||
|
mesh.texCoords.data(),
|
||||||
|
mesh.vertexTangent.data(),
|
||||||
|
mesh.vertexNormal.data(),
|
||||||
|
mesh.header.indexCount,
|
||||||
|
mesh.indices.data()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
graphicsSystem->BuildMeshBuffers();
|
graphicsSystem->BuildMeshBuffers();
|
||||||
|
|
||||||
|
//Test Textures
|
||||||
|
auto textures{ SHADE::SHAssetManager::GetAllTextures() };
|
||||||
|
|
||||||
// Create Materials
|
// Create Materials
|
||||||
auto matInst = graphicsSystem->AddOrGetBaseMaterialInstance();
|
auto matInst = graphicsSystem->AddOrGetBaseMaterialInstance();
|
||||||
|
|
||||||
|
@ -44,22 +69,33 @@ namespace Sandbox
|
||||||
constexpr int NUM_COLS = 1;
|
constexpr int NUM_COLS = 1;
|
||||||
static const SHVec3 TEST_OBJ_SPACING = { 1.0f, 1.0f, 1.0f };
|
static const SHVec3 TEST_OBJ_SPACING = { 1.0f, 1.0f, 1.0f };
|
||||||
static const SHVec3 TEST_OBJ_START_POS = { - (NUM_COLS / 2 * TEST_OBJ_SPACING.x ), 0.0f, 0.0f };
|
static const SHVec3 TEST_OBJ_START_POS = { - (NUM_COLS / 2 * TEST_OBJ_SPACING.x ), 0.0f, 0.0f };
|
||||||
for (int z = 0; z < NUM_ROWS; ++z)
|
//for (int z = 0; z < NUM_ROWS; ++z)
|
||||||
for (int x = 0; x < NUM_COLS; ++x)
|
//for (int x = 0; x < NUM_COLS; ++x)
|
||||||
{
|
//{
|
||||||
|
// auto entity = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
||||||
|
// auto& renderable = *SHComponentManager::GetComponent_s<SHRenderable>(entity);
|
||||||
|
// auto& transform = *SHComponentManager::GetComponent_s<SHTransformComponent>(entity);
|
||||||
|
|
||||||
|
// renderable.Mesh = handles.front();
|
||||||
|
// renderable.SetMaterial(matInst);
|
||||||
|
|
||||||
|
// // Set initial positions
|
||||||
|
// transform.SetWorldPosition(TEST_OBJ_START_POS + SHVec3{ x * TEST_OBJ_SPACING.x, 0.0f, z * TEST_OBJ_SPACING.z });
|
||||||
|
// //transform.SetLocalScale(TEST_OBJ_SCALE);
|
||||||
|
|
||||||
|
// stressTestObjects.emplace_back(entity);
|
||||||
|
//}
|
||||||
|
|
||||||
auto entity = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
auto entity = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
||||||
auto& renderable = *SHComponentManager::GetComponent_s<SHRenderable>(entity);
|
auto& renderable = *SHComponentManager::GetComponent_s<SHRenderable>(entity);
|
||||||
auto& transform = *SHComponentManager::GetComponent_s<SHTransformComponent>(entity);
|
auto& transform = *SHComponentManager::GetComponent_s<SHTransformComponent>(entity);
|
||||||
|
|
||||||
renderable.Mesh = CUBE_MESH;
|
renderable.Mesh = handles.front();
|
||||||
renderable.SetMaterial(matInst);
|
renderable.SetMaterial(matInst);
|
||||||
|
|
||||||
// Set initial positions
|
|
||||||
transform.SetWorldPosition(TEST_OBJ_START_POS + SHVec3{ x * TEST_OBJ_SPACING.x, 0.0f, z * TEST_OBJ_SPACING.z });
|
|
||||||
//transform.SetLocalScale(TEST_OBJ_SCALE);
|
//transform.SetLocalScale(TEST_OBJ_SCALE);
|
||||||
|
|
||||||
stressTestObjects.emplace_back(entity);
|
stressTestObjects.emplace_back(entity);
|
||||||
}
|
|
||||||
|
|
||||||
// Create blank entity with a script
|
// Create blank entity with a script
|
||||||
testObj = SHADE::SHEntityManager::CreateEntity();
|
testObj = SHADE::SHEntityManager::CreateEntity();
|
||||||
|
|
|
@ -42,6 +42,7 @@ project "SHADE_Engine"
|
||||||
"%{IncludeDir.VULKAN}\\include",
|
"%{IncludeDir.VULKAN}\\include",
|
||||||
"%{IncludeDir.VULKAN}\\Source\\SPIRV-Reflect",
|
"%{IncludeDir.VULKAN}\\Source\\SPIRV-Reflect",
|
||||||
"%{IncludeDir.dotnet}\\include",
|
"%{IncludeDir.dotnet}\\include",
|
||||||
|
"%{IncludeDir.tinyddsloader}"
|
||||||
}
|
}
|
||||||
|
|
||||||
externalwarnings "Off"
|
externalwarnings "Off"
|
||||||
|
@ -106,16 +107,34 @@ project "SHADE_Engine"
|
||||||
"xcopy /s /r /y /q \"%{IncludeDir.dotnet}\\bin\" \"$(OutDir)\""
|
"xcopy /s /r /y /q \"%{IncludeDir.dotnet}\\bin\" \"$(OutDir)\""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filter "configurations:Debug"
|
||||||
|
postbuildcommands {"xcopy /r /y /q \"%{IncludeDir.assimp}\\bin\\Debug\\assimp-vc142-mtd.dll\" \"$(OutDir)\""}
|
||||||
|
|
||||||
|
filter "configurations:Release"
|
||||||
|
postbuildcommands {"xcopy /r /y /q \"%{IncludeDir.assimp}\\bin\\Release\\assimp-vc142-mt.dll\" \"$(OutDir)\""}
|
||||||
|
|
||||||
warnings 'Extra'
|
warnings 'Extra'
|
||||||
|
|
||||||
filter "configurations:Debug"
|
filter "configurations:Debug"
|
||||||
symbols "On"
|
symbols "On"
|
||||||
defines {"_DEBUG"}
|
defines {"_DEBUG", "SHEDITOR"}
|
||||||
links{"assimp-vc142-mtd.lib", "librttr_core_d.lib", "spdlogd.lib"}
|
links{"assimp-vc142-mtd.lib", "librttr_core_d.lib", "spdlogd.lib"}
|
||||||
--links{"fmodstudioL_vc.lib", "fmodL_vc.lib"}
|
--links{"fmodstudioL_vc.lib", "fmodL_vc.lib"}
|
||||||
|
|
||||||
filter "configurations:Release"
|
filter "configurations:Release"
|
||||||
optimize "On"
|
optimize "On"
|
||||||
defines{"_RELEASE"}
|
defines{"_RELEASE", "SHEDITOR"}
|
||||||
links{"assimp-vc142-mt.lib", "librttr_core.lib", "spdlog.lib"}
|
links{"assimp-vc142-mt.lib", "librttr_core.lib", "spdlog.lib"}
|
||||||
--links{"fmodstudio_vc.lib", "fmod_vc.lib"}
|
--links{"fmodstudio_vc.lib", "fmod_vc.lib"}
|
||||||
|
|
||||||
|
filter "configurations:Publish"
|
||||||
|
optimize "On"
|
||||||
|
defines{"_RELEASE"}
|
||||||
|
links{"assimp-vc142-mt.lib", "librttr_core.lib", "spdlog.lib"}
|
||||||
|
excludes
|
||||||
|
{
|
||||||
|
"%{prj.location}/src/Editor/**.cpp",
|
||||||
|
"%{prj.location}/src/Editor/**.h",
|
||||||
|
"%{prj.location}/src/Editor/**.hpp",
|
||||||
|
}
|
||||||
|
--links{"fmodstudio_vc.lib", "fmod_vc.lib"}
|
|
@ -0,0 +1,29 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include "Math/SHMath.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
struct SHMeshAssetHeader
|
||||||
|
{
|
||||||
|
uint32_t vertexCount;
|
||||||
|
uint32_t indexCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SHMeshAsset
|
||||||
|
{
|
||||||
|
bool compiled;
|
||||||
|
bool changed;
|
||||||
|
|
||||||
|
SHMeshAssetHeader header;
|
||||||
|
|
||||||
|
std::string meshName;
|
||||||
|
|
||||||
|
std::vector<SHVec3> vertexPosition;
|
||||||
|
std::vector<SHVec3> vertexTangent;
|
||||||
|
std::vector<SHVec3> vertexNormal;
|
||||||
|
std::vector<SHVec2> texCoords;
|
||||||
|
std::vector<uint32_t> indices;
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "tinyddsloader.h"
|
||||||
|
|
||||||
|
#include "Graphics/MiddleEnd/Textures/SHTextureLibrary.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
struct SHTextureAsset
|
||||||
|
{
|
||||||
|
uint32_t numBytes;
|
||||||
|
uint32_t width;
|
||||||
|
uint32_t height;
|
||||||
|
SHTexture::TextureFormat format;
|
||||||
|
std::vector<uint32_t> mipOffsets;
|
||||||
|
SHTexture::PixelChannel const * pixelData;
|
||||||
|
|
||||||
|
SHTextureAsset()
|
||||||
|
: numBytes{ 0 },
|
||||||
|
width{ 0 },
|
||||||
|
height{ 0 },
|
||||||
|
format{ SHTexture::TextureFormat::eUndefined },
|
||||||
|
pixelData{ nullptr }
|
||||||
|
{}
|
||||||
|
|
||||||
|
SHTextureAsset(SHTextureAsset const& rhs)
|
||||||
|
: numBytes{ rhs.numBytes },
|
||||||
|
width{ rhs.width },
|
||||||
|
height{ rhs.height },
|
||||||
|
format{ rhs.format },
|
||||||
|
mipOffsets{ rhs.mipOffsets },
|
||||||
|
pixelData(rhs.pixelData)
|
||||||
|
{}
|
||||||
|
|
||||||
|
//SHTextureAsset(SHTextureAsset&& rhs)
|
||||||
|
// : numBytes{ rhs.numBytes },
|
||||||
|
// width{ rhs.width },
|
||||||
|
// height{ rhs.height },
|
||||||
|
// format{ rhs.format },
|
||||||
|
// mipOffsets{ rhs.mipOffsets },
|
||||||
|
// pixelData(std::move(rhs.pixelData))
|
||||||
|
//{}
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,129 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHMeshLoader.h"
|
||||||
|
#include <assimp/postprocess.h>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
Assimp::Importer SHMeshLoader::aiImporter;
|
||||||
|
|
||||||
|
void SHMeshLoader::ProcessNode(aiNode const& node, aiScene const& scene, std::vector<SHMeshAsset>& meshes)
|
||||||
|
{
|
||||||
|
for (size_t i {0}; i < node.mNumMeshes; ++i)
|
||||||
|
{
|
||||||
|
aiMesh* mesh = scene.mMeshes[node.mMeshes[i]];
|
||||||
|
meshes.push_back(ProcessMesh(*mesh, scene));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i{ 0 }; i < node.mNumChildren; ++i)
|
||||||
|
{
|
||||||
|
ProcessNode(*node.mChildren[i], scene, meshes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SHMeshAsset SHMeshLoader::ProcessMesh(aiMesh const& mesh, aiScene const& scene)
|
||||||
|
{
|
||||||
|
(void)scene;
|
||||||
|
|
||||||
|
SHMeshAsset result
|
||||||
|
{
|
||||||
|
.compiled { false},
|
||||||
|
.changed { false },
|
||||||
|
.meshName { mesh.mName.C_Str() }
|
||||||
|
};
|
||||||
|
|
||||||
|
for (size_t i{0}; i < mesh.mNumVertices; ++i)
|
||||||
|
{
|
||||||
|
// Vertex position
|
||||||
|
SHVec3 vertex;
|
||||||
|
vertex.x = mesh.mVertices[i].x;
|
||||||
|
vertex.y = mesh.mVertices[i].y;
|
||||||
|
vertex.z = mesh.mVertices[i].z;
|
||||||
|
result.vertexPosition.push_back(vertex);
|
||||||
|
|
||||||
|
// Tex coords
|
||||||
|
SHVec2 texCoord{0.f, 0.f};
|
||||||
|
if (mesh.mTextureCoords[0])
|
||||||
|
{
|
||||||
|
texCoord.x = mesh.mTextureCoords[0][i].x;
|
||||||
|
texCoord.y = mesh.mTextureCoords[0][i].y;
|
||||||
|
}
|
||||||
|
result.texCoords.push_back(texCoord);
|
||||||
|
|
||||||
|
// Normals
|
||||||
|
SHVec3 normal{0.f, 0.f, 0.f};
|
||||||
|
if (mesh.mNormals)
|
||||||
|
{
|
||||||
|
normal.x = mesh.mNormals[i].x;
|
||||||
|
normal.y = mesh.mNormals[i].y;
|
||||||
|
normal.z = mesh.mNormals[i].z;
|
||||||
|
}
|
||||||
|
result.vertexNormal.push_back(normal);
|
||||||
|
|
||||||
|
// Tangent
|
||||||
|
SHVec3 tangent{0.f, 0.f, 0.f};
|
||||||
|
if (mesh.mTangents)
|
||||||
|
{
|
||||||
|
tangent.x = mesh.mTangents[i].x;
|
||||||
|
tangent.y = mesh.mTangents[i].y;
|
||||||
|
tangent.z = mesh.mTangents[i].z;
|
||||||
|
}
|
||||||
|
result.vertexTangent.push_back(tangent);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i {0}; i < mesh.mNumFaces; ++i)
|
||||||
|
{
|
||||||
|
aiFace face = mesh.mFaces[i];
|
||||||
|
for (size_t j{0}; j < face.mNumIndices; ++j)
|
||||||
|
{
|
||||||
|
result.indices.push_back(face.mIndices[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.header.vertexCount = result.vertexPosition.size();
|
||||||
|
result.header.indexCount = result.indices.size();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHMeshLoader::LoadMesh(std::vector<SHMeshAsset>& meshes, AssetPath path)
|
||||||
|
{
|
||||||
|
const aiScene* scene = aiImporter.ReadFile(path.string().c_str(),
|
||||||
|
aiProcess_Triangulate
|
||||||
|
// Make sure we get triangles rather than nvert polygons
|
||||||
|
| aiProcess_GenUVCoords // Convert any type of mapping to uv mapping
|
||||||
|
| aiProcess_TransformUVCoords
|
||||||
|
// preprocess UV transformations (scaling, translation ...)
|
||||||
|
| aiProcess_FindInstances
|
||||||
|
// search for instanced meshes and remove them by references to one master
|
||||||
|
| aiProcess_CalcTangentSpace
|
||||||
|
// calculate tangents and bitangents if possible
|
||||||
|
| aiProcess_JoinIdenticalVertices
|
||||||
|
// join identical vertices/ optimize indexing
|
||||||
|
| aiProcess_RemoveRedundantMaterials // remove redundant materials
|
||||||
|
| aiProcess_FindInvalidData// detect invalid model data, such as invalid normal vectors
|
||||||
|
| aiProcess_FlipUVs // flip the V to match the Vulkans way of doing UVs
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!scene || !scene->HasMeshes())
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("ERROR in GLTF::ASSIMP: {}\nFile: {}", aiImporter.GetErrorString(), path.string());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//TODO MATERIALS FROM MESHES
|
||||||
|
//if (scene->HasMaterials())
|
||||||
|
//{
|
||||||
|
// for (int i{0}; i < scene->mNumMaterials; ++i)
|
||||||
|
// {
|
||||||
|
// if (scene->mMaterials[i]->mNumProperties > 0)
|
||||||
|
// {
|
||||||
|
// for (int j{0}; j < scene->mMaterials[i]->mProperties[j].)
|
||||||
|
// }
|
||||||
|
//std::cout << scene->mMaterials[i]->;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
ProcessNode(*scene->mRootNode, *scene, meshes);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
#pragma once
|
||||||
|
#include <assimp/Importer.hpp>
|
||||||
|
#include <assimp/scene.h>
|
||||||
|
#include "../SHAssetMacros.h"
|
||||||
|
#include "../Asset Types/SHMeshAsset.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHMeshLoader
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
static Assimp::Importer aiImporter;
|
||||||
|
|
||||||
|
static void ProcessNode(aiNode const& node, aiScene const& scene, std::vector<SHMeshAsset>& meshes);
|
||||||
|
|
||||||
|
static SHMeshAsset ProcessMesh(aiMesh const& mesh, aiScene const& scene);
|
||||||
|
public:
|
||||||
|
static bool LoadMesh(std::vector<SHMeshAsset>& meshes, AssetPath path);
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHMeshWriter.h"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
void SHADE::SHMeshWriter::WriteMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept
|
||||||
|
{
|
||||||
|
std::ofstream file{path, std::ios::out | std::ios::binary};
|
||||||
|
if (!file.is_open())
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Unable to open file for writing mesh file: {}", path.string());
|
||||||
|
}
|
||||||
|
|
||||||
|
file.write(
|
||||||
|
reinterpret_cast<char const*>(&(asset.header.vertexCount)),
|
||||||
|
sizeof(uint32_t)
|
||||||
|
);
|
||||||
|
|
||||||
|
file.write(
|
||||||
|
reinterpret_cast<const char*>(&(asset.header.indexCount)),
|
||||||
|
sizeof(uint32_t)
|
||||||
|
);
|
||||||
|
|
||||||
|
auto const vertexVec3Byte {sizeof(SHVec3) * asset.header.vertexCount};
|
||||||
|
auto const vertexVec2Byte {sizeof(SHVec2) * asset.header.vertexCount};
|
||||||
|
|
||||||
|
file.write(
|
||||||
|
reinterpret_cast<char const*>(asset.vertexPosition.data()),
|
||||||
|
vertexVec3Byte
|
||||||
|
);
|
||||||
|
|
||||||
|
file.write(
|
||||||
|
reinterpret_cast<char const*>(asset.vertexTangent.data()),
|
||||||
|
vertexVec3Byte
|
||||||
|
);
|
||||||
|
|
||||||
|
file.write(
|
||||||
|
reinterpret_cast<char const*>(asset.vertexNormal.data()),
|
||||||
|
vertexVec3Byte
|
||||||
|
);
|
||||||
|
|
||||||
|
file.write(
|
||||||
|
reinterpret_cast<char const*>(asset.texCoords.data()),
|
||||||
|
vertexVec2Byte
|
||||||
|
);
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../Asset Types/SHMeshAsset.h"
|
||||||
|
#include "../SHAssetMacros.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHMeshWriter
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
public:
|
||||||
|
static void WriteMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept;
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHTextureLoader.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
std::string SHTextureLoader::TinyDDSResultToString(tinyddsloader::Result value)
|
||||||
|
{
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case tinyddsloader::Result::ErrorFileOpen:
|
||||||
|
return "File open err";
|
||||||
|
case tinyddsloader::Result::ErrorRead:
|
||||||
|
return "File read err";
|
||||||
|
case tinyddsloader::Result::ErrorMagicWord:
|
||||||
|
return "File header magic word err";
|
||||||
|
case tinyddsloader::Result::ErrorSize:
|
||||||
|
return "File size err";
|
||||||
|
case tinyddsloader::Result::ErrorVerify:
|
||||||
|
return "Pixel format err";
|
||||||
|
case tinyddsloader::Result::ErrorNotSupported:
|
||||||
|
return "Unsupported format";
|
||||||
|
case tinyddsloader::Result::ErrorInvalidData:
|
||||||
|
return "Invalid data";
|
||||||
|
default:
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vk::Format SHTextureLoader::ddsLoaderToVkFormat(tinyddsloader::DDSFile::DXGIFormat format, bool isLinear)
|
||||||
|
{
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::BC1_UNorm:
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::BC1_UNorm_SRGB:
|
||||||
|
return isLinear ? vk::Format::eBc1RgbaUnormBlock : vk::Format::eBc1RgbaSrgbBlock;
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::BC2_UNorm:
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::BC2_UNorm_SRGB:
|
||||||
|
return isLinear ? vk::Format::eBc2UnormBlock : vk::Format::eBc2SrgbBlock;
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::BC3_UNorm:
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::BC3_UNorm_SRGB:
|
||||||
|
return isLinear ? vk::Format::eBc3UnormBlock : vk::Format::eBc3SrgbBlock;
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::BC5_UNorm:
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::BC5_SNorm:
|
||||||
|
return isLinear ? vk::Format::eBc5UnormBlock : vk::Format::eBc5SnormBlock;
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::R8G8B8A8_UNorm:
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::R8G8B8A8_UNorm_SRGB:
|
||||||
|
return isLinear ? vk::Format::eR8G8B8A8Unorm : vk::Format::eR8G8B8A8Srgb;
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::R8G8B8A8_SNorm:
|
||||||
|
return vk::Format::eR8G8B8A8Snorm;
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::B8G8R8A8_UNorm:
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::B8G8R8A8_UNorm_SRGB:
|
||||||
|
return isLinear ? vk::Format::eB8G8R8A8Unorm : vk::Format::eB8G8R8A8Srgb;
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::B8G8R8X8_UNorm:
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::B8G8R8X8_UNorm_SRGB:
|
||||||
|
return isLinear ? vk::Format::eB8G8R8A8Unorm : vk::Format::eB8G8R8Srgb;
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("Unsupported DDS format.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHTextureLoader::LoadImageAsset(AssetPath path, SHTextureAsset& asset)
|
||||||
|
{
|
||||||
|
tinyddsloader::Result loadResult = tinyddsloader::Result::Success;
|
||||||
|
tinyddsloader::DDSFile file;
|
||||||
|
loadResult = file.Load(path.string().c_str());
|
||||||
|
if (loadResult != tinyddsloader::Result::Success)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Unable to load Texture file: {} at {}", TinyDDSResultToString(loadResult), path.string());
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t totalBytes{ 0 };
|
||||||
|
|
||||||
|
std::vector<uint32_t> mipOff(file.GetMipCount());
|
||||||
|
|
||||||
|
for (auto i{0}; i < file.GetMipCount(); ++i)
|
||||||
|
{
|
||||||
|
mipOff.push_back(totalBytes);
|
||||||
|
totalBytes += file.GetImageData(i, 0)->m_memSlicePitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHTexture::PixelChannel* pixel = new SHTexture::PixelChannel[totalBytes];
|
||||||
|
std::memcpy(pixel, file.GetDDSData(), totalBytes);
|
||||||
|
//pixel = std::move(reinterpret_cast<SHTexture::PixelChannel const*>(file.GetDDSData()));
|
||||||
|
|
||||||
|
asset.numBytes = totalBytes;
|
||||||
|
asset.width = file.GetWidth();
|
||||||
|
asset.height = file.GetHeight();
|
||||||
|
asset.format = ddsLoaderToVkFormat(file.GetFormat(), true);
|
||||||
|
asset.mipOffsets = std::move(mipOff);
|
||||||
|
asset.pixelData = std::move(pixel);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
#pragma once
|
||||||
|
#define TINYDDSLOADER_IMPLEMENTATION
|
||||||
|
|
||||||
|
#include "../SHAssetMacros.h"
|
||||||
|
#include "../Asset Types/SHTextureAsset.h"
|
||||||
|
#include "tinyddsloader.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHTextureLoader
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
static std::string TinyDDSResultToString(tinyddsloader::Result value);
|
||||||
|
static vk::Format ddsLoaderToVkFormat(tinyddsloader::DDSFile::DXGIFormat format, bool isLinear);
|
||||||
|
|
||||||
|
public:
|
||||||
|
static void LoadImageAsset(AssetPath paths, SHTextureAsset& image);
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Filesystem/SHFileSystem.h"
|
||||||
|
#include "SHAssetMacros.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
struct SHAsset
|
||||||
|
{
|
||||||
|
AssetName name;
|
||||||
|
AssetID id;
|
||||||
|
AssetType type;
|
||||||
|
AssetPath path;
|
||||||
|
FolderLocation location;
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* \file SHAssetMacros.h
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \brief Macros and typedefs for assets
|
||||||
|
*
|
||||||
|
* \copyright Copyright (c) 2022 Digipen Institute of Technology. Reproduction
|
||||||
|
* or disclosure of this file or its contents without the prior
|
||||||
|
* written consent of Digipen Institute of Technology is prohibited
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef SH_ASSET_MACROS_H
|
||||||
|
#define SH_ASSET_MACROS_H
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
// FMOD Fwd Declare
|
||||||
|
namespace FMOD
|
||||||
|
{
|
||||||
|
class Sound;
|
||||||
|
class System;
|
||||||
|
class ChannelGroup;
|
||||||
|
class Channel;
|
||||||
|
}
|
||||||
|
enum FMOD_RESULT : int;
|
||||||
|
enum FMOD_SPEAKERMODE : int;
|
||||||
|
|
||||||
|
// Typedefs
|
||||||
|
typedef uint32_t AssetID;
|
||||||
|
typedef std::string AssetName;
|
||||||
|
typedef std::filesystem::path AssetPath;
|
||||||
|
typedef unsigned char* AssetData;
|
||||||
|
typedef std::string AssetMetaVersion;
|
||||||
|
typedef std::string AssetExtension;
|
||||||
|
typedef unsigned char AssetTypeMeta;
|
||||||
|
|
||||||
|
typedef FMOD::Sound* SHSound;
|
||||||
|
|
||||||
|
// Asset Meta Version
|
||||||
|
#define ASSET_META_VER "1.0"
|
||||||
|
|
||||||
|
// Asset type enum
|
||||||
|
enum class AssetType : uint8_t
|
||||||
|
{
|
||||||
|
INVALID = 0,
|
||||||
|
AUDIO = 1,
|
||||||
|
SHADER,
|
||||||
|
MATERIAL,
|
||||||
|
IMAGE,
|
||||||
|
TEXTURE,
|
||||||
|
MESH,
|
||||||
|
SCRIPT,
|
||||||
|
SCENE,
|
||||||
|
PREFAB,
|
||||||
|
AUDIO_WAV,
|
||||||
|
DDS
|
||||||
|
};
|
||||||
|
|
||||||
|
//Directory
|
||||||
|
#define ASSET_ROOT "./Assets/"
|
||||||
|
|
||||||
|
// ASSET EXTENSIONS
|
||||||
|
#define META_EXTENSION ".shmeta"
|
||||||
|
#define IMAGE_EXTENSION ".png"
|
||||||
|
#define AUDIO_EXTENSION ".ogg"
|
||||||
|
#define AUDIO_WAV_EXTENSION ".wav"
|
||||||
|
#define SHADER_EXTENSION ".glsl"
|
||||||
|
#define SCRIPT_EXTENSION ".cs"
|
||||||
|
#define SCENE_EXTENSION ".SHADE"
|
||||||
|
#define PREFAB_EXTENSION ".SHPrefab"
|
||||||
|
#define MATERIAL_EXTENSION ".SHMat"
|
||||||
|
#define TEXTURE_EXTENSION ".shtex"
|
||||||
|
#define DDS_EXTENSION ".dds"
|
||||||
|
#define FBX_EXTENSION ".fbx"
|
||||||
|
#define GLTF_EXTENSION ".gltf"
|
||||||
|
#define MESH_EXTENSION ".shmesh"
|
||||||
|
|
||||||
|
std::string const EXTENSIONS[] = {
|
||||||
|
AUDIO_EXTENSION,
|
||||||
|
SHADER_EXTENSION,
|
||||||
|
MATERIAL_EXTENSION,
|
||||||
|
IMAGE_EXTENSION,
|
||||||
|
TEXTURE_EXTENSION,
|
||||||
|
DDS_EXTENSION,
|
||||||
|
MESH_EXTENSION,
|
||||||
|
SCRIPT_EXTENSION,
|
||||||
|
SCENE_EXTENSION,
|
||||||
|
PREFAB_EXTENSION,
|
||||||
|
AUDIO_WAV_EXTENSION,
|
||||||
|
FBX_EXTENSION,
|
||||||
|
GLTF_EXTENSION
|
||||||
|
};
|
||||||
|
|
||||||
|
// Error flags
|
||||||
|
#define FILE_NOT_FOUND_ERR "FILE NOT FOUND"
|
||||||
|
#define META_NOT_FOUND_ERR "META NOT FOUND"
|
||||||
|
#define ASSET_NOT_FOUND_ERR "ASSET NOT FOUND"
|
||||||
|
#define EXT_DOES_NOT_EXIST "TYPE DOES NOT HAVE EXTENSION DEFINED"
|
||||||
|
|
||||||
|
#endif // !SH_ASSET_MACROS_H
|
|
@ -0,0 +1,441 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* \file SHAssetManager.cpp
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \brief Implementations for SHAssetManager.h
|
||||||
|
*
|
||||||
|
* \copyright Copyright (c) 2021 Digipen Institute of Technology. Reproduction
|
||||||
|
* or disclosure of this file or its contents without the prior
|
||||||
|
* written consent of Digipen Institute of Technology is prohibited.
|
||||||
|
******************************************************************************/
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include <random>
|
||||||
|
#include <chrono>
|
||||||
|
#include "SHAssetManager.h"
|
||||||
|
#include "SHAssetMetaHandler.h"
|
||||||
|
#include "Filesystem/SHFileSystem.h"
|
||||||
|
|
||||||
|
#include "Libraries/SHMeshLoader.h"
|
||||||
|
#include "Libraries/SHTextureLoader.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
FMOD::System* SHAssetManager::audioSystem;
|
||||||
|
std::unordered_map<AssetID, SHSound >* SHAssetManager::audioSoundList;
|
||||||
|
|
||||||
|
std::vector<SHAsset> SHAssetManager::assetCollection;
|
||||||
|
std::unordered_map<AssetID, SHAsset> SHAssetManager::assetRegistry;
|
||||||
|
|
||||||
|
std::unordered_map<AssetID, SHMeshAsset> SHAssetManager::meshCollection;
|
||||||
|
std::unordered_map<AssetID, SHTextureAsset> SHAssetManager::textureCollection;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Static function to generate asset ID.
|
||||||
|
****************************************************************************/
|
||||||
|
AssetID SHAssetManager::GenerateAssetID(AssetType type) noexcept
|
||||||
|
{
|
||||||
|
std::default_random_engine randEngine{
|
||||||
|
static_cast<unsigned int>(std::chrono::system_clock::now().time_since_epoch().count()) };
|
||||||
|
std::mt19937 idGen{ randEngine() };
|
||||||
|
AssetID result{ static_cast<AssetID>(type) << 24};
|
||||||
|
AssetID unique{ idGen() & ((1 << 24) - 1) };
|
||||||
|
|
||||||
|
result |= unique;
|
||||||
|
|
||||||
|
while (result == 0)
|
||||||
|
{
|
||||||
|
result = GenerateAssetID(type);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Deallocate all memory used by asset data
|
||||||
|
****************************************************************************/
|
||||||
|
void SHAssetManager::Unload() noexcept
|
||||||
|
{
|
||||||
|
for (auto const& asset : assetCollection)
|
||||||
|
{
|
||||||
|
SHAssetMetaHandler::WriteMetaData(asset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetPath SHAssetManager::GenerateLocalPath(AssetPath path) noexcept
|
||||||
|
{
|
||||||
|
if (!IsRecognised(path.extension().string().c_str()))
|
||||||
|
{
|
||||||
|
//TODO:ASSERT UNRECOGNISED FILE TYPE
|
||||||
|
return std::filesystem::path();
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetType type = SHAssetMetaHandler::GetTypeFromExtension(path.extension().string().c_str());
|
||||||
|
std::string folder;
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
//TODO:ASSERT UNSUPPORTED FILE TYPE
|
||||||
|
return std::filesystem::path();
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::filesystem::path(ASSET_ROOT + folder + path.filename().string());
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Get record of all assets currently loaded with name and id.
|
||||||
|
*
|
||||||
|
* \return const& to unordered_map<AssetName, AssetID>
|
||||||
|
****************************************************************************/
|
||||||
|
std::vector<SHAsset> const& SHAssetManager::GetAllAssets() noexcept
|
||||||
|
{
|
||||||
|
return assetCollection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Create record for new asset. CAN ONLY CREATE FOR CUSTOM
|
||||||
|
* ASSETS CREATED BY THE ENGINE.
|
||||||
|
*
|
||||||
|
* \param type of asset
|
||||||
|
* \param name of asset
|
||||||
|
* \return asset id generated for new asset
|
||||||
|
****************************************************************************/
|
||||||
|
AssetID SHAssetManager::CreateNewAsset(AssetType type, AssetName name) noexcept
|
||||||
|
{
|
||||||
|
AssetID id{ GenerateAssetID(type) };
|
||||||
|
SHAsset meta;
|
||||||
|
meta.id = id;
|
||||||
|
meta.type = type;
|
||||||
|
|
||||||
|
std::string folder;
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
folder = "";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
AssetPath path{ ASSET_ROOT + folder + name + SHAssetMetaHandler::GetExtensionFromType(type) };
|
||||||
|
|
||||||
|
SHAssetMetaHandler::WriteMetaData(meta);
|
||||||
|
|
||||||
|
assetCollection.push_back(meta);
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Import new asset from outside editor window.
|
||||||
|
*
|
||||||
|
* \param path - c style string to full path
|
||||||
|
* \return asset if generated for new
|
||||||
|
****************************************************************************/
|
||||||
|
AssetID SHAssetManager::ImportNewAsset(char const* p) noexcept
|
||||||
|
{
|
||||||
|
std::filesystem::path const path{ p };
|
||||||
|
|
||||||
|
std::filesystem::path const newPath{ GenerateLocalPath(path) };
|
||||||
|
if (newPath.empty())
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("Unsupported file format for asset: {}", path.string());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::filesystem::copy(path, newPath);
|
||||||
|
|
||||||
|
AssetID id{ RetrieveAsset(newPath.string().c_str()) };
|
||||||
|
if (id != 0)
|
||||||
|
{
|
||||||
|
LoadData(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Search through assets folder for new unregistered assets.
|
||||||
|
* Takes in no params and returns nothing. Only updates internally.
|
||||||
|
****************************************************************************/
|
||||||
|
void SHAssetManager::RefreshAllAssets() noexcept
|
||||||
|
{
|
||||||
|
std::vector<AssetPath> metaFiles;
|
||||||
|
std::vector<AssetPath> AssetFiles;
|
||||||
|
|
||||||
|
//SHFileSystem::LoadAllFiles(metaFiles, AssetFiles);
|
||||||
|
//std::vector<AssetPath> AssetFilesVerified;
|
||||||
|
std::vector<AssetPath> AssetFilesNew;
|
||||||
|
|
||||||
|
for (auto const& asset : AssetFiles)
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
for (auto it {metaFiles.begin()}; it != metaFiles.end(); ++it)
|
||||||
|
{
|
||||||
|
std::string fileExtCheck{ asset.filename().string() };
|
||||||
|
fileExtCheck += META_EXTENSION;
|
||||||
|
if (it->filename().string() == fileExtCheck)
|
||||||
|
{
|
||||||
|
metaFiles.erase(it);
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found && IsRecognised(asset.extension().string().c_str()))
|
||||||
|
{
|
||||||
|
AssetFilesNew.push_back(asset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<SHAsset> newLoad;
|
||||||
|
newLoad.reserve(AssetFilesNew.size());
|
||||||
|
|
||||||
|
//TODO: Handle if meta does not match all assets (if meta exist and asset doesnt, vice versa)
|
||||||
|
for (auto const& file : AssetFilesNew)
|
||||||
|
{
|
||||||
|
newLoad.push_back(RegisterAssetNew(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
//UpdateAllSpriteSets();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAssetManager::LoadDataTemp(std::string p) noexcept
|
||||||
|
{
|
||||||
|
AssetPath path{ p };
|
||||||
|
|
||||||
|
if (path.extension().string() == GLTF_EXTENSION)
|
||||||
|
{
|
||||||
|
LoadGLTF(
|
||||||
|
{
|
||||||
|
.name {path.filename().string()},
|
||||||
|
.id {0},
|
||||||
|
.type {AssetType::MESH},
|
||||||
|
.path {path},
|
||||||
|
.location {0}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (path.extension().string() == DDS_EXTENSION)
|
||||||
|
{
|
||||||
|
LoadDDS(
|
||||||
|
{
|
||||||
|
.name {path.filename().string()},
|
||||||
|
.id {0},
|
||||||
|
.type {AssetType::DDS},
|
||||||
|
.path {path},
|
||||||
|
.location {0}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<SHMeshAsset> SHAssetManager::GetAllMeshes() noexcept
|
||||||
|
{
|
||||||
|
std::vector<SHMeshAsset> result;
|
||||||
|
for (auto const& mesh : meshCollection)
|
||||||
|
{
|
||||||
|
result.push_back(mesh.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<SHTextureAsset> SHAssetManager::GetAllTextures() noexcept
|
||||||
|
{
|
||||||
|
std::vector<SHTextureAsset> result;
|
||||||
|
for (auto const& dds : textureCollection)
|
||||||
|
{
|
||||||
|
result.push_back(dds.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param Path for meta data file
|
||||||
|
* \param Path for asset file
|
||||||
|
|
||||||
|
* \brief Links meta data to asset in registries. Meta data should
|
||||||
|
* already exist
|
||||||
|
****************************************************************************/
|
||||||
|
void SHAssetManager::RegisterAsset(AssetPath const& metaPath, AssetPath const& path) noexcept
|
||||||
|
{
|
||||||
|
SHAsset const meta = SHAssetMetaHandler::RetrieveMetaData(metaPath);
|
||||||
|
|
||||||
|
assetCollection.push_back(meta);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param Path for asset file
|
||||||
|
|
||||||
|
* \brief Creates new meta data for new asset.
|
||||||
|
****************************************************************************/
|
||||||
|
SHAsset SHAssetManager::RegisterAssetNew(AssetPath const& asset) noexcept
|
||||||
|
{
|
||||||
|
SHAsset meta;
|
||||||
|
meta.type = SHAssetMetaHandler::GetTypeFromExtension(asset.extension().string());
|
||||||
|
meta.id = GenerateAssetID(meta.type);
|
||||||
|
|
||||||
|
assetCollection.push_back(meta);
|
||||||
|
|
||||||
|
SHAssetMetaHandler::WriteMetaData(meta);
|
||||||
|
return assetCollection.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHAssetManager::IsRecognised(char const* ext) noexcept
|
||||||
|
{
|
||||||
|
for (auto const& e : EXTENSIONS)
|
||||||
|
{
|
||||||
|
if (strcmp(ext, e.c_str()) == 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAssetManager::LoadGLTF(SHAsset asset) noexcept
|
||||||
|
{
|
||||||
|
std::vector<SHMeshAsset> meshes;
|
||||||
|
|
||||||
|
SHMeshLoader::LoadMesh(meshes, asset.path);
|
||||||
|
|
||||||
|
for (auto const& mesh : meshes)
|
||||||
|
{
|
||||||
|
meshCollection.emplace(GenerateAssetID(AssetType::MESH), mesh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAssetManager::LoadDDS(SHAsset asset) noexcept
|
||||||
|
{
|
||||||
|
SHTextureAsset image;
|
||||||
|
|
||||||
|
SHTextureLoader::LoadImageAsset(asset.path, image);
|
||||||
|
|
||||||
|
textureCollection.emplace(GenerateAssetID(AssetType::DDS), image);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Load all assets that are in the folder
|
||||||
|
****************************************************************************/
|
||||||
|
void SHAssetManager::Load() noexcept
|
||||||
|
{
|
||||||
|
RetrieveAssets();
|
||||||
|
LoadAllData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Load asset data into memory
|
||||||
|
****************************************************************************/
|
||||||
|
void SHAssetManager::LoadAllData() noexcept
|
||||||
|
{
|
||||||
|
for (auto const& asset : assetCollection)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAssetManager::LoadData(AssetID id) noexcept
|
||||||
|
{
|
||||||
|
(void)id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Retrieve all asset files and meta files from filesystem
|
||||||
|
****************************************************************************/
|
||||||
|
void SHAssetManager::RetrieveAssets() noexcept
|
||||||
|
{
|
||||||
|
std::vector<AssetPath> metaFiles;
|
||||||
|
std::vector<AssetPath> AssetFiles;
|
||||||
|
|
||||||
|
//TODO: Write new function for file manager to loop through all files
|
||||||
|
SHFileSystem::StartupFillDirectories(ASSET_ROOT);
|
||||||
|
FolderPointer rootFolder = SHFileSystem::GetRoot();
|
||||||
|
|
||||||
|
for (auto const& meta : metaFiles)
|
||||||
|
{
|
||||||
|
for (std::vector<AssetPath>::const_iterator it{ AssetFiles.cbegin() };
|
||||||
|
it != AssetFiles.cend();
|
||||||
|
++it)
|
||||||
|
{
|
||||||
|
// Asset exists for meta file
|
||||||
|
std::string fileExtCheck{ it->filename().string() };
|
||||||
|
fileExtCheck += META_EXTENSION;
|
||||||
|
if (meta.filename().string() == fileExtCheck)
|
||||||
|
{
|
||||||
|
RegisterAsset(meta, *it);
|
||||||
|
AssetFiles.erase(it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Handle if meta does not match all assets (if meta exist and asset doesnt, vice versa)
|
||||||
|
for (auto const& file : AssetFiles)
|
||||||
|
{
|
||||||
|
if (IsRecognised(file.extension().string().c_str()))
|
||||||
|
{
|
||||||
|
SHAssetMetaHandler::WriteMetaData(RegisterAssetNew(file));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Unsupported File Format: " << file.filename() << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetID SHAssetManager::RetrieveAsset(char const* path) noexcept
|
||||||
|
{
|
||||||
|
std::filesystem::path p{ path };
|
||||||
|
if (IsRecognised(p.extension().string().c_str()))
|
||||||
|
{
|
||||||
|
SHAsset const& meta{ RegisterAssetNew(p) };
|
||||||
|
SHAssetMetaHandler::WriteMetaData(meta);
|
||||||
|
return meta.id;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Unsupported File Format: " << p.filename() << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assert that file imported is not recognised
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param Full path of file
|
||||||
|
|
||||||
|
* \brief Extracts file name from path. Formats file name into readable
|
||||||
|
* with spaces and capitalises first letter of every word
|
||||||
|
****************************************************************************/
|
||||||
|
AssetName SHAssetManager::GetNameFromPath(AssetPath filepath) noexcept
|
||||||
|
{
|
||||||
|
std::string name{ filepath.filename().string() };
|
||||||
|
name = name.substr(0, name.find_last_of('.'));
|
||||||
|
|
||||||
|
//if (name[0] <= 122 && name[0] >= 97)
|
||||||
|
//{
|
||||||
|
// name[0] -= 32;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//for (size_t i{ 1 }; i < name.length(); ++i)
|
||||||
|
//{
|
||||||
|
// // Replace all underscores with spaces
|
||||||
|
// if (name[i] == '_')
|
||||||
|
// {
|
||||||
|
// name[i] = ' ';
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (name[i + 1] <= 'Z' && name[i + 1] >= 'A'
|
||||||
|
// && name[i] <= 'z' && name[i] >= 'a')
|
||||||
|
// {
|
||||||
|
// name.insert(i + 1, 1, ' ');
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (name[i - 1] == ' ' && name[i] <= 'z' && name[i] >= 'a')
|
||||||
|
// {
|
||||||
|
// name[i] -= 32;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,133 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* \file SHAssetManager.h
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \brief Interface for resource manager, to be used by engine side
|
||||||
|
* operations.
|
||||||
|
*
|
||||||
|
* \copyright Copyright (c) 2021 Digipen Institute of Technology. Reproduction
|
||||||
|
* or disclosure of this file or its contents without the prior
|
||||||
|
* written consent of Digipen Institute of Technology is prohibited.
|
||||||
|
******************************************************************************/
|
||||||
|
#pragma once
|
||||||
|
#include "tinyddsloader.h"
|
||||||
|
#include "SHAsset.h"
|
||||||
|
|
||||||
|
#include "Asset Types/SHMeshAsset.h"
|
||||||
|
#include "Asset Types/SHTextureAsset.h"
|
||||||
|
#include "SH_API.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SH_API SHAssetManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Static function to generate resource ID.
|
||||||
|
****************************************************************************/
|
||||||
|
static AssetID GenerateAssetID(AssetType type) noexcept;
|
||||||
|
|
||||||
|
static AssetPath GenerateLocalPath(AssetPath path) noexcept;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Deallocate all memory used by resource data
|
||||||
|
****************************************************************************/
|
||||||
|
static void Unload() noexcept;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Load all resources that are in the folder
|
||||||
|
****************************************************************************/
|
||||||
|
static void Load() noexcept;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Get record of all resources currently loaded with name and id.
|
||||||
|
*
|
||||||
|
* \return const& to unordered_map<AssetName, AssetID>
|
||||||
|
****************************************************************************/
|
||||||
|
static std::vector<SHAsset> const& GetAllAssets() noexcept;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Create record for new resource. CAN ONLY CREATE FOR CUSTOM
|
||||||
|
* RESOURCES CREATED BY THE ENGINE.
|
||||||
|
*
|
||||||
|
* \param type of resource
|
||||||
|
* \param name of resource
|
||||||
|
* \return resource id generated for new asset
|
||||||
|
****************************************************************************/
|
||||||
|
static AssetID CreateNewAsset(AssetType, AssetName) noexcept;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Import new resource from outside editor window.
|
||||||
|
*
|
||||||
|
* \param path - c style string to full path
|
||||||
|
* \return resource if generated for new
|
||||||
|
****************************************************************************/
|
||||||
|
static AssetID ImportNewAsset(char const* path) noexcept;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Search through resources folder for new unregistered assets.
|
||||||
|
* Takes in no params and returns nothing. Only updates internally.
|
||||||
|
****************************************************************************/
|
||||||
|
static void RefreshAllAssets() noexcept;
|
||||||
|
// -------------------------------------------------------------------------/
|
||||||
|
|
||||||
|
//TODO: TEMPORARY FOR TESTING GLTF & DDS
|
||||||
|
static void LoadDataTemp(std::string path) noexcept;
|
||||||
|
static std::vector<SHMeshAsset> GetAllMeshes() noexcept;
|
||||||
|
static std::vector<SHTextureAsset> GetAllTextures() noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Load resource data into memory
|
||||||
|
****************************************************************************/
|
||||||
|
static void LoadAllData() noexcept;
|
||||||
|
|
||||||
|
static void LoadData(AssetID id) noexcept;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Retrieve all resource files and meta files from filesystem
|
||||||
|
****************************************************************************/
|
||||||
|
static void RetrieveAssets() noexcept;
|
||||||
|
|
||||||
|
static AssetID RetrieveAsset(char const* path) noexcept;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param Full path of file
|
||||||
|
|
||||||
|
* \brief Extracts file name from path. Formats file name into readable
|
||||||
|
* with spaces and capitalises first letter of every word
|
||||||
|
****************************************************************************/
|
||||||
|
static AssetName GetNameFromPath(AssetPath) noexcept;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param Path for meta data file
|
||||||
|
* \param Path for resource file
|
||||||
|
|
||||||
|
* \brief Links meta data to resource in registries. Meta data should
|
||||||
|
* already exist
|
||||||
|
****************************************************************************/
|
||||||
|
static void RegisterAsset(AssetPath const&, AssetPath const&) noexcept;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param Path for resource file
|
||||||
|
|
||||||
|
* \brief Creates new meta data for new resource.
|
||||||
|
****************************************************************************/
|
||||||
|
static SHAsset RegisterAssetNew(AssetPath const&) noexcept;
|
||||||
|
|
||||||
|
static bool IsRecognised(char const*) noexcept;
|
||||||
|
|
||||||
|
// Specialised load calls
|
||||||
|
static void LoadGLTF(SHAsset asset) noexcept;
|
||||||
|
static void LoadDDS(SHAsset asset) noexcept;
|
||||||
|
|
||||||
|
static FMOD::System* audioSystem;
|
||||||
|
static std::unordered_map<AssetID,SHSound>* audioSoundList;
|
||||||
|
|
||||||
|
// For all resources
|
||||||
|
static std::vector<SHAsset> assetCollection;
|
||||||
|
static std::unordered_map<AssetID, SHAsset> assetRegistry;
|
||||||
|
|
||||||
|
static std::unordered_map<AssetID, SHMeshAsset> meshCollection;
|
||||||
|
static std::unordered_map<AssetID, SHTextureAsset> textureCollection;
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,118 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* \file SHAssetMetaHandler.cpp
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \brief Implementations for SHAssetMetaHandler.h
|
||||||
|
*
|
||||||
|
* \copyright Copyright (c) 2021 Digipen Institute of Technology. Reproduction
|
||||||
|
* or disclosure of this file or its contents without the prior
|
||||||
|
* written consent of Digipen Institute of Technology is prohibited
|
||||||
|
******************************************************************************/
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHAssetMetaHandler.h"
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/****************************************************************************
|
||||||
|
* \param reference to ifstream file to read line from
|
||||||
|
* \param reference to string to store line into
|
||||||
|
|
||||||
|
* \brief Helper function to retrieve field value from meta data file
|
||||||
|
* for processing
|
||||||
|
****************************************************************************/
|
||||||
|
void GetFieldValue(std::ifstream& file, std::string& line) noexcept
|
||||||
|
{
|
||||||
|
line = "";
|
||||||
|
std::getline(file, line);
|
||||||
|
line = line.substr(line.find_last_of(':') + 2, line.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param String containing extension of resource file
|
||||||
|
|
||||||
|
* \brief Get correct resource type from file extension of resource.
|
||||||
|
****************************************************************************/
|
||||||
|
AssetType SHAssetMetaHandler::GetTypeFromExtension(AssetExtension ext) noexcept
|
||||||
|
{
|
||||||
|
for (int i{0}; i < EXTENSIONS->size(); ++i)
|
||||||
|
{
|
||||||
|
if (ext == EXTENSIONS[i])
|
||||||
|
{
|
||||||
|
return static_cast<AssetType>(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return AssetType::INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param String containing extension of resource file
|
||||||
|
|
||||||
|
* \brief Get correct resource type from file extension of resource.
|
||||||
|
****************************************************************************/
|
||||||
|
AssetExtension SHAssetMetaHandler::GetExtensionFromType(AssetType type) noexcept
|
||||||
|
{
|
||||||
|
return EXTENSIONS[static_cast<size_t>(type)];
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param Create class containing meta data from meta file
|
||||||
|
|
||||||
|
* \brief path to meta data file
|
||||||
|
****************************************************************************/
|
||||||
|
SHAsset SHAssetMetaHandler::RetrieveMetaData(AssetPath const& path) noexcept
|
||||||
|
{
|
||||||
|
std::ifstream metaFile{ path.string(), std::ios_base::in };
|
||||||
|
if (!metaFile.is_open())
|
||||||
|
{
|
||||||
|
// Error unable to open
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string line;
|
||||||
|
SHAsset meta;
|
||||||
|
|
||||||
|
// Get resource id
|
||||||
|
GetFieldValue(metaFile, line);
|
||||||
|
std::stringstream idStream{ line };
|
||||||
|
AssetID id;
|
||||||
|
idStream >> id;
|
||||||
|
meta.id = id;
|
||||||
|
|
||||||
|
// Get resource type
|
||||||
|
GetFieldValue(metaFile, line);
|
||||||
|
std::stringstream typeStream{ line };
|
||||||
|
AssetTypeMeta type;
|
||||||
|
typeStream >> type;
|
||||||
|
meta.type = static_cast<AssetType>(type);
|
||||||
|
|
||||||
|
metaFile.close();
|
||||||
|
|
||||||
|
return meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param Asset meta data to be written into
|
||||||
|
* \param Path to be written into
|
||||||
|
|
||||||
|
* \brief Writes meta data into text file
|
||||||
|
****************************************************************************/
|
||||||
|
void SHAssetMetaHandler::WriteMetaData(SHAsset const& meta) noexcept
|
||||||
|
{
|
||||||
|
std::string path{ meta.path.string() };
|
||||||
|
path.append(META_EXTENSION);
|
||||||
|
|
||||||
|
std::ofstream metaFile{ path, std::ios_base::out };
|
||||||
|
|
||||||
|
if (!metaFile.is_open())
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Asset write path is invalid: {}", path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
metaFile << "ID: " << meta.id << "\n";
|
||||||
|
metaFile << "Type: " << static_cast<int>(meta.type) << std::endl;
|
||||||
|
metaFile.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* \file SHAssetMetaHandler.h
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \brief Handler classes for meta data for all resources
|
||||||
|
*
|
||||||
|
* \copyright Copyright (c) 2021 Digipen Institute of Technology. Reproduction
|
||||||
|
* or disclosure of this file or its contents without the prior
|
||||||
|
* written consent of Digipen Institute of Technology is prohibited
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef SH_RESOURCE_META_HANDLER_H
|
||||||
|
#define SH_RESOURCE_META_HANDLER_H
|
||||||
|
|
||||||
|
#include "SHAssetMacros.h"
|
||||||
|
#include "SHAsset.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
struct SHAssetMetaHandler
|
||||||
|
{
|
||||||
|
/****************************************************************************
|
||||||
|
* \param String containing extension of resource file
|
||||||
|
|
||||||
|
* \brief Get correct resource type from file extension of resource.
|
||||||
|
****************************************************************************/
|
||||||
|
static AssetType GetTypeFromExtension(AssetExtension) noexcept;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param String containing extension of resource file
|
||||||
|
|
||||||
|
* \brief Get correct resource type from file extension of resource.
|
||||||
|
****************************************************************************/
|
||||||
|
static AssetExtension GetExtensionFromType(AssetType) noexcept;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param Create class containing meta data from meta file
|
||||||
|
|
||||||
|
* \brief path to meta data file
|
||||||
|
****************************************************************************/
|
||||||
|
static SHAsset RetrieveMetaData(AssetPath const&) noexcept;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param Asset meta data to be written into
|
||||||
|
* \param Path to be written into
|
||||||
|
|
||||||
|
* \brief Writes meta data into text file
|
||||||
|
****************************************************************************/
|
||||||
|
static void WriteMetaData(SHAsset const&) noexcept;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !SH_RESOURCE_META_HANDLER_H
|
|
@ -0,0 +1,51 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| STL Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHBaseCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~SHBaseCommand() = default;
|
||||||
|
virtual void Execute() {}
|
||||||
|
virtual void Undo() {}
|
||||||
|
virtual void Merge(std::shared_ptr<SHBaseCommand>) {}
|
||||||
|
};//struct SHBaseCommand
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class SHCommand : SHBaseCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef std::function<void(T const&)> SetterFunction;
|
||||||
|
|
||||||
|
SHCommand(T const& oldVal, T const& value, SetterFunction setFnc)
|
||||||
|
: oldValue(oldVal), newValue(value), set(setFnc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Execute() override
|
||||||
|
{
|
||||||
|
set(newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Undo() override
|
||||||
|
{
|
||||||
|
set(oldValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Merge(std::shared_ptr<SHBaseCommand> newCommand) override
|
||||||
|
{
|
||||||
|
newValue = std::reinterpret_pointer_cast<SHCommand>(newCommand)->newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
T oldValue;
|
||||||
|
T newValue;
|
||||||
|
SetterFunction set;
|
||||||
|
};
|
||||||
|
}//namespace SHADE
|
|
@ -0,0 +1,57 @@
|
||||||
|
//#==============================================================#
|
||||||
|
//|| PCH Include ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "SHpch.h"
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| SHADE Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "SHCommandManager.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
SHCommandManager::CommandStack SHCommandManager::undoStack{};
|
||||||
|
SHCommandManager::CommandStack SHCommandManager::redoStack{};
|
||||||
|
|
||||||
|
void SHCommandManager::PerformCommand(CommandPtr commandPtr, bool const& overrideValue)
|
||||||
|
{
|
||||||
|
redoStack = CommandStack();
|
||||||
|
commandPtr->Execute();
|
||||||
|
if (overrideValue && !undoStack.empty())
|
||||||
|
{
|
||||||
|
undoStack.top()->Merge(commandPtr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
undoStack.push(commandPtr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHCommandManager::UndoCommand()
|
||||||
|
{
|
||||||
|
if (undoStack.empty())
|
||||||
|
return;
|
||||||
|
undoStack.top()->Undo();
|
||||||
|
redoStack.push(undoStack.top());
|
||||||
|
undoStack.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHCommandManager::RedoCommand()
|
||||||
|
{
|
||||||
|
if (redoStack.empty())
|
||||||
|
return;
|
||||||
|
redoStack.top()->Execute();
|
||||||
|
undoStack.push(redoStack.top());
|
||||||
|
redoStack.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t SHCommandManager::GetUndoStackSize()
|
||||||
|
{
|
||||||
|
return undoStack.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t SHCommandManager::GetRedoStackSize()
|
||||||
|
{
|
||||||
|
return redoStack.size();
|
||||||
|
}
|
||||||
|
}//namespace SHADE
|
|
@ -0,0 +1,34 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| STL Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <stack>
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| SHADE Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "SHCommand.hpp"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHCommandManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Type Aliases ||
|
||||||
|
//#==============================================================#
|
||||||
|
using CommandPtr = std::shared_ptr<SHBaseCommand>;
|
||||||
|
using CommandStack = std::stack<CommandPtr>;
|
||||||
|
|
||||||
|
static void PerformCommand(CommandPtr commandPtr, bool const& overrideValue = false);
|
||||||
|
static void UndoCommand();
|
||||||
|
static void RedoCommand();
|
||||||
|
static std::size_t GetUndoStackSize();
|
||||||
|
static std::size_t GetRedoStackSize();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static CommandStack undoStack;
|
||||||
|
static CommandStack redoStack;
|
||||||
|
};
|
||||||
|
}//namespace SHADE
|
|
@ -0,0 +1,21 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
|
||||||
|
#include "SHDragDrop.hpp"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
bool SHDragDrop::hasDragDrop = false;
|
||||||
|
|
||||||
|
bool SHDragDrop::BeginSource(ImGuiDragDropFlags const flags)
|
||||||
|
{ return ImGui::BeginDragDropSource(flags); }
|
||||||
|
|
||||||
|
void SHDragDrop::EndSource()
|
||||||
|
{ ImGui::EndDragDropSource();}
|
||||||
|
|
||||||
|
bool SHDragDrop::BeginTarget()
|
||||||
|
{ return ImGui::BeginDragDropTarget(); }
|
||||||
|
|
||||||
|
void SHDragDrop::EndTarget()
|
||||||
|
{ ImGui::EndDragDropTarget(); hasDragDrop = false;}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string_view>
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
//TODO: Convert to RTTR?
|
||||||
|
constexpr auto DRAG_EID = "DragEID";
|
||||||
|
constexpr auto DRAG_RESOURCE = "DragResource";
|
||||||
|
|
||||||
|
|
||||||
|
struct SHDragDrop
|
||||||
|
{
|
||||||
|
static bool BeginSource(ImGuiDragDropFlags const flags = 0);
|
||||||
|
/**
|
||||||
|
* \brief Ends the DragDrop Source. ONLY CALL IF BeginSource returns true
|
||||||
|
*/
|
||||||
|
static void EndSource();
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static bool SetPayload(std::string_view const type, T* object, ImGuiCond const cond = 0)
|
||||||
|
{
|
||||||
|
hasDragDrop = ImGui::SetDragDropPayload(type.data(), static_cast<void*>(object), sizeof(T), cond);
|
||||||
|
return hasDragDrop;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool BeginTarget();
|
||||||
|
/**
|
||||||
|
* \brief Ends the DragDrop Target. ONLY CALL IF BeginTarget returns true
|
||||||
|
*/
|
||||||
|
static void EndTarget();
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static T* AcceptPayload(std::string_view const type, ImGuiDragDropFlags const flags = 0)
|
||||||
|
{
|
||||||
|
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload(type.data(), flags))
|
||||||
|
return static_cast<T*>(payload->Data);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool hasDragDrop;
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,212 @@
|
||||||
|
//#==============================================================#
|
||||||
|
//|| PCH Include ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "SHpch.h"
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| SHADE Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "Editor/SHImGuiHelpers.hpp"
|
||||||
|
#include "Editor/SHEditorWidgets.hpp"
|
||||||
|
#include "SHHierarchyPanel.h"
|
||||||
|
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||||
|
#include "Editor/SHEditor.hpp"
|
||||||
|
#include "Scene/SHSceneManager.h"
|
||||||
|
#include "Editor/DragDrop/SHDragDrop.hpp"
|
||||||
|
#include "Tools/SHException.h"
|
||||||
|
#include "Editor/IconsMaterialDesign.h"
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Library Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Public Member Functions ||
|
||||||
|
//#==============================================================#
|
||||||
|
SHHierarchyPanel::SHHierarchyPanel()
|
||||||
|
:SHEditorWindow("Hierarchy Panel", ImGuiWindowFlags_MenuBar)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHHierarchyPanel::Init()
|
||||||
|
{
|
||||||
|
SHEditorWindow::Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHHierarchyPanel::Update()
|
||||||
|
{
|
||||||
|
SHEditorWindow::Update();
|
||||||
|
|
||||||
|
isAnyNodeSelected = false;
|
||||||
|
|
||||||
|
if (Begin())
|
||||||
|
{
|
||||||
|
DrawMenuBar();
|
||||||
|
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
|
if(const auto root = sceneGraph.GetRoot())
|
||||||
|
{
|
||||||
|
auto const& children = root->GetChildren();
|
||||||
|
for (const auto child : children)
|
||||||
|
{
|
||||||
|
RecursivelyDrawEntityNode(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("Scene Graph root is null! Unable to render hierarchy.")
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ImGui::IsWindowHovered() && !SHDragDrop::hasDragDrop && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left))
|
||||||
|
{
|
||||||
|
SHEditor::selectedEntities.clear();
|
||||||
|
}
|
||||||
|
ImGui::SeparatorEx(ImGuiSeparatorFlags_Horizontal);
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHHierarchyPanel::Exit()
|
||||||
|
{
|
||||||
|
SHEditorWindow::Exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Private Member Functions ||
|
||||||
|
//#==============================================================#
|
||||||
|
void SHHierarchyPanel::DrawMenuBar() const noexcept
|
||||||
|
{
|
||||||
|
if (ImGui::BeginMenuBar())
|
||||||
|
{
|
||||||
|
if (ImGui::SmallButton(ICON_MD_ADD))
|
||||||
|
{
|
||||||
|
SHEntityManager::CreateEntity();
|
||||||
|
}
|
||||||
|
if (ImGui::IsItemHovered())
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text("Add Entity");
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
ImGui::EndMenuBar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImRect SHHierarchyPanel::RecursivelyDrawEntityNode(SHSceneNode* currentNode)
|
||||||
|
{
|
||||||
|
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
|
|
||||||
|
//Get node data (Children, eid, selected)
|
||||||
|
auto& children = currentNode->GetChildren();
|
||||||
|
EntityID eid = currentNode->GetEntityID();
|
||||||
|
const bool isSelected = (std::ranges::find(SHEditor::selectedEntities, eid) != SHEditor::selectedEntities.end());
|
||||||
|
|
||||||
|
const ImGuiTreeNodeFlags nodeFlags = ((isSelected) ? ImGuiTreeNodeFlags_Selected : 0) | ((children.empty()) ? ImGuiTreeNodeFlags_Leaf : ImGuiTreeNodeFlags_OpenOnArrow);
|
||||||
|
|
||||||
|
//bool highlighted = false;
|
||||||
|
//if(highlighted)
|
||||||
|
//{
|
||||||
|
// ImGui::PushStyleColor(ImGuiCol_Text, highlightedColor);
|
||||||
|
//}
|
||||||
|
|
||||||
|
auto* entity = SHEntityManager::GetEntityByID(currentNode->GetEntityID());
|
||||||
|
//Draw Node
|
||||||
|
bool isNodeOpen = ImGui::TreeNodeEx((void*)eid, nodeFlags, "%u: %s", EntityHandleGenerator::GetIndex(eid), entity->name.c_str());
|
||||||
|
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
||||||
|
|
||||||
|
//Check For Begin Drag
|
||||||
|
if (SHDragDrop::BeginSource())
|
||||||
|
{
|
||||||
|
ImGui::Text("Moving EID: %zu", eid);
|
||||||
|
SHDragDrop::SetPayload<EntityID>(DRAG_EID, &eid);
|
||||||
|
SHDragDrop::EndSource();
|
||||||
|
}
|
||||||
|
else if (SHDragDrop::BeginTarget()) //If Received DragDrop
|
||||||
|
{
|
||||||
|
if (const EntityID* eidPayload = SHDragDrop::AcceptPayload<EntityID>(DRAG_EID)) //If payload is valid
|
||||||
|
{
|
||||||
|
EntityID const dropEID = *eidPayload;
|
||||||
|
if(!sceneGraph.GetChild(dropEID, eid))
|
||||||
|
sceneGraph.SetParent(dropEID, eid); //Set dropEID parent to eid (belonging to current Node)
|
||||||
|
SHDragDrop::EndTarget();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Context menu
|
||||||
|
if(ImGui::BeginPopupContextItem(std::to_string(eid).c_str()))
|
||||||
|
{
|
||||||
|
if(!isSelected)
|
||||||
|
{
|
||||||
|
SHEditor::selectedEntities.clear();
|
||||||
|
SHEditor::selectedEntities.push_back(eid);
|
||||||
|
}
|
||||||
|
if(ImGui::Selectable(std::format("{} Delete", ICON_MD_DELETE).data()))
|
||||||
|
{
|
||||||
|
SHEntityManager::DestroyEntity(eid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if((currentNode->GetParent() != sceneGraph.GetRoot()) && ImGui::Selectable(std::format("{} Unparent Selected", ICON_MD_NORTH_WEST).data()))
|
||||||
|
{
|
||||||
|
sceneGraph.SetParent(currentNode->GetEntityID(), nullptr);
|
||||||
|
}
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Handle node selection
|
||||||
|
if (ImGui::IsItemHovered())
|
||||||
|
{
|
||||||
|
if (ImGui::IsMouseReleased(ImGuiMouseButton_Left))
|
||||||
|
{
|
||||||
|
if (!isSelected)
|
||||||
|
{
|
||||||
|
if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
|
||||||
|
SHEditor::selectedEntities.clear();
|
||||||
|
SHEditor::selectedEntities.push_back(eid);
|
||||||
|
}//if not selected
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
|
||||||
|
{
|
||||||
|
auto it = std::ranges::remove(SHEditor::selectedEntities, eid).begin();
|
||||||
|
}//if mod ctrl is not pressed
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHEditor::selectedEntities.clear();
|
||||||
|
SHEditor::selectedEntities.push_back(eid);
|
||||||
|
}
|
||||||
|
}//if selected
|
||||||
|
}//if left mouse button released
|
||||||
|
}//if item hovered
|
||||||
|
|
||||||
|
if (isNodeOpen)
|
||||||
|
{
|
||||||
|
const ImColor treeLineColor = ImGui::GetColorU32(ImGuiCol_CheckMark);
|
||||||
|
const float horizontalOffset = 0.0f;
|
||||||
|
ImDrawList* drawList = ImGui::GetWindowDrawList();
|
||||||
|
|
||||||
|
ImVec2 vertLineStart = ImGui::GetCursorScreenPos();
|
||||||
|
vertLineStart.x += horizontalOffset;
|
||||||
|
ImVec2 vertLineEnd = vertLineStart;
|
||||||
|
|
||||||
|
for (const auto child : children)
|
||||||
|
{
|
||||||
|
const float horizontalLineSize = 8.0f;
|
||||||
|
const ImRect childRect = RecursivelyDrawEntityNode(child);
|
||||||
|
const float midPoint = (childRect.Min.y + childRect.Max.y) * 0.5f;
|
||||||
|
drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 2);
|
||||||
|
vertLineEnd.y = midPoint;
|
||||||
|
}
|
||||||
|
drawList->AddLine(vertLineStart, vertLineEnd, treeLineColor, 2);
|
||||||
|
ImGui::TreePop();
|
||||||
|
}
|
||||||
|
return nodeRect;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHHierarchyPanel::CreateChildEntity(EntityID parentEID) const noexcept
|
||||||
|
{
|
||||||
|
SHEntityManager::CreateEntity(MAX_EID, "DefaultChild", parentEID);
|
||||||
|
}
|
||||||
|
}//namespace SHADE
|
|
@ -0,0 +1,33 @@
|
||||||
|
#pragma once
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Library Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| SHADE Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "imgui_internal.h"
|
||||||
|
#include "ECS_Base/SHECSMacros.h"
|
||||||
|
#include "Editor/EditorWindow/SHEditorWindow.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHSceneNode;
|
||||||
|
constexpr ImVec4 highlightedColor = ImVec4(0.f, 0.7f, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
class SHHierarchyPanel final : public SHEditorWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SHHierarchyPanel();
|
||||||
|
void Init() override;
|
||||||
|
void Update() override;
|
||||||
|
void Exit() override;
|
||||||
|
private:
|
||||||
|
void DrawMenuBar() const noexcept;
|
||||||
|
ImRect RecursivelyDrawEntityNode(SHSceneNode*);
|
||||||
|
void CreateChildEntity(EntityID parentEID) const noexcept;
|
||||||
|
std::string filter;
|
||||||
|
bool isAnyNodeSelected = false;
|
||||||
|
};//class SHHierarchyPanel
|
||||||
|
}//namespace SHADE
|
|
@ -0,0 +1,70 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Library Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <imgui.h>
|
||||||
|
#include <rttr/type>
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| SHADE Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "Editor/IconsMaterialDesign.h"
|
||||||
|
#include "ECS_Base/Components/SHComponent.h"
|
||||||
|
#include "Editor/SHEditorWidgets.hpp"
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
template<typename T, std::enable_if_t<std::is_base_of<SHComponent, T>::value, bool> = true>
|
||||||
|
static void DrawContextMenu(T* component)
|
||||||
|
{
|
||||||
|
if(!component)
|
||||||
|
return;
|
||||||
|
rttr::string_view componentName = rttr::type::get<T>().get_name();
|
||||||
|
|
||||||
|
if (ImGui::BeginPopupContextItem(componentName.data()))
|
||||||
|
{
|
||||||
|
|
||||||
|
if (ImGui::Selectable(std::format("{} Copy {}", ICON_MD_CONTENT_COPY, componentName.data()).data()))
|
||||||
|
{
|
||||||
|
//SHClipboardUtil::WriteStringToClipboard(SHClipboardUtil::CFNAME::CFCOMPONENT, SHComponentToString(component));
|
||||||
|
}
|
||||||
|
if (ImGui::Selectable(std::format("{} Paste {}", ICON_MD_CONTENT_PASTE, componentName.data()).data()))
|
||||||
|
{
|
||||||
|
//SHStringToComponent(component, SHClipboardUtil::ReadStringFromClipboard(SHClipboardUtil::CFNAME::CFCOMPONENT));
|
||||||
|
}
|
||||||
|
if (ImGui::Selectable(std::format("{} Delete {}", ICON_MD_DELETE, componentName.data()).data()))
|
||||||
|
{
|
||||||
|
SHComponentManager::RemoveComponent<T>(component->GetEID());
|
||||||
|
}
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template<typename T, std::enable_if_t<std::is_base_of_v<SHComponent, T>, bool> = true>
|
||||||
|
static void DrawComponent(T* component)
|
||||||
|
{
|
||||||
|
if (!component)
|
||||||
|
return;
|
||||||
|
auto componentType = rttr::type::get(*component);
|
||||||
|
CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; });
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
||||||
|
{
|
||||||
|
DrawContextMenu(component);
|
||||||
|
auto const& properties = componentType.get_properties();
|
||||||
|
for (auto const& property : properties)
|
||||||
|
{
|
||||||
|
auto const& type = property.get_type();
|
||||||
|
|
||||||
|
if (type == rttr::type::get<SHVec4>())
|
||||||
|
{
|
||||||
|
DragVec4(property.get_name().data(), { "X", "Y", "Z", "W" }, [component, property]() {return property.get_value(component).template convert<SHVec4>(); }, [component, property](SHVec4 vec) {return property.set_value(component, vec); });
|
||||||
|
}
|
||||||
|
else if (type == rttr::type::get<SHVec3>())
|
||||||
|
{
|
||||||
|
DragVec3(property.get_name().data(), { "X", "Y", "Z" }, [component, property]() {return property.get_value(component).template convert<SHVec3>(); }, [component, property](SHVec3 vec) {return property.set_value(component, vec); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else DrawContextMenu(component);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
|
||||||
|
#include "SHEditorInspector.h"
|
||||||
|
|
||||||
|
#include "ECS_Base/SHECSMacros.h"
|
||||||
|
#include "ECS_Base/Entity/SHEntity.h"
|
||||||
|
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||||
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
|
|
||||||
|
#include "Editor/SHEditor.hpp"
|
||||||
|
#include "Editor/SHImGuiHelpers.hpp"
|
||||||
|
#include "Editor/SHEditorWidgets.hpp"
|
||||||
|
#include "SHEditorComponentView.hpp"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
template<typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||||
|
void DrawAddComponentButton(EntityID const& eid)
|
||||||
|
{
|
||||||
|
if(!SHComponentManager::HasComponent<ComponentType>(eid) && ImGui::Selectable(std::format("Add {}", rttr::type::get<ComponentType>().get_name().data()).data()))
|
||||||
|
{
|
||||||
|
SHComponentManager::AddComponent<ComponentType>(eid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SHEditorInspector::SHEditorInspector()
|
||||||
|
:SHEditorWindow("Inspector", ImGuiWindowFlags_MenuBar)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorInspector::Init()
|
||||||
|
{
|
||||||
|
SHEditorWindow::Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorInspector::Update()
|
||||||
|
{
|
||||||
|
SHEditorWindow::Update();
|
||||||
|
if (Begin())
|
||||||
|
{
|
||||||
|
if (!SHEditor::selectedEntities.empty())
|
||||||
|
{
|
||||||
|
EntityID const& eid = SHEditor::selectedEntities[0];
|
||||||
|
SHEntity* entity = SHEntityManager::GetEntityByID(eid);
|
||||||
|
|
||||||
|
ImGui::TextColored(ImGuiColors::green, "EID: %zu", eid);
|
||||||
|
CheckBox("##IsActive", [entity]()->bool {return entity->GetActive(); }, [entity](bool const& active) {entity->SetActive(active); });
|
||||||
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
ImGui::InputText("##EntityName", &entity->name);
|
||||||
|
|
||||||
|
if (auto transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(eid))
|
||||||
|
{
|
||||||
|
DrawComponent(transformComponent);
|
||||||
|
}
|
||||||
|
ImGui::Separator();
|
||||||
|
if(ImGui::BeginMenu(std::format("{} Add Component", ICON_MD_LIBRARY_ADD).data()))
|
||||||
|
{
|
||||||
|
DrawAddComponentButton<SHTransformComponent>(eid);
|
||||||
|
DrawAddComponentButton<SHRenderable>(eid);
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorInspector::Exit()
|
||||||
|
{
|
||||||
|
SHEditorWindow::Exit();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Library Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <imgui.h>
|
||||||
|
#include <rttr/type>
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| SHADE Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "Editor/EditorWindow/SHEditorWindow.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHComponent;
|
||||||
|
|
||||||
|
class SHEditorInspector final : public SHEditorWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SHEditorInspector();
|
||||||
|
void Init() override;
|
||||||
|
void Update() override;
|
||||||
|
void Exit() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,130 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| SHADE Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "SHEditorMenuBar.h"
|
||||||
|
#include "Editor/IconsMaterialDesign.h"
|
||||||
|
#include "Editor/Command/SHCommandManager.h"
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Library Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <imgui.h>
|
||||||
|
#include <imgui_internal.h>
|
||||||
|
#include <rttr/type>
|
||||||
|
|
||||||
|
#include "Editor/SHEditor.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
constexpr ImGuiWindowFlags editorMenuBarFlags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse |
|
||||||
|
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDocking |
|
||||||
|
ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
|
||||||
|
|
||||||
|
constexpr ImGuiWindowFlags dockspaceFlags = ImGuiDockNodeFlags_PassthruCentralNode;
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Public Member Functions ||
|
||||||
|
//#==============================================================#
|
||||||
|
SHEditorMenuBar::SHEditorMenuBar()
|
||||||
|
:SHEditorWindow("SHEditorMenuBar", editorMenuBarFlags | ImGuiWindowFlags_NoBackground)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorMenuBar::Init()
|
||||||
|
{
|
||||||
|
SHEditorWindow::Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorMenuBar::Update()
|
||||||
|
{
|
||||||
|
SHEditorWindow::Update();
|
||||||
|
DrawMainMenuBar();
|
||||||
|
DrawSecondaryBar();
|
||||||
|
DrawStatusBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Private Member Functions ||
|
||||||
|
//#==============================================================#
|
||||||
|
void SHEditorMenuBar::DrawMainMenuBar() noexcept
|
||||||
|
{
|
||||||
|
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||||
|
|
||||||
|
ImGui::SetNextWindowPos(viewport->WorkPos);
|
||||||
|
ImGui::SetNextWindowSize(viewport->WorkSize);
|
||||||
|
ImGui::SetNextWindowViewport(viewport->ID);
|
||||||
|
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, { ImVec2(0.0f, 0.0f) });
|
||||||
|
if (Begin())
|
||||||
|
{
|
||||||
|
ImGui::PopStyleVar(3);
|
||||||
|
|
||||||
|
if (ImGui::BeginMainMenuBar())
|
||||||
|
{
|
||||||
|
if (ImGui::BeginMenu("File"))
|
||||||
|
{
|
||||||
|
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
if(ImGui::BeginMenu("Edit"))
|
||||||
|
{
|
||||||
|
ImGui::BeginDisabled(!SHCommandManager::GetUndoStackSize());
|
||||||
|
if(ImGui::Button(std::format("{} Undo", ICON_MD_UNDO).data()))
|
||||||
|
{
|
||||||
|
SHCommandManager::UndoCommand();
|
||||||
|
}
|
||||||
|
ImGui::EndDisabled();
|
||||||
|
ImGui::BeginDisabled(!SHCommandManager::GetRedoStackSize());
|
||||||
|
if(ImGui::Button(std::format("{} Redo", ICON_MD_REDO).data()))
|
||||||
|
{
|
||||||
|
SHCommandManager::RedoCommand();
|
||||||
|
}
|
||||||
|
ImGui::EndDisabled();
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
if(ImGui::BeginMenu("Theme"))
|
||||||
|
{
|
||||||
|
auto styles = rttr::type::get<SHEditor::Style>().get_enumeration();
|
||||||
|
auto values = styles.get_values();
|
||||||
|
for (auto style : values)
|
||||||
|
{
|
||||||
|
if(ImGui::Selectable(style.to_string().c_str()))
|
||||||
|
{
|
||||||
|
SHEditor::SetStyle(style.convert<SHEditor::Style>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
ImGui::EndMainMenuBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
const ImGuiID dockspace_id = ImGui::GetID("DockSpace");
|
||||||
|
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspaceFlags);
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorMenuBar::DrawSecondaryBar() const noexcept
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorMenuBar::DrawStatusBar() const noexcept
|
||||||
|
{
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, { ImVec2(0.0f, 0.0f) });
|
||||||
|
if (ImGui::BeginViewportSideBar("MainStatusBar", ImGui::GetMainViewport(), ImGuiDir_Down, menuBarHeight, editorMenuBarFlags))
|
||||||
|
{
|
||||||
|
ImGui::Text("Entity count: ");
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
ImGui::PopStyleVar(3);
|
||||||
|
|
||||||
|
}
|
||||||
|
}//namespace SHADE
|
|
@ -0,0 +1,22 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| SHADE Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "Editor/EditorWindow/SHEditorWindow.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHEditorMenuBar final : public SHEditorWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SHEditorMenuBar();
|
||||||
|
virtual void Init() override;
|
||||||
|
virtual void Update() override;
|
||||||
|
private:
|
||||||
|
void DrawMainMenuBar() noexcept;
|
||||||
|
void DrawSecondaryBar() const noexcept;
|
||||||
|
void DrawStatusBar() const noexcept;
|
||||||
|
float menuBarHeight = 20.0f;
|
||||||
|
};//class SHEditorMenuBar
|
||||||
|
}//namespace SHADE
|
|
@ -0,0 +1,46 @@
|
||||||
|
//#==============================================================#
|
||||||
|
//|| PCH Include ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "SHpch.h"
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| SHADE Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "SHEditorWindow.h"
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Library Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Public Member Functions ||
|
||||||
|
//#==============================================================#
|
||||||
|
SHEditorWindow::SHEditorWindow(std::string_view const& name, ImGuiWindowFlags const& inFlags)
|
||||||
|
: isOpen(true), windowName(name), windowFlags(inFlags), io(ImGui::GetIO())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorWindow::Init()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorWindow::Update()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorWindow::Exit()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Protected Member Functions ||
|
||||||
|
//#==============================================================#
|
||||||
|
bool SHEditorWindow::Begin()
|
||||||
|
{
|
||||||
|
return ImGui::Begin(windowName.data(), &isOpen, windowFlags);
|
||||||
|
}
|
||||||
|
}//namespace SHADE
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| STL Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Forward Declarations ||
|
||||||
|
//#==============================================================#
|
||||||
|
struct ImGuiIO;
|
||||||
|
typedef int ImGuiWindowFlags;
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHEditorWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SHEditorWindow(std::string_view const& name, ImGuiWindowFlags const& inFlags);
|
||||||
|
virtual ~SHEditorWindow() = default;
|
||||||
|
virtual void Init();
|
||||||
|
virtual void Update();
|
||||||
|
virtual void Exit();
|
||||||
|
bool isOpen = false;
|
||||||
|
std::string_view windowName;
|
||||||
|
protected:
|
||||||
|
virtual bool Begin();
|
||||||
|
ImGuiWindowFlags windowFlags = 0;
|
||||||
|
ImGuiIO& io;
|
||||||
|
};//class SHEditorWindow
|
||||||
|
}//namespace SHADE
|
|
@ -0,0 +1,4 @@
|
||||||
|
#pragma once
|
||||||
|
#include "MenuBar/SHEditorMenuBar.h" //Menu Bar
|
||||||
|
#include "HierarchyPanel/SHHierarchyPanel.h" //Hierarchy Panel
|
||||||
|
#include "Inspector/SHEditorInspector.h" //Inspector
|
File diff suppressed because it is too large
Load Diff
|
@ -1,79 +1,125 @@
|
||||||
|
//#==============================================================#
|
||||||
|
//|| PCH Include ||
|
||||||
|
//#==============================================================#
|
||||||
#include "SHpch.h"
|
#include "SHpch.h"
|
||||||
#include "SHEditor.h"
|
|
||||||
|
|
||||||
#include <imgui.h>
|
#include "IconsMaterialDesign.h"
|
||||||
|
#include "DragDrop/SHDragDrop.hpp"
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| SHADE Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "Tools/SHLogger.h"
|
||||||
|
#include "Tools/SHException.h"
|
||||||
|
|
||||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
|
||||||
#include "Graphics/Instance/SHVkInstance.h"
|
#include "Graphics/Instance/SHVkInstance.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
||||||
#include "Graphics/Swapchain/SHVkSwapchain.h"
|
#include "Graphics/Swapchain/SHVkSwapchain.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHViewport.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHRenderer.h"
|
||||||
|
|
||||||
//IMGUI Backend includes
|
#include "SHEditor.hpp"
|
||||||
|
#include "SHEditorWidgets.hpp"
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Editor Window Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "EditorWindow/SHEditorWindowIncludes.h"
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Library Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <imgui.h>
|
||||||
|
#include <SDL.h>
|
||||||
|
#include <rttr/registration>
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| ImGui Backend Includes ||
|
||||||
|
//#==============================================================#
|
||||||
#include <backends/imgui_impl_sdl.h>
|
#include <backends/imgui_impl_sdl.h>
|
||||||
#include <backends/imgui_impl_vulkan.h>
|
#include <backends/imgui_impl_vulkan.h>
|
||||||
|
|
||||||
|
RTTR_REGISTRATION
|
||||||
|
{
|
||||||
|
using namespace SHADE;
|
||||||
|
using namespace rttr;
|
||||||
|
registration::enumeration<SHEditor::Style>("Style")
|
||||||
|
(
|
||||||
|
value("SHADE", SHEditor::Style::SHADE),
|
||||||
|
value("DARK", SHEditor::Style::DARK),
|
||||||
|
value("LIGHT", SHEditor::Style::LIGHT),
|
||||||
|
value("CLASSIC", SHEditor::Style::CLASSIC)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Initialise static members ||
|
||||||
|
//#==============================================================#
|
||||||
Handle<SHVkCommandPool> SHEditor::imguiCommandPool;
|
Handle<SHVkCommandPool> SHEditor::imguiCommandPool;
|
||||||
Handle<SHVkCommandBuffer> SHEditor::imguiCommandBuffer;
|
Handle<SHVkCommandBuffer> SHEditor::imguiCommandBuffer;
|
||||||
|
SHEditor::EditorWindowMap SHEditor::editorWindows{};
|
||||||
|
SHEditor::EditorWindowID SHEditor::windowCount{};
|
||||||
|
std::vector<EntityID> SHEditor::selectedEntities;
|
||||||
|
|
||||||
void SHEditor::Initialise(SDL_Window* sdlWindow)
|
//#==============================================================#
|
||||||
|
//|| Public Member Functions ||
|
||||||
|
//#==============================================================#
|
||||||
|
void SHEditor::Initialise(SDL_Window* const sdlWindow)
|
||||||
{
|
{
|
||||||
IMGUI_CHECKVERSION();
|
IMGUI_CHECKVERSION();
|
||||||
ImGui::CreateContext();
|
if(auto context = ImGui::CreateContext())
|
||||||
|
{
|
||||||
|
if(context == nullptr)
|
||||||
|
{
|
||||||
|
SHLOG_CRITICAL("Failed to create ImGui Context")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||||
|
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
|
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; //Enable for Multi-Viewports
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; //Enable docking
|
||||||
|
|
||||||
ImGui_ImplSDL2_InitForVulkan(sdlWindow);
|
InitFonts();
|
||||||
|
InitBackend(sdlWindow);
|
||||||
|
|
||||||
auto* gfxSystem = reinterpret_cast<SHGraphicsSystem*>(SHSystemManager::GetSystem<SHGraphicsSystem>());
|
SetStyle(Style::SHADE);
|
||||||
|
|
||||||
ImGui_ImplVulkan_InitInfo initInfo{};
|
//Add editor windows
|
||||||
initInfo.Instance = SHVkInstance::GetVkInstance();
|
CreateEditorWindow<SHEditorMenuBar>();
|
||||||
initInfo.PhysicalDevice = gfxSystem->GetPhysicalDevice()->GetVkPhysicalDevice();
|
CreateEditorWindow<SHHierarchyPanel>();
|
||||||
initInfo.Device = gfxSystem->GetDevice()->GetVkLogicalDevice();
|
CreateEditorWindow<SHEditorInspector>();
|
||||||
initInfo.Queue = gfxSystem->GetQueue()->GetVkQueue();
|
|
||||||
initInfo.DescriptorPool = gfxSystem->GetDescriptorPool()->GetVkHandle();
|
|
||||||
initInfo.MinImageCount = initInfo.ImageCount = gfxSystem->GetSwapchain()->GetNumImages();
|
|
||||||
initInfo.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
|
|
||||||
|
|
||||||
imguiCommandPool = gfxSystem->GetDevice()->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true);
|
SHLOG_INFO("Successfully initialised SHADE Engine Editor")
|
||||||
imguiCommandBuffer = imguiCommandPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
|
||||||
|
|
||||||
/*auto renderPass = gfxSystem->GetRenderGraph().GetNode("ImGui Node")->GetRenderpass();
|
|
||||||
ImGui_ImplVulkan_Init(&initInfo, renderPass->GetVkRenderpass());*/
|
|
||||||
|
|
||||||
imguiCommandBuffer->BeginRecording();
|
|
||||||
ImGui_ImplVulkan_CreateFontsTexture(imguiCommandBuffer->GetVkCommandBuffer());
|
|
||||||
imguiCommandBuffer->EndRecording();
|
|
||||||
gfxSystem->GetQueue()->SubmitCommandBuffer({imguiCommandBuffer}, {}, {}, vk::PipelineStageFlagBits::eNone, {});
|
|
||||||
|
|
||||||
ImGui_ImplVulkan_DestroyFontUploadObjects();
|
|
||||||
|
|
||||||
/*gfxSystem->GetRenderGraph().GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle<SHVkCommandBuffer>& cmd) {
|
|
||||||
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->GetVkCommandBuffer());
|
|
||||||
});*/
|
|
||||||
|
|
||||||
//ImGuiIO& io = ImGui::GetIO();
|
|
||||||
//int w, h;
|
|
||||||
//SDL_GetWindowSize(sdlWindow, &w, &h);
|
|
||||||
//io.DisplaySize = { static_cast<float>(w),static_cast<float>(h)};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHEditor::PreRender()
|
void SHEditor::Update(float const dt)
|
||||||
{
|
{
|
||||||
|
(void)dt;
|
||||||
NewFrame();
|
NewFrame();
|
||||||
|
|
||||||
ImGui::ShowDemoWindow();
|
for (const auto& window : editorWindows | std::views::values)
|
||||||
ImGui::Begin("Your mom");
|
|
||||||
if (ImGui::Button("OP"))
|
|
||||||
{
|
{
|
||||||
std::cout << "HEHEHEOHEIOHIEOH\n";
|
window->Update();
|
||||||
}
|
}
|
||||||
ImGui::End();
|
|
||||||
|
if(ImGui::IsKeyDown(ImGuiKey_LeftShift) && ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_Z))
|
||||||
|
{
|
||||||
|
SHCommandManager::RedoCommand();
|
||||||
|
}
|
||||||
|
else if(ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_Z))
|
||||||
|
{
|
||||||
|
SHCommandManager::UndoCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Render();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHEditor::Render()
|
void SHEditor::Render()
|
||||||
|
@ -87,6 +133,18 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHEditor::InitFonts() noexcept
|
||||||
|
{
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
ImFont* mainFont = io.Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/Segoe UI.ttf", 20.f);//TODO: Change to config based assets path
|
||||||
|
|
||||||
|
static const ImWchar icon_ranges[] = { ICON_MIN_MD, ICON_MAX_16_MD, 0 };
|
||||||
|
ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.PixelSnapH = true;
|
||||||
|
ImFont* UIFont = io.Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/MaterialIcons-Regular.ttf", 20.f, &icons_config, icon_ranges); //TODO: Change to config based assets path
|
||||||
|
|
||||||
|
io.Fonts->Build();
|
||||||
|
}
|
||||||
|
|
||||||
void SHEditor::Exit()
|
void SHEditor::Exit()
|
||||||
{
|
{
|
||||||
ImGui_ImplVulkan_Shutdown();
|
ImGui_ImplVulkan_Shutdown();
|
||||||
|
@ -94,19 +152,164 @@ namespace SHADE
|
||||||
ImGui::DestroyContext();
|
ImGui::DestroyContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHEditor::SetStyle(Style style)
|
||||||
void SHEditor::InitBackend()
|
|
||||||
{
|
{
|
||||||
|
switch (style)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case Style::SHADE:
|
||||||
|
{
|
||||||
|
ImGuiStyle& imStyle = ImGui::GetStyle();
|
||||||
|
ImVec4* colors = imStyle.Colors;
|
||||||
|
colors[ImGuiCol_Text] = ImVec4(0.706f, 0.729f, 0.757f, 1.00f);
|
||||||
|
colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f);
|
||||||
|
colors[ImGuiCol_WindowBg] = ImVec4(0.172f, 0.184f, 0.203f, 1.f);
|
||||||
|
colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
|
||||||
|
colors[ImGuiCol_PopupBg] = ImVec4(0.19f, 0.19f, 0.19f, 0.92f);
|
||||||
|
colors[ImGuiCol_Border] = ImVec4(0.19f, 0.19f, 0.19f, 0.29f);
|
||||||
|
colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.24f);
|
||||||
|
colors[ImGuiCol_FrameBg] = ImVec4(0.05f, 0.05f, 0.05f, 0.54f);
|
||||||
|
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.19f, 0.19f, 0.19f, 0.54f);
|
||||||
|
colors[ImGuiCol_FrameBgActive] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f);
|
||||||
|
colors[ImGuiCol_TitleBg] = colors[ImGuiCol_WindowBg];
|
||||||
|
colors[ImGuiCol_TitleBgActive] = colors[ImGuiCol_WindowBg];
|
||||||
|
colors[ImGuiCol_TitleBgCollapsed] = colors[ImGuiCol_WindowBg];
|
||||||
|
colors[ImGuiCol_MenuBarBg] = ImVec4(0.129f, 0.141f, 0.157f, 1.f);
|
||||||
|
colors[ImGuiCol_ScrollbarBg] = colors[ImGuiCol_WindowBg];
|
||||||
|
colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.34f, 0.34f, 0.34f, 0.54f);
|
||||||
|
colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.40f, 0.40f, 0.40f, 0.54f);
|
||||||
|
colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.56f, 0.56f, 0.56f, 0.54f);
|
||||||
|
colors[ImGuiCol_CheckMark] = ImVec4(0.627f, 0.239f, 0.761f, 1.00f);
|
||||||
|
colors[ImGuiCol_SliderGrab] = ImVec4(0.34f, 0.34f, 0.34f, 0.54f);
|
||||||
|
colors[ImGuiCol_SliderGrabActive] = ImVec4(0.56f, 0.56f, 0.56f, 0.54f);
|
||||||
|
colors[ImGuiCol_Button] = ImVec4(0.05f, 0.05f, 0.05f, 0.54f);
|
||||||
|
colors[ImGuiCol_ButtonHovered] = ImVec4(0.15f, 0.15f, 0.15f, 0.54f);
|
||||||
|
colors[ImGuiCol_ButtonActive] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f);
|
||||||
|
colors[ImGuiCol_Header] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f);
|
||||||
|
colors[ImGuiCol_HeaderHovered] = ImVec4(0.00f, 0.00f, 0.00f, 0.36f);
|
||||||
|
colors[ImGuiCol_HeaderActive] = ImVec4(0.20f, 0.22f, 0.23f, 0.33f);
|
||||||
|
colors[ImGuiCol_Separator] = colors[ImGuiCol_MenuBarBg];
|
||||||
|
colors[ImGuiCol_SeparatorHovered] = ImVec4(0.44f, 0.44f, 0.44f, 0.29f);
|
||||||
|
colors[ImGuiCol_SeparatorActive] = ImVec4(0.40f, 0.44f, 0.47f, 1.00f);
|
||||||
|
colors[ImGuiCol_ResizeGrip] = ImVec4(0.28f, 0.28f, 0.28f, 0.29f);
|
||||||
|
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.44f, 0.44f, 0.44f, 0.29f);
|
||||||
|
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.40f, 0.44f, 0.47f, 1.00f);
|
||||||
|
colors[ImGuiCol_Tab] = colors[ImGuiCol_WindowBg];
|
||||||
|
colors[ImGuiCol_TabHovered] = ImVec4(0.14f, 0.14f, 0.14f, 1.00f);
|
||||||
|
colors[ImGuiCol_TabActive] = ImVec4(0.14f, 0.14f, 0.14f, 0.8f);
|
||||||
|
colors[ImGuiCol_TabUnfocused] = colors[ImGuiCol_WindowBg];
|
||||||
|
colors[ImGuiCol_TabUnfocusedActive] = colors[ImGuiCol_WindowBg];
|
||||||
|
colors[ImGuiCol_DockingPreview] = ImVec4(0.627f, 0.239f, 0.761f, 1.00f);
|
||||||
|
colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.855f, 0.6f, 0.941f, 1.00f);
|
||||||
|
colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
|
||||||
|
colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
|
||||||
|
colors[ImGuiCol_PlotHistogram] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
|
||||||
|
colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
|
||||||
|
colors[ImGuiCol_TableHeaderBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f);
|
||||||
|
colors[ImGuiCol_TableBorderStrong] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f);
|
||||||
|
colors[ImGuiCol_TableBorderLight] = ImVec4(0.28f, 0.28f, 0.28f, 0.29f);
|
||||||
|
colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
|
||||||
|
colors[ImGuiCol_TableRowBgAlt] = ImVec4(1.00f, 1.00f, 1.00f, 0.06f);
|
||||||
|
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f);
|
||||||
|
colors[ImGuiCol_DragDropTarget] = ImVec4(0.33f, 0.67f, 0.86f, 1.00f);
|
||||||
|
colors[ImGuiCol_NavHighlight] = ImVec4(0.73f, 0.73f, 0.73f, 0.7f);
|
||||||
|
colors[ImGuiCol_NavWindowingHighlight] = ImVec4(0.141f, 0.141f, 0.141f, 0.70f);
|
||||||
|
colors[ImGuiCol_NavWindowingDimBg] = colors[ImGuiCol_NavHighlight];
|
||||||
|
colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.2f, 0.2f, 0.2f, 0.65f);
|
||||||
|
|
||||||
|
imStyle.WindowPadding = ImVec2(8.00f, 8.00f);
|
||||||
|
imStyle.FramePadding = ImVec2(5.00f, 2.00f);
|
||||||
|
imStyle.CellPadding = ImVec2(6.00f, 8.00f);
|
||||||
|
imStyle.ItemSpacing = ImVec2(6.00f, 6.00f);
|
||||||
|
imStyle.ItemInnerSpacing = ImVec2(6.00f, 6.00f);
|
||||||
|
imStyle.TouchExtraPadding = ImVec2(0.00f, 0.00f);
|
||||||
|
imStyle.IndentSpacing = 25;
|
||||||
|
imStyle.ScrollbarSize = 15;
|
||||||
|
imStyle.GrabMinSize = 10;
|
||||||
|
imStyle.WindowBorderSize = 0.6f;
|
||||||
|
imStyle.ChildBorderSize = 1;
|
||||||
|
imStyle.PopupBorderSize = 1;
|
||||||
|
imStyle.FrameBorderSize = 1;
|
||||||
|
imStyle.TabBorderSize = 1;
|
||||||
|
imStyle.WindowRounding = 7;
|
||||||
|
imStyle.ChildRounding = 4;
|
||||||
|
imStyle.FrameRounding = 3;
|
||||||
|
imStyle.PopupRounding = 4;
|
||||||
|
imStyle.ScrollbarRounding = 9;
|
||||||
|
imStyle.GrabRounding = 3;
|
||||||
|
imStyle.LogSliderDeadzone = 4;
|
||||||
|
imStyle.TabRounding = 4;
|
||||||
|
imStyle.WindowMenuButtonPosition = ImGuiDir_None;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Style::DARK: ImGui::StyleColorsDark(); break;
|
||||||
|
case Style::LIGHT: ImGui::StyleColorsLight(); break;
|
||||||
|
case Style::CLASSIC: ImGui::StyleColorsClassic(); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Private Member Functions ||
|
||||||
|
//#==============================================================#
|
||||||
|
void SHEditor::InitBackend(SDL_Window* sdlWindow)
|
||||||
|
{
|
||||||
|
if(ImGui_ImplSDL2_InitForVulkan(sdlWindow) == false)
|
||||||
|
{
|
||||||
|
SHLOG_CRITICAL("Editor backend initialisation; Failed to perform SDL initialisation for Vulkan")
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto* gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||||
|
|
||||||
|
ImGui_ImplVulkan_InitInfo initInfo{};
|
||||||
|
initInfo.Instance = SHVkInstance::GetVkInstance();
|
||||||
|
initInfo.PhysicalDevice = gfxSystem->GetPhysicalDevice()->GetVkPhysicalDevice();
|
||||||
|
initInfo.Device = gfxSystem->GetDevice()->GetVkLogicalDevice();
|
||||||
|
initInfo.Queue = gfxSystem->GetQueue()->GetVkQueue();
|
||||||
|
initInfo.DescriptorPool = gfxSystem->GetDescriptorPool()->GetVkHandle();
|
||||||
|
initInfo.MinImageCount = initInfo.ImageCount = gfxSystem->GetSwapchain()->GetNumImages();
|
||||||
|
initInfo.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
|
||||||
|
imguiCommandPool = gfxSystem->GetDevice()->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true);
|
||||||
|
imguiCommandBuffer = imguiCommandPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
||||||
|
|
||||||
|
auto const& renderers = gfxSystem->GetDefaultViewport()->GetRenderers();
|
||||||
|
|
||||||
|
SHASSERT(!renderers.empty(), "No Renderers available")
|
||||||
|
auto renderGraph = renderers[0]->GetRenderGraph();
|
||||||
|
auto renderPass = renderGraph->GetNode("ImGui Node")->GetRenderpass();
|
||||||
|
|
||||||
|
if(ImGui_ImplVulkan_Init(&initInfo, renderPass->GetVkRenderpass()) == false)
|
||||||
|
{
|
||||||
|
SHLOG_CRITICAL("Editor backend initialisation; Failed to initialise Vulkan backend")
|
||||||
|
}
|
||||||
|
|
||||||
|
imguiCommandBuffer->BeginRecording();
|
||||||
|
if(ImGui_ImplVulkan_CreateFontsTexture(imguiCommandBuffer->GetVkCommandBuffer()) == false)
|
||||||
|
{
|
||||||
|
SHLOG_CRITICAL("Editor backend initialisation; Failed to create fonts texture for Vulkan backend")
|
||||||
|
}
|
||||||
|
imguiCommandBuffer->EndRecording();
|
||||||
|
gfxSystem->GetQueue()->SubmitCommandBuffer({ imguiCommandBuffer }, {}, {}, vk::PipelineStageFlagBits::eNone, {});
|
||||||
|
|
||||||
|
ImGui_ImplVulkan_DestroyFontUploadObjects();
|
||||||
|
|
||||||
|
renderGraph->GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle<SHVkCommandBuffer>& cmd) {
|
||||||
|
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->GetVkCommandBuffer());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHEditor::NewFrame()
|
void SHEditor::NewFrame()
|
||||||
{
|
{
|
||||||
|
SDL_Event event;
|
||||||
|
while (SDL_PollEvent(&event) != 0)
|
||||||
|
{
|
||||||
|
ImGui_ImplSDL2_ProcessEvent(&event);
|
||||||
|
}
|
||||||
ImGui_ImplVulkan_NewFrame();
|
ImGui_ImplVulkan_NewFrame();
|
||||||
ImGui_ImplSDL2_NewFrame();
|
ImGui_ImplSDL2_NewFrame();
|
||||||
ImGui::NewFrame();
|
ImGui::NewFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHEditor::EndFrame()
|
|
||||||
{
|
}//namespace SHADE
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "SH_API.h"
|
|
||||||
#include <SDL.h>
|
|
||||||
|
|
||||||
#include "Resource/Handle.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace SHADE
|
|
||||||
{
|
|
||||||
class SHVkCommandBuffer;
|
|
||||||
class SHVkCommandPool;
|
|
||||||
|
|
||||||
class SH_API SHEditor
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static void Initialise(SDL_Window* sdlWindow);
|
|
||||||
static void PreRender();
|
|
||||||
static void Render();
|
|
||||||
static void Exit();
|
|
||||||
private:
|
|
||||||
static void InitBackend();
|
|
||||||
static void NewFrame();
|
|
||||||
static void EndFrame();
|
|
||||||
|
|
||||||
static Handle<SHVkCommandPool> imguiCommandPool;
|
|
||||||
static Handle<SHVkCommandBuffer> imguiCommandBuffer;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -0,0 +1,168 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| STL Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <vector>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| SHADE Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "SH_API.h"
|
||||||
|
#include "ECS_Base/SHECSMacros.h"
|
||||||
|
#include "Resource/Handle.h"
|
||||||
|
#include "EditorWindow/SHEditorWindow.h"
|
||||||
|
#include "Tools/SHLogger.h"
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Library Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <SDL_video.h>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Forward Declarations ||
|
||||||
|
//#==============================================================#
|
||||||
|
class SHVkCommandBuffer;
|
||||||
|
class SHVkCommandPool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SHEditor static class contains editor variables and implementation of editor functions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class SH_API SHEditor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Type Aliases ||
|
||||||
|
//#==============================================================#
|
||||||
|
using EditorWindowID = uint8_t;
|
||||||
|
using EditorWindowPtr = std::unique_ptr<SHEditorWindow>;
|
||||||
|
using EditorWindowMap = std::unordered_map<EditorWindowID, EditorWindowPtr>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Style options
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
enum class Style : uint8_t
|
||||||
|
{
|
||||||
|
SHADE,
|
||||||
|
DARK,
|
||||||
|
LIGHT,
|
||||||
|
CLASSIC
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialise the editor
|
||||||
|
*
|
||||||
|
* @param sdlWindow pointer to SDL_Window object created in application
|
||||||
|
*/
|
||||||
|
static void Initialise(SDL_Window* sdlWindow);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Update the editor and add to ImGui DrawList
|
||||||
|
*
|
||||||
|
* @param dt Delta-time of the frame
|
||||||
|
*/
|
||||||
|
static void Update(float dt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Safely shutdown the editor
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void Exit();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the Style for the editor
|
||||||
|
*
|
||||||
|
* @param style Desired style
|
||||||
|
*/
|
||||||
|
static void SetStyle(Style style);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get ID for the Editor Window Type
|
||||||
|
*
|
||||||
|
* @tparam T Type of Editor Window
|
||||||
|
* @return EditorWindowID ID of Editor Window Type
|
||||||
|
*/
|
||||||
|
template <typename T, std::enable_if_t<std::is_base_of_v<SHEditorWindow, T>, bool> = true>
|
||||||
|
static EditorWindowID GetEditorWindowID()
|
||||||
|
{
|
||||||
|
static EditorWindowID id;
|
||||||
|
static bool idCreated = false;
|
||||||
|
if (!idCreated)
|
||||||
|
{
|
||||||
|
id = windowCount++;
|
||||||
|
idCreated = true;
|
||||||
|
}
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get pointer to the Editor Window
|
||||||
|
*
|
||||||
|
* @tparam T Type of editor window to retrieve
|
||||||
|
* @return T* Pointer to the editor window
|
||||||
|
*/
|
||||||
|
template <typename T, std::enable_if_t<std::is_base_of_v<SHEditorWindow, T>, bool> = true>
|
||||||
|
static T* GetEditorWindow()
|
||||||
|
{
|
||||||
|
return reinterpret_cast<T*>(editorWindows[GetEditorWindowID<T>()].get());
|
||||||
|
}
|
||||||
|
|
||||||
|
// List of selected entities
|
||||||
|
static std::vector<EntityID> selectedEntities;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* @brief Initialise Backend for ImGui (SDL and Vulkan backend)
|
||||||
|
*
|
||||||
|
* @param sdlWindow Pointer to SDL_Window
|
||||||
|
*/
|
||||||
|
static void InitBackend(SDL_Window* sdlWindow);
|
||||||
|
/**
|
||||||
|
* @brief Start new frame for editor
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void NewFrame();
|
||||||
|
/**
|
||||||
|
* @brief Perform ImGui and ImGui Backend Render
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void Render();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create an Editor Window
|
||||||
|
*
|
||||||
|
* @tparam T Type of Editor Window to create
|
||||||
|
*/
|
||||||
|
template <typename T, std::enable_if_t<std::is_base_of_v<SHEditorWindow, T>, bool> = true>
|
||||||
|
static void CreateEditorWindow()
|
||||||
|
{
|
||||||
|
static bool isCreated = false;
|
||||||
|
if (!isCreated)
|
||||||
|
{
|
||||||
|
editorWindows[GetEditorWindowID<T>()] = std::make_unique<T>();
|
||||||
|
isCreated = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("Attempt to create duplicate of Editor window type")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void InitFonts() noexcept;
|
||||||
|
|
||||||
|
// Handle to command pool used for ImGui Vulkan Backend
|
||||||
|
static Handle<SHVkCommandPool> imguiCommandPool;
|
||||||
|
// Handle to command buffer used for ImGui Vulkan Backend
|
||||||
|
static Handle<SHVkCommandBuffer> imguiCommandBuffer;
|
||||||
|
|
||||||
|
// Number of windows; used for Editor Window ID Generation
|
||||||
|
static EditorWindowID windowCount;
|
||||||
|
// Map of Editor Windows
|
||||||
|
static EditorWindowMap editorWindows;
|
||||||
|
};//class SHEditor
|
||||||
|
}//namespace SHADE
|
|
@ -0,0 +1,187 @@
|
||||||
|
#pragma once
|
||||||
|
//#==============================================================#
|
||||||
|
//|| STL Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| SHADE Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "Math/SHMath.h"
|
||||||
|
#include "Command/SHCommandManager.h"
|
||||||
|
#include "SHImGuiHelpers.hpp"
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Library Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <imgui.h>
|
||||||
|
#include <imgui_internal.h>
|
||||||
|
#include <misc/cpp/imgui_stdlib.h>
|
||||||
|
#include <rttr/type.h>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Custom Widgets ||
|
||||||
|
//#==============================================================#
|
||||||
|
static bool Splitter(bool verticalSplit, float thickness, float* size1, float* size2, float minSize1, float minSize2, float splitterAxisSize = -1.0f)
|
||||||
|
{
|
||||||
|
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
||||||
|
const ImGuiID id = window->GetID("##Splitter");
|
||||||
|
ImRect bb;
|
||||||
|
bb.Min = window->DC.CursorPos + (verticalSplit ? ImVec2(*size1, 0.0f) : ImVec2(0.0f, *size1));
|
||||||
|
bb.Max = bb.Min + (verticalSplit ? ImVec2(thickness, splitterAxisSize) : ImVec2(splitterAxisSize, thickness));
|
||||||
|
return ImGui::SplitterBehavior(bb, id, verticalSplit ? ImGuiAxis_X : ImGuiAxis_Y, size1, size2, minSize1, minSize2, 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
static bool DragN(const std::string& fieldLabel, std::vector<std::string>const& componentLabels,
|
||||||
|
std::vector<T*> values, float speed = 0.1f, const char* displayFormat = "", T valueMin = T(), T valueMax = T(),
|
||||||
|
ImGuiSliderFlags flags = 0)
|
||||||
|
{
|
||||||
|
const ImGuiWindow* const window = ImGui::GetCurrentWindow();
|
||||||
|
if (window->SkipItems)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const ImGuiContext& g = *GImGui;
|
||||||
|
bool valueChanged = false;
|
||||||
|
ImGui::BeginGroup();
|
||||||
|
ImGui::PushID(fieldLabel.c_str());
|
||||||
|
PushMultiItemsWidthsAndLabels(componentLabels, 0.0f);
|
||||||
|
ImGui::BeginColumns("DragVecCol", 2, ImGuiOldColumnFlags_NoBorder | ImGuiOldColumnFlags_NoResize);
|
||||||
|
ImGui::SetColumnWidth(-1, 80.0f);
|
||||||
|
ImGui::Text(fieldLabel.c_str());
|
||||||
|
ImGui::NextColumn();
|
||||||
|
for (std::size_t i = 0; i < N; ++i)
|
||||||
|
{
|
||||||
|
ImGui::PushID(static_cast<int>(i));
|
||||||
|
ImGui::TextUnformatted(componentLabels[i].c_str(), ImGui::FindRenderedTextEnd(componentLabels[i].c_str())); ImGui::SameLine();
|
||||||
|
ImGui::SetNextItemWidth(80.0f);
|
||||||
|
valueChanged |= ImGui::DragFloat("##v", values[i], speed, valueMin, valueMax, displayFormat, flags);
|
||||||
|
|
||||||
|
const ImVec2 min = ImGui::GetItemRectMin();
|
||||||
|
const ImVec2 max = ImGui::GetItemRectMax();
|
||||||
|
const float spacing = g.Style.FrameRounding;
|
||||||
|
const float halfSpacing = spacing / 2;
|
||||||
|
|
||||||
|
window->DrawList->AddLine({ min.x + spacing, max.y - halfSpacing }, { max.x - spacing, max.y - halfSpacing },
|
||||||
|
ImGuiColors::colors[i], 4);
|
||||||
|
|
||||||
|
ImGui::SameLine(0, g.Style.ItemInnerSpacing.x);
|
||||||
|
ImGui::PopID();
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
}
|
||||||
|
ImGui::EndColumns();
|
||||||
|
ImGui::PopID();
|
||||||
|
ImGui::EndGroup();
|
||||||
|
|
||||||
|
return valueChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool DragVec2(const std::string& fieldLabel, std::vector<std::string>const& componentLabels, std::function<SHVec2(void)> get,
|
||||||
|
std::function<void(SHVec2)> set, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f,
|
||||||
|
ImGuiSliderFlags flags = 0)
|
||||||
|
{
|
||||||
|
SHVec2 values = get();
|
||||||
|
bool changed = false;
|
||||||
|
if (DragN<float, 2>(fieldLabel, componentLabels, {&values.x, &values.y}, speed, displayFormat, valueMin, valueMax, flags))
|
||||||
|
{
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
{
|
||||||
|
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec2>>(get(), values, set)), false);
|
||||||
|
else if(ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec2>>(get(), values, set)), true);
|
||||||
|
else if(ImGui::IsItemDeactivatedAfterEdit())
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec2>>(get(), values, set)), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool DragVec3(const std::string& fieldLabel, std::vector<std::string>const& componentLabels, std::function<SHVec3(void)> get,
|
||||||
|
std::function<void(SHVec3)> set, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f,
|
||||||
|
ImGuiSliderFlags flags = 0)
|
||||||
|
{
|
||||||
|
SHVec3 values = get();
|
||||||
|
bool changed = false;
|
||||||
|
if (DragN<float, 3>(fieldLabel, componentLabels, {&values.x, &values.y, &values.z}, speed, displayFormat, valueMin, valueMax, flags))
|
||||||
|
{
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
{
|
||||||
|
if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f))
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec3>>(get(), values, set)), false);
|
||||||
|
else if(ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec3>>(get(), values, set)), true);
|
||||||
|
else if(ImGui::IsItemDeactivatedAfterEdit())
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec3>>(get(), values, set)), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool DragVec4(const std::string& fieldLabel, std::vector<std::string>const& componentLabels, std::function<SHVec4(void)> get,
|
||||||
|
std::function<void(SHVec4)> set, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f,
|
||||||
|
ImGuiSliderFlags flags = 0)
|
||||||
|
{
|
||||||
|
SHVec4 values = get();
|
||||||
|
bool changed = false;
|
||||||
|
if (DragN<float, 4>(fieldLabel, componentLabels, {&values.x, &values.y, &values.z, &values.w}, speed, displayFormat, valueMin, valueMax, flags))
|
||||||
|
{
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
{
|
||||||
|
if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f))
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec4>>(get(), values, set)), false);
|
||||||
|
else if(ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec4>>(get(), values, set)), true);
|
||||||
|
else if(ImGui::IsItemDeactivatedAfterEdit())
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec4>>(get(), values, set)), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Widget Extensions ||
|
||||||
|
//#==============================================================#
|
||||||
|
|
||||||
|
static bool CheckBox(std::string const& label, std::function<bool(void)> get, std::function<void(bool const&)> set)
|
||||||
|
{
|
||||||
|
bool value = get();
|
||||||
|
if (ImGui::Checkbox(label.c_str(), &value))
|
||||||
|
{
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<bool>>(get(), value, set)), false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static bool RadioButton(std::vector<std::string> const& listLabels, std::vector<T> const& listTypes, std::function<T(void)> get, std::function<void(T const&)> set)
|
||||||
|
{
|
||||||
|
T type = get();
|
||||||
|
for (size_t i = 0; i < listTypes.size(); i++)
|
||||||
|
{
|
||||||
|
if (ImGui::RadioButton(listLabels[i].c_str(), type == listTypes[i]))
|
||||||
|
{
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), listTypes[i], set)), false);
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}//namespace SHADE
|
|
@ -0,0 +1,69 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| STL Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| SHADE Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "Math/SHMath.h"
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| SHADE-ImGui Math Conversions ||
|
||||||
|
//#==============================================================#
|
||||||
|
#ifndef SH_IM_MATH
|
||||||
|
#define IM_VEC2_CLASS_EXTRA \
|
||||||
|
ImVec2(const SHADE::SHVec2& vec) {x = vec.x; y = vec.y;} \
|
||||||
|
operator SHADE::SHVec2() const {return SHADE::SHVec2(x,y);}
|
||||||
|
#define IM_VEC3_CLASS_EXTRA \
|
||||||
|
ImVec3(const SHADE::SHVec3& vec) {x = vec.x; y = vec.y; z = vec.z;} \
|
||||||
|
operator SHADE::SHVec3() const {return SHADE::SHVec3(x,y,z);}
|
||||||
|
#define IM_VEC4_CLASS_EXTRA \
|
||||||
|
ImVec4(const SHADE::SHVec4& vec) {x = vec.x; y = vec.y; z = vec.z; w = vec.w;} \
|
||||||
|
operator SHADE::SHVec4() const {return SHADE::SHVec4(x,y,z,w);}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Library Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <imgui_internal.h>
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
namespace ImGuiColors
|
||||||
|
{
|
||||||
|
constexpr ImVec4 red = {1.0f, 0.0f, 0.0f, 1.f};
|
||||||
|
constexpr ImVec4 green = {0.0f, 1.0f, 0.0f, 1.f};
|
||||||
|
constexpr ImVec4 blue = {0.0f, 0.0f, 1.0f, 1.f};
|
||||||
|
constexpr ImVec4 white = {1.0f, 1.0f, 1.0f, 1.f};
|
||||||
|
|
||||||
|
constexpr ImU32 colors[] = {
|
||||||
|
0xBB0000FF, // red
|
||||||
|
0xBB00FF00, // green
|
||||||
|
0xBBFF0000, // blue
|
||||||
|
0xBBFFFFFF, // white
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PushMultiItemsWidthsAndLabels(const std::vector<std::string>& labels, float wFull)
|
||||||
|
{
|
||||||
|
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
||||||
|
const ImGuiStyle& style = GImGui->Style;
|
||||||
|
if (wFull <= 0.0f)
|
||||||
|
wFull = ImGui::GetContentRegionAvail().x;
|
||||||
|
const auto size = labels.size();
|
||||||
|
const float w_item_one =
|
||||||
|
ImMax(1.0f, (wFull - (static_cast<float>(size) - 1.0f) * (style.ItemInnerSpacing.x * 2.0f)) / static_cast<float>(
|
||||||
|
size)) -
|
||||||
|
style.ItemInnerSpacing.x;
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
window->DC.ItemWidthStack.push_back(w_item_one - ImGui::CalcTextSize(labels[i].c_str()).x);
|
||||||
|
window->DC.ItemWidth = window->DC.ItemWidthStack.back();
|
||||||
|
}
|
||||||
|
} //namespace SHADE
|
|
@ -80,6 +80,12 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if (!dirEntry.is_directory())
|
if (!dirEntry.is_directory())
|
||||||
{
|
{
|
||||||
|
folder->files.emplace_back(
|
||||||
|
dirEntry.path().filename().string(),
|
||||||
|
dirEntry.path().string(),
|
||||||
|
dirEntry.path().extension().string()
|
||||||
|
);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,6 +109,11 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FolderPointer SHFileSystem::GetRoot() noexcept
|
||||||
|
{
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
FolderPointer SHFileSystem::CreateFolder(FolderPath path, FolderLocation parent, FolderHandle location, FolderName name) noexcept
|
FolderPointer SHFileSystem::CreateFolder(FolderPath path, FolderLocation parent, FolderHandle location, FolderName name) noexcept
|
||||||
{
|
{
|
||||||
assert(
|
assert(
|
||||||
|
|
|
@ -14,12 +14,22 @@ namespace SHADE
|
||||||
typedef uint64_t FolderLocation;
|
typedef uint64_t FolderLocation;
|
||||||
typedef uint64_t FolderHandle;
|
typedef uint64_t FolderHandle;
|
||||||
typedef std::string FolderName;
|
typedef std::string FolderName;
|
||||||
|
typedef std::string FileName;
|
||||||
typedef std::string FolderPath;
|
typedef std::string FolderPath;
|
||||||
|
typedef std::string FilePath;
|
||||||
|
typedef std::string FileExt;
|
||||||
typedef SHFolder* FolderPointer;
|
typedef SHFolder* FolderPointer;
|
||||||
|
|
||||||
constexpr char FOLDER_BIT_ALLOCATE{ 4 };
|
constexpr char FOLDER_BIT_ALLOCATE{ 4 };
|
||||||
constexpr char FOLDER_MAX_DEPTH{ 16 };
|
constexpr char FOLDER_MAX_DEPTH{ 16 };
|
||||||
|
|
||||||
|
struct SHFile
|
||||||
|
{
|
||||||
|
FileName name;
|
||||||
|
FilePath path;
|
||||||
|
FileExt ext;
|
||||||
|
};
|
||||||
|
|
||||||
class SHFolder
|
class SHFolder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -28,6 +38,7 @@ namespace SHADE
|
||||||
FolderHandle id;
|
FolderHandle id;
|
||||||
FolderName name;
|
FolderName name;
|
||||||
std::vector<FolderPointer> subFolders;
|
std::vector<FolderPointer> subFolders;
|
||||||
|
std::vector<SHFile> files;
|
||||||
|
|
||||||
bool folded;
|
bool folded;
|
||||||
|
|
||||||
|
@ -45,6 +56,8 @@ namespace SHADE
|
||||||
|
|
||||||
static void StartupFillDirectories(FolderPath path) noexcept;
|
static void StartupFillDirectories(FolderPath path) noexcept;
|
||||||
|
|
||||||
|
static FolderPointer GetRoot() noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static FolderPointer root;
|
static FolderPointer root;
|
||||||
|
|
||||||
|
|
|
@ -135,11 +135,13 @@ namespace SHADE
|
||||||
//worldRenderGraph->AddResource("Position", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
|
//worldRenderGraph->AddResource("Position", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
|
||||||
//worldRenderGraph->AddResource("Normals", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
|
//worldRenderGraph->AddResource("Normals", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
|
||||||
//worldRenderGraph->AddResource("Composite", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
|
//worldRenderGraph->AddResource("Composite", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
|
||||||
|
worldRenderGraph->AddResource("Scene", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eB8G8R8A8Unorm);
|
||||||
worldRenderGraph->AddResource("Present", SH_ATT_DESC_TYPE::COLOR_PRESENT, windowDims.first, windowDims.second);
|
worldRenderGraph->AddResource("Present", SH_ATT_DESC_TYPE::COLOR_PRESENT, windowDims.first, windowDims.second);
|
||||||
auto node = worldRenderGraph->AddNode("G-Buffer", { /*"Composite", "Position", "Normals",*/ "Present" }, {}); // no predecessors
|
auto node = worldRenderGraph->AddNode("G-Buffer", { /*"Composite", "Position", */"Present" }, {}); // no predecessors
|
||||||
|
|
||||||
//First subpass to write to G-Buffer
|
//First subpass to write to G-Buffer
|
||||||
auto gBufferWriteSubpass = node->AddSubpass("G-Buffer Write");
|
auto gBufferWriteSubpass = node->AddSubpass("G-Buffer Write");
|
||||||
|
//gBufferWriteSubpass->AddColorOutput("Scene");
|
||||||
gBufferWriteSubpass->AddColorOutput("Present");
|
gBufferWriteSubpass->AddColorOutput("Present");
|
||||||
//writeSubpass->AddColorOutput("Normals");
|
//writeSubpass->AddColorOutput("Normals");
|
||||||
|
|
||||||
|
|
|
@ -202,6 +202,7 @@ namespace SHADE
|
||||||
Handle<SHVkPhysicalDevice> GetPhysicalDevice() const { return physicalDevice; }
|
Handle<SHVkPhysicalDevice> GetPhysicalDevice() const { return physicalDevice; }
|
||||||
Handle<SHVkQueue> GetQueue() const { return graphicsQueue; }
|
Handle<SHVkQueue> GetQueue() const { return graphicsQueue; }
|
||||||
Handle<SHVkDescriptorPool> GetDescriptorPool() const { return descPool; }
|
Handle<SHVkDescriptorPool> GetDescriptorPool() const { return descPool; }
|
||||||
|
Handle<SHViewport> GetDefaultViewport() const {return defaultViewport;}
|
||||||
//SHRenderGraph const& GetRenderGraph(void) const noexcept;
|
//SHRenderGraph const& GetRenderGraph(void) const noexcept;
|
||||||
|
|
||||||
//Handle<SHVkRenderpass> GetRenderPass() const { return renderPass; }
|
//Handle<SHVkRenderpass> GetRenderPass() const { return renderPass; }
|
||||||
|
|
|
@ -284,6 +284,7 @@ namespace SHADE
|
||||||
SHRenderGraph(SHRenderGraph&& rhs) noexcept;
|
SHRenderGraph(SHRenderGraph&& rhs) noexcept;
|
||||||
SHRenderGraph& operator=(SHRenderGraph&& rhs) noexcept;
|
SHRenderGraph& operator=(SHRenderGraph&& rhs) noexcept;
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PUBLIC MEMBER FUNCTIONS */
|
/* PUBLIC MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include "SHPch.h"
|
#include "SHPch.h"
|
||||||
#include "SHWindowMap.h"
|
#include "SHWindowMap.h"
|
||||||
#include "SHWindow.h"
|
#include "SHWindow.h"
|
||||||
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
#include "Input/SHInputManagerSystem.h"
|
||||||
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
|
@ -339,6 +341,14 @@ namespace SHADE
|
||||||
OnPosChange(reinterpret_cast<LPWINDOWPOS>(lparam));
|
OnPosChange(reinterpret_cast<LPWINDOWPOS>(lparam));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case WM_MOUSEWHEEL:
|
||||||
|
{
|
||||||
|
if (auto im = SHSystemManager::GetSystem<SHInputManagerSystem>())
|
||||||
|
{
|
||||||
|
im->PollWheelVerticalDelta(wparam);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return ::DefWindowProc(hwnd, msg, wparam, lparam);
|
return ::DefWindowProc(hwnd, msg, wparam, lparam);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
//#include <Xinput.h>
|
//#include <Xinput.h>
|
||||||
//#include "../../SHADE_Managed/src/SHpch.h"
|
//#include "../../SHADE_Managed/src/SHpch.h"
|
||||||
|
#include "SH_API.h"
|
||||||
#include "ECS_Base/System/SHSystem.h"
|
#include "ECS_Base/System/SHSystem.h"
|
||||||
#include "ECS_Base/System/SHFixedSystemRoutine.h"
|
#include "ECS_Base/System/SHFixedSystemRoutine.h"
|
||||||
|
|
||||||
|
|
|
@ -182,3 +182,14 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace SHADE
|
} // namespace SHADE
|
||||||
|
|
||||||
|
RTTR_REGISTRATION
|
||||||
|
{
|
||||||
|
using namespace SHADE;
|
||||||
|
using namespace rttr;
|
||||||
|
|
||||||
|
registration::class_<SHTransformComponent>("Transform Component")
|
||||||
|
.property("Translate", &SHTransformComponent::GetLocalPosition, &SHTransformComponent::SetLocalPosition)
|
||||||
|
.property("Rotate", &SHTransformComponent::GetLocalRotation, select_overload<void(SHVec3 const&)>(&SHTransformComponent::SetLocalRotation))
|
||||||
|
.property("Scale", &SHTransformComponent::GetLocalScale, &SHTransformComponent::SetLocalScale);
|
||||||
|
}
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
|
#include <rttr/registration>
|
||||||
// Project Headers
|
// Project Headers
|
||||||
#include "SH_API.h"
|
#include "SH_API.h"
|
||||||
#include "ECS_Base/Components/SHComponent.h"
|
#include "ECS_Base/Components/SHComponent.h"
|
||||||
|
@ -116,6 +117,8 @@ namespace SHADE
|
||||||
SHTransform world;
|
SHTransform world;
|
||||||
|
|
||||||
UpdateQueue updateQueue;
|
UpdateQueue updateQueue;
|
||||||
|
|
||||||
|
RTTR_ENABLE()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -66,27 +66,23 @@ namespace SHADE
|
||||||
|
|
||||||
for (const auto* child : node->GetChildren())
|
for (const auto* child : node->GetChildren())
|
||||||
{
|
{
|
||||||
|
auto* childTransform = SHComponentManager::GetComponent_s<SHTransformComponent>(child->GetEntityID());
|
||||||
|
if (childTransform)
|
||||||
|
|
||||||
const bool HAS_TRANSFORM = SHComponentManager::HasComponent<SHTransformComponent>(child->GetEntityID());
|
|
||||||
if (!HAS_TRANSFORM)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
auto* childTransform = SHComponentManager::GetComponent<SHTransformComponent>(child->GetEntityID());
|
|
||||||
|
|
||||||
// Only update if node in hierarchy and component are both active
|
|
||||||
const bool IS_NODE_ACTIVE = child->IsActive();
|
|
||||||
if (IS_NODE_ACTIVE && childTransform->isActive)
|
|
||||||
{
|
{
|
||||||
if (childTransform->dirty || HAS_PARENT_CHANGED)
|
// Only update if node in hierarchy and component are both active
|
||||||
UpdateTransform(*childTransform, NODE_TRANSFORM);
|
const bool IS_NODE_ACTIVE = child->IsActive();
|
||||||
|
if (IS_NODE_ACTIVE && childTransform->isActive)
|
||||||
|
{
|
||||||
|
if (childTransform->dirty || HAS_PARENT_CHANGED)
|
||||||
|
UpdateTransform(*childTransform, NODE_TRANSFORM);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateEntity(child);
|
UpdateEntity(child);
|
||||||
|
|
||||||
// Clear dirty flag after all children are updated
|
// Clear dirty flag after all children are updated
|
||||||
childTransform->dirty = false;
|
if (childTransform)
|
||||||
|
childTransform->dirty = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,8 +140,8 @@ namespace SHADE
|
||||||
tf.world.ComputeTRS();
|
tf.world.ComputeTRS();
|
||||||
|
|
||||||
// Transpose TRS to column major
|
// Transpose TRS to column major
|
||||||
tf.local.trs.Transpose();
|
//tf.local.trs.Transpose();
|
||||||
tf.world.trs.Transpose();
|
//tf.world.trs.Transpose();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace SHADE
|
} // namespace SHADE
|
|
@ -7,7 +7,8 @@ workspace "SHADE"
|
||||||
configurations
|
configurations
|
||||||
{
|
{
|
||||||
"Debug",
|
"Debug",
|
||||||
"Release"
|
"Release",
|
||||||
|
"Publish"
|
||||||
}
|
}
|
||||||
|
|
||||||
flags
|
flags
|
||||||
|
|
Loading…
Reference in New Issue