Merge branch 'main' into SP3-6-c-scripting
This commit is contained in:
commit
b5f7ff1106
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -18,10 +18,11 @@ echo "K - RTTR"
|
|||
echo "L - yamlcpp"
|
||||
echo "M - SDL"
|
||||
echo "N - dotnet"
|
||||
echo "O - tinyddsloader"
|
||||
echo ---------------------------------------------------
|
||||
echo.
|
||||
|
||||
choice /C ABCDEFGHIJKLMN /T 10 /D A
|
||||
choice /C ABCDEFGHIJKLMNO /T 10 /D A
|
||||
set _e=%ERRORLEVEL%
|
||||
|
||||
if %_e%==1 goto VMA
|
||||
|
@ -38,6 +39,7 @@ if %_e%==11 goto RTTR
|
|||
if %_e%==12 goto yamlcpp
|
||||
if %_e%==13 goto SDL
|
||||
if %_e%==14 goto dotnet
|
||||
if %_e%==15 goto tinyddsloader
|
||||
|
||||
: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
|
||||
del "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/benikabocha/tinyddsloader.git "Dependencies/tinyddsloader"
|
||||
|
||||
:done
|
||||
echo DONE!
|
||||
|
|
|
@ -14,3 +14,4 @@ IncludeDir["reactphysics3d"] = "%{wks.location}\\Dependencies\\reactphysics3d"
|
|||
IncludeDir["SDL"] = "%{wks.location}\\Dependencies\\SDL"
|
||||
IncludeDir["VULKAN"] = "$(VULKAN_SDK)"
|
||||
IncludeDir["dotnet"] = "%{wks.location}\\Dependencies\\dotnet"
|
||||
IncludeDir["tinyddsloader"] = "%{wks.location}\\Dependencies\\tinyddsloader"
|
||||
|
|
|
@ -30,10 +30,12 @@ project "SHADE_Application"
|
|||
|
||||
externalincludedirs
|
||||
{
|
||||
"%{IncludeDir.spdlog}/include",
|
||||
"%{IncludeDir.VULKAN}/include",
|
||||
"%{IncludeDir.VMA}/include",
|
||||
"%{IncludeDir.VULKAN}/Source/SPIRV-Reflect"
|
||||
"%{IncludeDir.spdlog}/include",
|
||||
"%{IncludeDir.VULKAN}/include",
|
||||
"%{IncludeDir.VMA}/include",
|
||||
"%{IncludeDir.VULKAN}/Source/SPIRV-Reflect",
|
||||
"%{IncludeDir.RTTR}/include",
|
||||
"%{IncludeDir.tinyddsloader}"
|
||||
}
|
||||
|
||||
externalwarnings "Off"
|
||||
|
@ -71,8 +73,12 @@ project "SHADE_Application"
|
|||
|
||||
filter "configurations:Debug"
|
||||
symbols "On"
|
||||
defines {"_DEBUG"}
|
||||
defines {"_DEBUG", "SHEDITOR"}
|
||||
|
||||
filter "configurations:Release"
|
||||
optimize "On"
|
||||
defines{"_RELEASE", "SHEDITOR"}
|
||||
|
||||
filter "configurations:Publish"
|
||||
optimize "On"
|
||||
defines{"_RELEASE"}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
//#define SHEDITOR
|
||||
#ifdef SHEDITOR
|
||||
#include "Editor/SHEditor.h"
|
||||
#include "Editor/SHEditor.hpp"
|
||||
//#include "Scenes/SBEditorScene.h"
|
||||
#endif // SHEDITOR
|
||||
|
||||
|
@ -28,6 +28,8 @@
|
|||
#include "Scenes/SBTestScene.h"
|
||||
#include "Math/Transform/SHTransformComponent.h"
|
||||
|
||||
#include "Assets/SHAssetManager.h"
|
||||
|
||||
using namespace SHADE;
|
||||
|
||||
namespace Sandbox
|
||||
|
@ -44,14 +46,13 @@ namespace Sandbox
|
|||
// Set working directory
|
||||
SHADE::SHFileUtilities::SetWorkDirToExecDir();
|
||||
|
||||
SDL_Init(SDL_INIT_EVERYTHING);
|
||||
window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
|
||||
|
||||
// Create Systems
|
||||
SHADE::SHSystemManager::CreateSystem<SHADE::SHGraphicsSystem>();
|
||||
SHADE::SHSystemManager::CreateSystem<SHADE::SHScriptEngine>();
|
||||
// TODO(Diren): Create Physics System here
|
||||
SHADE::SHSystemManager::CreateSystem<SHADE::SHTransformSystem>();
|
||||
SHADE::SHSystemManager::CreateSystem<SHADE::SHGraphicsSystem>();
|
||||
SHADE::SHGraphicsSystem* graphicsSystem = static_cast<SHADE::SHGraphicsSystem*>(SHADE::SHSystemManager::GetSystem<SHADE::SHGraphicsSystem>());
|
||||
SHADE::SHSystemManager::CreateSystem<SHADE::SHInputManagerSystem>();
|
||||
|
||||
|
@ -75,15 +76,20 @@ namespace Sandbox
|
|||
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHTransformComponent>();
|
||||
|
||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHInputManagerSystem, SHADE::SHInputManagerSystem::InputManagerRoutine>();
|
||||
|
||||
//TODO: REMOVE AFTER PRESENTATION
|
||||
SHADE::SHAssetManager::LoadDataTemp("../../Assets/racoon.fbx");
|
||||
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
|
||||
graphicsSystem->SetWindow(&window);
|
||||
sdlWindow = SDL_CreateWindowFrom(window.GetHWND());
|
||||
//auto [w, h] = window.GetWindowSize();
|
||||
//SDL_SetWindowSize(sdlWindow, w, h);
|
||||
|
||||
|
||||
SHADE::SHSystemManager::Init();
|
||||
#ifdef SHEDITOR
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
sdlWindow = SDL_CreateWindowFrom(window.GetHWND());
|
||||
SHADE::SHEditor::Initialise(sdlWindow);
|
||||
#else
|
||||
#endif
|
||||
|
@ -104,13 +110,9 @@ namespace Sandbox
|
|||
graphicsSystem->BeginRender();
|
||||
|
||||
#ifdef SHEDITOR
|
||||
SHADE::SHEditor::PreRender();
|
||||
//SHADE::SHEditor::Render();
|
||||
SHADE::SHEditor::Update(0.16f);
|
||||
#endif
|
||||
|
||||
#ifdef SHEDITOR
|
||||
SHADE::SHEditor::Render();
|
||||
#endif
|
||||
graphicsSystem->Run(1.0f);
|
||||
graphicsSystem->EndRender();
|
||||
|
||||
|
@ -123,11 +125,12 @@ namespace Sandbox
|
|||
{
|
||||
#ifdef SHEDITOR
|
||||
SHADE::SHEditor::Exit();
|
||||
#endif
|
||||
SHSceneManager::Exit();
|
||||
SHADE::SHSystemManager::Exit();
|
||||
SDL_DestroyWindow(sdlWindow);
|
||||
SDL_Quit();
|
||||
#endif
|
||||
|
||||
SHSceneManager::Exit();
|
||||
SHADE::SHSystemManager::Exit();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include "Scripting/SHScriptEngine.h"
|
||||
#include "Math/Transform/SHTransformComponent.h"
|
||||
|
||||
#include "Assets/SHAssetManager.h"
|
||||
|
||||
using namespace SHADE;
|
||||
|
||||
namespace Sandbox
|
||||
|
@ -33,6 +35,23 @@ namespace Sandbox
|
|||
SHADE::SHGraphicsSystem* graphicsSystem = static_cast<SHADE::SHGraphicsSystem*>(SHADE::SHSystemManager::GetSystem<SHADE::SHGraphicsSystem>());
|
||||
// Create temp meshes
|
||||
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)
|
||||
{
|
||||
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();
|
||||
|
||||
// Create Materials
|
||||
|
@ -44,22 +63,33 @@ namespace Sandbox
|
|||
constexpr int NUM_COLS = 1;
|
||||
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 };
|
||||
for (int z = 0; z < NUM_ROWS; ++z)
|
||||
for (int x = 0; x < NUM_COLS; ++x)
|
||||
{
|
||||
//for (int z = 0; z < NUM_ROWS; ++z)
|
||||
//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& renderable = *SHComponentManager::GetComponent_s<SHRenderable>(entity);
|
||||
auto& transform = *SHComponentManager::GetComponent_s<SHTransformComponent>(entity);
|
||||
|
||||
renderable.Mesh = CUBE_MESH;
|
||||
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);
|
||||
}
|
||||
|
||||
// Create blank entity with a script
|
||||
testObj = SHADE::SHEntityManager::CreateEntity();
|
||||
|
|
|
@ -42,6 +42,7 @@ project "SHADE_Engine"
|
|||
"%{IncludeDir.VULKAN}\\include",
|
||||
"%{IncludeDir.VULKAN}\\Source\\SPIRV-Reflect",
|
||||
"%{IncludeDir.dotnet}\\include",
|
||||
"%{IncludeDir.tinyddsloader}"
|
||||
}
|
||||
|
||||
externalwarnings "Off"
|
||||
|
@ -103,19 +104,37 @@ project "SHADE_Engine"
|
|||
{
|
||||
"xcopy /s /r /y /q \"%{IncludeDir.spdlog}\\bin\" \"$(OutDir)\"",
|
||||
"xcopy /r /y /q \"%{IncludeDir.SDL}\\lib\\SDL2.dll\" \"$(OutDir)\"",
|
||||
"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'
|
||||
|
||||
filter "configurations:Debug"
|
||||
symbols "On"
|
||||
defines {"_DEBUG"}
|
||||
defines {"_DEBUG", "SHEDITOR"}
|
||||
links{"assimp-vc142-mtd.lib", "librttr_core_d.lib", "spdlogd.lib"}
|
||||
--links{"fmodstudioL_vc.lib", "fmodL_vc.lib"}
|
||||
|
||||
filter "configurations:Release"
|
||||
optimize "On"
|
||||
defines{"_RELEASE", "SHEDITOR"}
|
||||
links{"assimp-vc142-mt.lib", "librttr_core.lib", "spdlog.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,11 @@
|
|||
#pragma once
|
||||
|
||||
#include "tinyddsloader.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
struct SHDDSAsset
|
||||
{
|
||||
tinyddsloader::DDSFile image;
|
||||
};
|
||||
}
|
|
@ -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,38 @@
|
|||
#include "SHpch.h"
|
||||
#include "SHDDSLoader.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
std::string SHDDSLoader::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 magicword 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";
|
||||
}
|
||||
}
|
||||
|
||||
void SHDDSLoader::LoadImageAsset(AssetPath path, SHDDSAsset& asset)
|
||||
{
|
||||
tinyddsloader::Result loadResult = tinyddsloader::Result::Success;
|
||||
loadResult = asset.image.Load(path.string().c_str());
|
||||
if (loadResult != tinyddsloader::Result::Success)
|
||||
{
|
||||
SHLOG_ERROR("Unable to load DDS file: {} at {}", TinyDDSResultToString(loadResult), path.string());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
#define TINYDDSLOADER_IMPLEMENTATION
|
||||
|
||||
#include "../SHAssetMacros.h"
|
||||
#include "../Asset Types/SHDDSAsset.h"
|
||||
#include "tinyddsloader.h"
|
||||
#include <vector>
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
class SHDDSLoader
|
||||
{
|
||||
private:
|
||||
static std::string TinyDDSResultToString(tinyddsloader::Result value);
|
||||
public:
|
||||
static void LoadImageAsset(AssetPath paths, SHDDSAsset& image);
|
||||
};
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
#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_PreTransformVertices // pre-transform all vertices
|
||||
| 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,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,96 @@
|
|||
/******************************************************************************
|
||||
* \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 ".dds"
|
||||
#define FBX_EXTENSION ".fbx"
|
||||
#define MESH_EXTENSION ".shmesh"
|
||||
|
||||
std::string const EXTENSIONS[] = {
|
||||
AUDIO_EXTENSION,
|
||||
SHADER_EXTENSION,
|
||||
MATERIAL_EXTENSION,
|
||||
IMAGE_EXTENSION,
|
||||
TEXTURE_EXTENSION,
|
||||
MESH_EXTENSION,
|
||||
SCRIPT_EXTENSION,
|
||||
SCENE_EXTENSION,
|
||||
PREFAB_EXTENSION,
|
||||
AUDIO_WAV_EXTENSION,
|
||||
FBX_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/SHDDSLoader.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, SHDDSAsset> SHAssetManager::ddsCollection;
|
||||
|
||||
/****************************************************************************
|
||||
* \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() == FBX_EXTENSION)
|
||||
{
|
||||
LoadGLTF(
|
||||
{
|
||||
.name {path.filename().string()},
|
||||
.id {0},
|
||||
.type {AssetType::MESH},
|
||||
.path {path},
|
||||
.location {0}
|
||||
}
|
||||
);
|
||||
}
|
||||
else if (path.extension().string() == TEXTURE_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<SHDDSAsset> SHAssetManager::GetAllDDS() noexcept
|
||||
{
|
||||
std::vector<SHDDSAsset> result;
|
||||
for (auto const& dds : ddsCollection)
|
||||
{
|
||||
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
|
||||
{
|
||||
SHDDSAsset image;
|
||||
|
||||
SHDDSLoader::LoadImageAsset(asset.path, image);
|
||||
|
||||
ddsCollection.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/SHDDSAsset.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<SHDDSAsset> GetAllDDS() 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, SHDDSAsset> ddsCollection;
|
||||
};
|
||||
}
|
|
@ -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 "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 "Graphics/Instance/SHVkInstance.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.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_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
|
||||
{
|
||||
//#==============================================================#
|
||||
//|| Initialise static members ||
|
||||
//#==============================================================#
|
||||
Handle<SHVkCommandPool> SHEditor::imguiCommandPool;
|
||||
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::CreateContext();
|
||||
if(auto context = ImGui::CreateContext())
|
||||
{
|
||||
if(context == nullptr)
|
||||
{
|
||||
SHLOG_CRITICAL("Failed to create ImGui Context")
|
||||
}
|
||||
}
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; //Enable for Multi-Viewports
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; //Enable docking
|
||||
|
||||
ImGui_ImplSDL2_InitForVulkan(sdlWindow);
|
||||
InitFonts();
|
||||
InitBackend(sdlWindow);
|
||||
|
||||
auto* gfxSystem = reinterpret_cast<SHGraphicsSystem*>(SHSystemManager::GetSystem<SHGraphicsSystem>());
|
||||
SetStyle(Style::SHADE);
|
||||
|
||||
//Add editor windows
|
||||
CreateEditorWindow<SHEditorMenuBar>();
|
||||
CreateEditorWindow<SHHierarchyPanel>();
|
||||
CreateEditorWindow<SHEditorInspector>();
|
||||
|
||||
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 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)};
|
||||
SHLOG_INFO("Successfully initialised SHADE Engine Editor")
|
||||
}
|
||||
|
||||
void SHEditor::PreRender()
|
||||
void SHEditor::Update(float const dt)
|
||||
{
|
||||
(void)dt;
|
||||
NewFrame();
|
||||
|
||||
ImGui::ShowDemoWindow();
|
||||
ImGui::Begin("Your mom");
|
||||
if (ImGui::Button("OP"))
|
||||
for (const auto& window : editorWindows | std::views::values)
|
||||
{
|
||||
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()
|
||||
|
@ -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()
|
||||
{
|
||||
ImGui_ImplVulkan_Shutdown();
|
||||
|
@ -94,19 +152,164 @@ namespace SHADE
|
|||
ImGui::DestroyContext();
|
||||
}
|
||||
|
||||
|
||||
void SHEditor::InitBackend()
|
||||
void SHEditor::SetStyle(Style style)
|
||||
{
|
||||
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()
|
||||
{
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event) != 0)
|
||||
{
|
||||
ImGui_ImplSDL2_ProcessEvent(&event);
|
||||
}
|
||||
ImGui_ImplVulkan_NewFrame();
|
||||
ImGui_ImplSDL2_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())
|
||||
{
|
||||
folder->files.emplace_back(
|
||||
dirEntry.path().filename().string(),
|
||||
dirEntry.path().string(),
|
||||
dirEntry.path().extension().string()
|
||||
);
|
||||
|
||||
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
|
||||
{
|
||||
assert(
|
||||
|
|
|
@ -14,12 +14,22 @@ namespace SHADE
|
|||
typedef uint64_t FolderLocation;
|
||||
typedef uint64_t FolderHandle;
|
||||
typedef std::string FolderName;
|
||||
typedef std::string FileName;
|
||||
typedef std::string FolderPath;
|
||||
typedef std::string FilePath;
|
||||
typedef std::string FileExt;
|
||||
typedef SHFolder* FolderPointer;
|
||||
|
||||
constexpr char FOLDER_BIT_ALLOCATE{ 4 };
|
||||
constexpr char FOLDER_MAX_DEPTH{ 16 };
|
||||
|
||||
struct SHFile
|
||||
{
|
||||
FileName name;
|
||||
FilePath path;
|
||||
FileExt ext;
|
||||
};
|
||||
|
||||
class SHFolder
|
||||
{
|
||||
public:
|
||||
|
@ -28,6 +38,7 @@ namespace SHADE
|
|||
FolderHandle id;
|
||||
FolderName name;
|
||||
std::vector<FolderPointer> subFolders;
|
||||
std::vector<SHFile> files;
|
||||
|
||||
bool folded;
|
||||
|
||||
|
@ -45,6 +56,8 @@ namespace SHADE
|
|||
|
||||
static void StartupFillDirectories(FolderPath path) noexcept;
|
||||
|
||||
static FolderPointer GetRoot() noexcept;
|
||||
|
||||
private:
|
||||
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("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("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);
|
||||
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
|
||||
auto gBufferWriteSubpass = node->AddSubpass("G-Buffer Write");
|
||||
//gBufferWriteSubpass->AddColorOutput("Scene");
|
||||
gBufferWriteSubpass->AddColorOutput("Present");
|
||||
//writeSubpass->AddColorOutput("Normals");
|
||||
|
||||
|
|
|
@ -202,6 +202,7 @@ namespace SHADE
|
|||
Handle<SHVkPhysicalDevice> GetPhysicalDevice() const { return physicalDevice; }
|
||||
Handle<SHVkQueue> GetQueue() const { return graphicsQueue; }
|
||||
Handle<SHVkDescriptorPool> GetDescriptorPool() const { return descPool; }
|
||||
Handle<SHViewport> GetDefaultViewport() const {return defaultViewport;}
|
||||
//SHRenderGraph const& GetRenderGraph(void) const noexcept;
|
||||
|
||||
//Handle<SHVkRenderpass> GetRenderPass() const { return renderPass; }
|
||||
|
|
|
@ -284,6 +284,7 @@ namespace SHADE
|
|||
SHRenderGraph(SHRenderGraph&& rhs) noexcept;
|
||||
SHRenderGraph& operator=(SHRenderGraph&& rhs) noexcept;
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* PUBLIC MEMBER FUNCTIONS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
|
|
@ -181,4 +181,15 @@ namespace SHADE
|
|||
updateQueue.push({ UpdateCommandType::WORLD_SCALE, newWorldScale });
|
||||
}
|
||||
|
||||
} // 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 <rttr/registration>
|
||||
// Project Headers
|
||||
#include "SH_API.h"
|
||||
#include "ECS_Base/Components/SHComponent.h"
|
||||
|
@ -116,6 +117,8 @@ namespace SHADE
|
|||
SHTransform world;
|
||||
|
||||
UpdateQueue updateQueue;
|
||||
|
||||
RTTR_ENABLE()
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -66,27 +66,23 @@ namespace SHADE
|
|||
|
||||
for (const auto* child : node->GetChildren())
|
||||
{
|
||||
|
||||
|
||||
|
||||
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)
|
||||
auto* childTransform = SHComponentManager::GetComponent_s<SHTransformComponent>(child->GetEntityID());
|
||||
if (childTransform)
|
||||
{
|
||||
if (childTransform->dirty || HAS_PARENT_CHANGED)
|
||||
UpdateTransform(*childTransform, NODE_TRANSFORM);
|
||||
// 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)
|
||||
UpdateTransform(*childTransform, NODE_TRANSFORM);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateEntity(child);
|
||||
|
||||
// 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();
|
||||
|
||||
// Transpose TRS to column major
|
||||
tf.local.trs.Transpose();
|
||||
tf.world.trs.Transpose();
|
||||
//tf.local.trs.Transpose();
|
||||
//tf.world.trs.Transpose();
|
||||
}
|
||||
|
||||
} // namespace SHADE
|
|
@ -7,7 +7,8 @@ workspace "SHADE"
|
|||
configurations
|
||||
{
|
||||
"Debug",
|
||||
"Release"
|
||||
"Release",
|
||||
"Publish"
|
||||
}
|
||||
|
||||
flags
|
||||
|
|
Loading…
Reference in New Issue