Merge branch 'main' into SP3-8-serialization
This commit is contained in:
commit
9aaacbf5ea
|
@ -30,13 +30,14 @@ project "SHADE_Application"
|
|||
|
||||
externalincludedirs
|
||||
{
|
||||
"%{IncludeDir.spdlog}/include",
|
||||
"%{IncludeDir.VULKAN}/include",
|
||||
"%{IncludeDir.VMA}/include",
|
||||
"%{IncludeDir.VULKAN}/Source/SPIRV-Reflect",
|
||||
"%{IncludeDir.tinyddsloader}",
|
||||
"%{IncludeDir.RTTR}\\include",
|
||||
"%{IncludeDir.fmod}/include",
|
||||
"%{IncludeDir.RTTR}\\include"
|
||||
"%{IncludeDir.VULKAN}/Source/SPIRV-Reflect",
|
||||
"%{IncludeDir.VMA}/include",
|
||||
"%{IncludeDir.VULKAN}/include",
|
||||
"%{IncludeDir.spdlog}/include",
|
||||
"%{IncludeDir.tinyddsloader}",
|
||||
"%{IncludeDir.reactphysics3d}\\include"
|
||||
}
|
||||
|
||||
externalwarnings "Off"
|
||||
|
@ -57,7 +58,7 @@ project "SHADE_Application"
|
|||
libdirs
|
||||
{
|
||||
"%{IncludeDir.spdlog}/lib",
|
||||
"%{IncludeDir.SDL}/lib",
|
||||
"%{IncludeDir.SDL}/lib"
|
||||
}
|
||||
|
||||
defines
|
||||
|
|
|
@ -16,19 +16,28 @@
|
|||
#include <ctime>
|
||||
#include <SDL.h>
|
||||
|
||||
#include "Scripting/SHScriptEngine.h"
|
||||
|
||||
#include "Graphics/MiddleEnd/Meshes/SHPrimitiveGenerator.h"
|
||||
|
||||
// Managers
|
||||
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||
#include "Scene/SHSceneManager.h"
|
||||
|
||||
// Systems
|
||||
#include "Scripting/SHScriptEngine.h"
|
||||
#include "Physics/SHPhysicsSystem.h"
|
||||
#include "Math/Transform/SHTransformSystem.h"
|
||||
#include "Input/SHInputManager.h"
|
||||
#include "FRC/SHFramerateController.h"
|
||||
#include "AudioSystem/SHAudioSystem.h"
|
||||
|
||||
#include "Scenes/SBTestScene.h"
|
||||
// Components
|
||||
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||
#include "Math/Transform/SHTransformComponent.h"
|
||||
|
||||
#include "Scenes/SBTestScene.h"
|
||||
|
||||
|
||||
#include "Assets/SHAssetManager.h"
|
||||
|
||||
#include "Tools/SHLogger.h"
|
||||
|
@ -54,7 +63,7 @@ namespace Sandbox
|
|||
// Create Systems
|
||||
SHADE::SHSystemManager::CreateSystem<SHADE::SHGraphicsSystem>();
|
||||
SHADE::SHSystemManager::CreateSystem<SHADE::SHScriptEngine>();
|
||||
// TODO(Diren): Create Physics System here
|
||||
SHADE::SHSystemManager::CreateSystem<SHADE::SHPhysicsSystem>();
|
||||
SHADE::SHSystemManager::CreateSystem<SHADE::SHTransformSystem>();
|
||||
SHADE::SHGraphicsSystem* graphicsSystem = static_cast<SHADE::SHGraphicsSystem*>(SHADE::SHSystemManager::GetSystem<SHADE::SHGraphicsSystem>());
|
||||
SHADE::SHSystemManager::CreateSystem<SHADE::SHAudioSystem>();
|
||||
|
@ -65,18 +74,21 @@ namespace Sandbox
|
|||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHScriptEngine, SHADE::SHScriptEngine::LateUpdateRoutine>();
|
||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHScriptEngine, SHADE::SHScriptEngine::FrameCleanUpRoutine>();
|
||||
|
||||
// TODO(Diren): Register Physics System & Routines here
|
||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHPhysicsSystem, SHADE::SHPhysicsSystem::PhysicsPreUpdate>();
|
||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHPhysicsSystem, SHADE::SHPhysicsSystem::PhysicsFixedUpdate>();
|
||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHPhysicsSystem, SHADE::SHPhysicsSystem::PhysicsPostUpdate>();
|
||||
|
||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHTransformSystem, SHADE::SHTransformSystem::TransformUpdateRoutine>();
|
||||
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHTransformComponent>();
|
||||
|
||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::BatcherDispatcherRoutine>();
|
||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::BeginRoutine>();
|
||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::RenderRoutine>();
|
||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::EndRoutine>();
|
||||
|
||||
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHRenderable>();
|
||||
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHRigidBodyComponent>();
|
||||
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHColliderComponent>();
|
||||
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHTransformComponent>();
|
||||
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHRenderable>();
|
||||
|
||||
//TODO: REMOVE AFTER PRESENTATION
|
||||
//SHADE::SHAssetManager::LoadDataTemp("../../Assets/racoon.gltf");
|
||||
|
@ -133,6 +145,9 @@ namespace Sandbox
|
|||
|
||||
SHADE::SHSystemManager::RunRoutines(false, 0.016f);
|
||||
}
|
||||
|
||||
// Finish all graphics jobs first
|
||||
graphicsSystem->AwaitGraphicsExecution();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include "Scripting/SHScriptEngine.h"
|
||||
#include "Math/Transform/SHTransformComponent.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
|
||||
#include "Physics/Components/SHRigidBodyComponent.h"
|
||||
#include "Physics/Components/SHColliderComponent.h"
|
||||
|
||||
#include "Assets/SHAssetManager.h"
|
||||
|
||||
|
@ -18,9 +20,9 @@ using namespace SHADE;
|
|||
namespace Sandbox
|
||||
{
|
||||
|
||||
void SBTestScene::WindowFocusFunc([[maybe_unused]]void* window, int focused)
|
||||
void SBTestScene::WindowFocusFunc([[maybe_unused]] void* window, int focused)
|
||||
{
|
||||
if(focused)
|
||||
if (focused)
|
||||
{
|
||||
}
|
||||
else
|
||||
|
@ -44,15 +46,15 @@ namespace Sandbox
|
|||
{
|
||||
if (mesh.header.meshName == "Cube.012")
|
||||
{
|
||||
handles.push_back(graphicsSystem->AddMesh(
|
||||
mesh.header.vertexCount,
|
||||
mesh.vertexPosition.data(),
|
||||
mesh.texCoords.data(),
|
||||
mesh.vertexTangent.data(),
|
||||
mesh.vertexNormal.data(),
|
||||
mesh.header.indexCount,
|
||||
mesh.indices.data()
|
||||
));
|
||||
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();
|
||||
|
@ -62,8 +64,8 @@ namespace Sandbox
|
|||
std::vector<Handle<SHTexture>> texHandles;
|
||||
for (const auto& tex : textures)
|
||||
{
|
||||
auto texture = graphicsSystem->Add(tex);
|
||||
texHandles.push_back(texture);
|
||||
auto texture = graphicsSystem->Add(tex);
|
||||
texHandles.push_back(texture);
|
||||
}
|
||||
graphicsSystem->BuildTextures();
|
||||
|
||||
|
@ -75,37 +77,38 @@ namespace Sandbox
|
|||
customMat->SetProperty("data.alpha", 0.1f);
|
||||
|
||||
// Create Stress Test Objects
|
||||
static const SHVec3 TEST_OBJ_SCALE = { 0.05f, 0.05f, 0.05f };
|
||||
constexpr int NUM_ROWS = 100;
|
||||
constexpr int NUM_COLS = 100;
|
||||
static const SHVec3 TEST_OBJ_SPACING = { 0.05f, 0.05f, 0.05f };
|
||||
static const SHVec3 TEST_OBJ_START_POS = { - (NUM_COLS / 2 * TEST_OBJ_SPACING.x ) + 1.0f, -2.0f, -1.0f };
|
||||
static const SHVec3 TEST_OBJ_SCALE = SHVec3::One * 0.5f;
|
||||
constexpr int NUM_ROWS = 10;
|
||||
constexpr int NUM_COLS = 10;
|
||||
static const SHVec3 TEST_OBJ_SPACING = { 0.1f, 0.1f, 0.1f };
|
||||
static const SHVec3 TEST_OBJ_START_POS = { -(NUM_COLS / 2 * TEST_OBJ_SPACING.x) + 1.0f, -2.0f, -1.0f };
|
||||
|
||||
for (int y = 0; y < NUM_ROWS; ++y)
|
||||
for (int x = 0; x < NUM_COLS; ++x)
|
||||
{
|
||||
auto entity = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
||||
for (int x = 0; x < NUM_COLS; ++x)
|
||||
{
|
||||
auto entity = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent, SHRigidBodyComponent, SHColliderComponent>();
|
||||
auto& renderable = *SHComponentManager::GetComponent_s<SHRenderable>(entity);
|
||||
auto& transform = *SHComponentManager::GetComponent_s<SHTransformComponent>(entity);
|
||||
auto& transform = *SHComponentManager::GetComponent_s<SHTransformComponent>(entity);
|
||||
auto& collider = *SHComponentManager::GetComponent_s<SHColliderComponent>(entity);
|
||||
|
||||
renderable.Mesh = handles.front();
|
||||
//renderable.Mesh = handles.front();
|
||||
renderable.Mesh = CUBE_MESH;
|
||||
renderable.SetMaterial(customMat);
|
||||
|
||||
if (y == 50)
|
||||
renderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(1.0f, 0.0f, 0.0f, 1.0f));
|
||||
|
||||
//Set initial positions
|
||||
transform.SetWorldPosition(TEST_OBJ_START_POS + SHVec3{
|
||||
x * TEST_OBJ_SPACING.x,
|
||||
y * TEST_OBJ_SPACING.y,
|
||||
0.0f
|
||||
});
|
||||
transform.SetWorldPosition(TEST_OBJ_START_POS + SHVec3{ x * TEST_OBJ_SPACING.x, y * TEST_OBJ_SPACING.y, SHMath::GenerateRandomNumber(-3.5f, -5.0f)});
|
||||
//transform.SetWorldPosition({-1.0f, -1.0f, -1.0f});
|
||||
//transform.SetWorldRotation(3.14159265f * 1.5f, -3.14159265f / 2.0f, 0.0f);
|
||||
transform.SetLocalScale(TEST_OBJ_SCALE);
|
||||
transform.SetWorldRotation(SHMath::GenerateRandomNumber(), SHMath::GenerateRandomNumber(), SHMath::GenerateRandomNumber());
|
||||
transform.SetWorldScale(TEST_OBJ_SCALE);
|
||||
|
||||
auto* box = collider.AddBoundingBox();
|
||||
box->SetHalfExtents(transform.GetWorldScale() * 0.5f);
|
||||
|
||||
stressTestObjects.emplace_back(entity);
|
||||
}
|
||||
}
|
||||
|
||||
auto raccoonSpin = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
||||
auto& renderable = *SHComponentManager::GetComponent_s<SHRenderable>(raccoonSpin);
|
||||
|
@ -117,41 +120,50 @@ namespace Sandbox
|
|||
renderable.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f);
|
||||
renderable.GetModifiableMaterial()->SetProperty("data.textureIndex", 0);
|
||||
|
||||
transform.SetWorldPosition ({-3.0f, -1.0f, -1.0f});
|
||||
transform.SetLocalScale({5.0f, 5.0f, 5.0f});
|
||||
transform.SetWorldPosition({ -3.0f, -1.0f, -1.0f });
|
||||
transform.SetLocalScale({ 5.0f, 5.0f, 5.0f });
|
||||
|
||||
//auto entity = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
||||
//auto& renderable = *SHComponentManager::GetComponent_s<SHRenderable>(entity);
|
||||
//auto& transform = *SHComponentManager::GetComponent_s<SHTransformComponent>(entity);
|
||||
auto floor = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent, SHRigidBodyComponent, SHColliderComponent>();
|
||||
auto& floorRenderable = *SHComponentManager::GetComponent_s<SHRenderable>(floor);
|
||||
auto& floorTransform = *SHComponentManager::GetComponent_s<SHTransformComponent>(floor);
|
||||
auto& floorRigidBody = *SHComponentManager::GetComponent_s<SHRigidBodyComponent>(floor);
|
||||
auto& floorCollider = *SHComponentManager::GetComponent_s<SHColliderComponent>(floor);
|
||||
|
||||
//renderable.Mesh = handles.back();
|
||||
//renderable.SetMaterial(customMat);
|
||||
floorRenderable.Mesh = CUBE_MESH;
|
||||
floorRenderable.SetMaterial(customMat);
|
||||
floorRenderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
|
||||
//transform.SetLocalScale(TEST_OBJ_SCALE);
|
||||
//transform.SetWorldPosition({-1.0f, -1.0f, -1.0f});
|
||||
floorTransform.SetWorldScale({7.5f, 0.5f, 7.5});
|
||||
floorTransform.SetWorldPosition({0.0f, -3.0f, -5.0f});
|
||||
|
||||
floorRigidBody.SetType(SHRigidBodyComponent::Type::STATIC);
|
||||
|
||||
auto* floorBox = floorCollider.AddBoundingBox();
|
||||
floorBox->SetHalfExtents(floorTransform.GetWorldScale() * 0.5f);
|
||||
|
||||
// Create blank entity with a script
|
||||
//testObj = SHADE::SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
||||
//auto& testObjRenderable = *SHComponentManager::GetComponent_s<SHRenderable>(testObj);
|
||||
//auto& testObjRenderable = *SHComponentManager::GetComponent<SHRenderable>(testObj);
|
||||
//testObjRenderable.Mesh = CUBE_MESH;
|
||||
//testObjRenderable.SetMaterial(matInst);
|
||||
|
||||
|
||||
SHADE::SHScriptEngine* scriptEngine = static_cast<SHADE::SHScriptEngine*>(SHADE::SHSystemManager::GetSystem<SHADE::SHScriptEngine>());
|
||||
scriptEngine->AddScript(raccoonSpin, "RaccoonSpin");
|
||||
scriptEngine->AddScript(raccoonSpin, "RaccoonSpin");
|
||||
|
||||
auto raccoonShowcase = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
||||
auto& renderableShowcase = *SHComponentManager::GetComponent_s<SHRenderable>(raccoonShowcase);
|
||||
auto& transformShowcase = *SHComponentManager::GetComponent_s<SHTransformComponent>(raccoonShowcase);
|
||||
auto raccoonShowcase = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
||||
auto& renderableShowcase = *SHComponentManager::GetComponent_s<SHRenderable>(raccoonShowcase);
|
||||
auto& transformShowcase = *SHComponentManager::GetComponent_s<SHTransformComponent>(raccoonShowcase);
|
||||
|
||||
renderableShowcase.Mesh = handles.front();
|
||||
renderableShowcase.SetMaterial(customMat);
|
||||
renderableShowcase.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f));
|
||||
renderableShowcase.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f);
|
||||
renderableShowcase.GetModifiableMaterial()->SetProperty("data.textureIndex", 0);
|
||||
renderableShowcase.Mesh = handles.front();
|
||||
renderableShowcase.SetMaterial(customMat);
|
||||
renderableShowcase.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f));
|
||||
renderableShowcase.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f);
|
||||
renderableShowcase.GetModifiableMaterial()->SetProperty("data.textureIndex", 0);
|
||||
|
||||
transformShowcase.SetWorldPosition({ 3.0f, -1.0f, -1.0f });
|
||||
transformShowcase.SetLocalScale({ 5.0f, 5.0f, 5.0f });
|
||||
scriptEngine->AddScript(raccoonShowcase, "RaccoonShowcase");
|
||||
transformShowcase.SetWorldPosition({ 3.0f, -1.0f, -1.0f });
|
||||
transformShowcase.SetLocalScale({ 5.0f, 5.0f, 5.0f });
|
||||
scriptEngine->AddScript(raccoonShowcase, "RaccoonShowcase");
|
||||
}
|
||||
|
||||
void SBTestScene::Update(float dt)
|
||||
|
@ -168,8 +180,8 @@ namespace Sandbox
|
|||
if (GetKeyState(VK_SPACE) & 0x8000)
|
||||
{
|
||||
rotation = 0.0f;
|
||||
SHADE::SHScriptEngine* scriptEngine = static_cast<SHADE::SHScriptEngine*>(SHADE::SHSystemManager::GetSystem<SHADE::SHScriptEngine>());
|
||||
scriptEngine->RemoveAllScripts(testObj);
|
||||
SHADE::SHScriptEngine* scriptEngine = static_cast<SHADE::SHScriptEngine*>(SHADE::SHSystemManager::GetSystem<SHADE::SHScriptEngine>());
|
||||
scriptEngine->RemoveAllScripts(testObj);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -186,8 +198,4 @@ namespace Sandbox
|
|||
{
|
||||
//SHSerialization::SerializeScene("resources/scenes/Scene01.SHADE");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ project "SHADE_Engine"
|
|||
"%{IncludeDir.RTTR}/lib",
|
||||
"%{IncludeDir.SDL}/lib",
|
||||
"%{IncludeDir.spdlog}/lib",
|
||||
"%{IncludeDir.fmod}/lib",
|
||||
"%{IncludeDir.fmod}/lib"
|
||||
}
|
||||
|
||||
links
|
||||
|
@ -163,8 +163,8 @@ project "SHADE_Engine"
|
|||
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",
|
||||
-- "%{prj.location}/src/Editor/**.cpp",
|
||||
-- "%{prj.location}/src/Editor/**.h",
|
||||
-- "%{prj.location}/src/Editor/**.hpp",
|
||||
}
|
||||
links{"fmodstudio_vc.lib", "fmod_vc.lib"}
|
|
@ -17,7 +17,8 @@ namespace SHADE
|
|||
SHTexture::PixelChannel const * pixelData;
|
||||
|
||||
SHTextureAsset()
|
||||
: numBytes{ 0 },
|
||||
: compiled{ false },
|
||||
numBytes{ 0 },
|
||||
width{ 0 },
|
||||
height{ 0 },
|
||||
format{ SHTexture::TextureFormat::eUndefined },
|
||||
|
@ -25,7 +26,8 @@ namespace SHADE
|
|||
{}
|
||||
|
||||
SHTextureAsset(SHTextureAsset const& rhs)
|
||||
: numBytes{ rhs.numBytes },
|
||||
: compiled{ false },
|
||||
numBytes{ rhs.numBytes },
|
||||
width{ rhs.width },
|
||||
height{ rhs.height },
|
||||
format{ rhs.format },
|
||||
|
|
|
@ -91,8 +91,8 @@ namespace SHADE
|
|||
}
|
||||
}
|
||||
|
||||
result.header.vertexCount = result.vertexPosition.size();
|
||||
result.header.indexCount = result.indices.size();
|
||||
result.header.vertexCount = static_cast<uint32_t>(result.vertexPosition.size());
|
||||
result.header.indexCount = static_cast<uint32_t>(result.indices.size());
|
||||
result.header.meshName = mesh.mName.C_Str();
|
||||
|
||||
return result;
|
||||
|
|
|
@ -83,10 +83,10 @@ namespace SHADE
|
|||
|
||||
std::vector<uint32_t> mipOff(file.GetMipCount());
|
||||
|
||||
for (auto i{0}; i < file.GetMipCount(); ++i)
|
||||
for (size_t i{0}; i < file.GetMipCount(); ++i)
|
||||
{
|
||||
mipOff[i] = totalBytes;
|
||||
totalBytes += file.GetImageData(i, 0)->m_memSlicePitch;
|
||||
mipOff[i] = static_cast<uint32_t>(totalBytes);
|
||||
totalBytes += file.GetImageData(static_cast<uint32_t>(i), 0)->m_memSlicePitch;
|
||||
}
|
||||
|
||||
SHTexture::PixelChannel* pixel = new SHTexture::PixelChannel[totalBytes];
|
||||
|
@ -94,7 +94,7 @@ namespace SHADE
|
|||
//pixel = std::move(reinterpret_cast<SHTexture::PixelChannel const*>(file.GetDDSData()));
|
||||
|
||||
asset.compiled = false;
|
||||
asset.numBytes = totalBytes;
|
||||
asset.numBytes = static_cast<uint32_t>(totalBytes);
|
||||
asset.width = file.GetWidth();
|
||||
asset.height = file.GetHeight();
|
||||
asset.format = ddsLoaderToVkFormat(file.GetFormat(), true);
|
||||
|
|
|
@ -72,12 +72,13 @@ namespace SHADE
|
|||
|
||||
AssetType type = SHAssetMetaHandler::GetTypeFromExtension(path.extension().string().c_str());
|
||||
std::string folder;
|
||||
switch (type)
|
||||
{
|
||||
default:
|
||||
//TODO:ASSERT UNSUPPORTED FILE TYPE
|
||||
return std::filesystem::path();
|
||||
}
|
||||
//TODO Implement asset type generation
|
||||
//switch (type)
|
||||
//{
|
||||
//default:
|
||||
// //TODO:ASSERT UNSUPPORTED FILE TYPE
|
||||
// return std::filesystem::path();
|
||||
//}
|
||||
|
||||
return std::filesystem::path(ASSET_ROOT + folder + path.filename().string());
|
||||
}
|
||||
|
@ -108,12 +109,13 @@ namespace SHADE
|
|||
meta.type = type;
|
||||
|
||||
std::string folder;
|
||||
switch (type)
|
||||
{
|
||||
default:
|
||||
folder = "";
|
||||
break;
|
||||
}
|
||||
//TODO implement folder choosing
|
||||
//switch (type)
|
||||
//{
|
||||
//default:
|
||||
// folder = "";
|
||||
// break;
|
||||
//}
|
||||
AssetPath path{ ASSET_ROOT + folder + name + SHAssetMetaHandler::GetExtensionFromType(type) };
|
||||
|
||||
SHAssetMetaHandler::WriteMetaData(meta);
|
||||
|
|
|
@ -122,7 +122,7 @@ namespace SHADE
|
|||
break;
|
||||
|
||||
default:
|
||||
void;
|
||||
break;
|
||||
}
|
||||
|
||||
metaFile.close();
|
||||
|
|
|
@ -90,7 +90,7 @@ namespace SHADE
|
|||
//PlayEventOnce("event:/SFX/Dawn/Dawn_Attack");
|
||||
}
|
||||
|
||||
void SHADE::SHAudioSystem::Run(float dt)
|
||||
void SHADE::SHAudioSystem::Run(double dt)
|
||||
{
|
||||
static_cast<void>(dt);
|
||||
//if (GetKeyState(VK_SPACE) & 0x8000)
|
||||
|
@ -417,7 +417,7 @@ namespace SHADE
|
|||
int instanceCount = 0;
|
||||
event.second->getInstanceCount(&instanceCount);
|
||||
std::vector<FMOD::Studio::EventInstance*> instances(instanceCount);
|
||||
event.second->getInstanceList(instances.data(), instances.size(), &instanceCount);
|
||||
event.second->getInstanceList(instances.data(), static_cast<int>(instances.size()), &instanceCount);
|
||||
for (auto const& instance : instances)
|
||||
{
|
||||
instance->setPaused(pause);
|
||||
|
|
|
@ -50,7 +50,7 @@ namespace SHADE
|
|||
~SHAudioSystem();
|
||||
|
||||
void Init();
|
||||
void Run(float dt);
|
||||
void Run(double dt);
|
||||
class SH_API AudioRoutine final : public SHSystemRoutine
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -8,23 +8,19 @@ namespace SHADE
|
|||
{
|
||||
class SHFixedSystemRoutine: public SHSystemRoutine
|
||||
{
|
||||
private:
|
||||
double accumulatedTime;
|
||||
double fixedTimeStep;
|
||||
|
||||
protected:
|
||||
SHFixedSystemRoutine(double timeStep = DEFAULT_FIXED_STEP, std::string routineName = "Default Fixed Routine Name", bool editorPause = false)
|
||||
double accumulatedTime;
|
||||
double fixedTimeStep;
|
||||
|
||||
SHFixedSystemRoutine(double timeStep = DEFAULT_FIXED_STEP, std::string routineName = "Default Fixed Routine Name", bool editorPause = false)
|
||||
:SHSystemRoutine(routineName, editorPause), accumulatedTime(0.0), fixedTimeStep(timeStep){}
|
||||
|
||||
|
||||
|
||||
public:
|
||||
~SHFixedSystemRoutine() = default;
|
||||
|
||||
virtual void Execute(double dt) noexcept;
|
||||
|
||||
virtual void FixedExecute(double dt) noexcept {};
|
||||
virtual void Execute(double dt) noexcept override;
|
||||
|
||||
virtual void FixedExecute(double dt) noexcept {}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -5,9 +5,13 @@
|
|||
//#==============================================================#
|
||||
#include <functional>
|
||||
|
||||
#include "SH_API.h"
|
||||
#include "Scripting/SHScriptEngine.h"
|
||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
class SHBaseCommand
|
||||
class SH_API SHBaseCommand
|
||||
{
|
||||
public:
|
||||
virtual ~SHBaseCommand() = default;
|
||||
|
@ -48,4 +52,20 @@ namespace SHADE
|
|||
T newValue;
|
||||
SetterFunction set;
|
||||
};
|
||||
|
||||
class SH_API SHCLICommand : SHBaseCommand
|
||||
{
|
||||
public:
|
||||
SHCLICommand() = default;
|
||||
void Execute() override
|
||||
{
|
||||
SHScriptEngine* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||
scriptEngine->RedoScriptInspectorChanges();
|
||||
}
|
||||
void Undo() override
|
||||
{
|
||||
SHScriptEngine* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||
scriptEngine->UndoScriptInspectorChanges();
|
||||
}
|
||||
};
|
||||
}//namespace SHADE
|
||||
|
|
|
@ -27,6 +27,11 @@ namespace SHADE
|
|||
}
|
||||
}
|
||||
|
||||
void SHCommandManager::RegisterCommand(CommandPtr commandPtr)
|
||||
{
|
||||
undoStack.push(commandPtr);
|
||||
}
|
||||
|
||||
void SHCommandManager::UndoCommand()
|
||||
{
|
||||
if (undoStack.empty())
|
||||
|
|
|
@ -9,10 +9,11 @@
|
|||
//|| SHADE Includes ||
|
||||
//#==============================================================#
|
||||
#include "SHCommand.hpp"
|
||||
#include "SH_API.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
class SHCommandManager
|
||||
class SH_API SHCommandManager
|
||||
{
|
||||
public:
|
||||
//#==============================================================#
|
||||
|
@ -22,6 +23,7 @@ namespace SHADE
|
|||
using CommandStack = std::stack<CommandPtr>;
|
||||
|
||||
static void PerformCommand(CommandPtr commandPtr, bool const& overrideValue = false);
|
||||
static void RegisterCommand(CommandPtr commandPtr);
|
||||
static void UndoCommand();
|
||||
static void RedoCommand();
|
||||
static std::size_t GetUndoStackSize();
|
||||
|
|
|
@ -114,7 +114,7 @@ namespace SHADE
|
|||
|
||||
auto* entity = SHEntityManager::GetEntityByID(currentNode->GetEntityID());
|
||||
//Draw Node
|
||||
bool isNodeOpen = ImGui::TreeNodeEx((void*)eid, nodeFlags, "%u: %s", EntityHandleGenerator::GetIndex(eid), entity->name.c_str());
|
||||
bool isNodeOpen = ImGui::TreeNodeEx(reinterpret_cast<void*>(entity), nodeFlags, "%u: %s", EntityHandleGenerator::GetIndex(eid), entity->name.c_str());
|
||||
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
||||
|
||||
//Check For Begin Drag
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
#include "AudioSystem/SHAudioSystem.h"
|
||||
#include "Physics/Components/SHRigidBodyComponent.h"
|
||||
#include "Physics/Components/SHColliderComponent.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -70,23 +72,28 @@ namespace SHADE
|
|||
{
|
||||
DrawComponent(renderableComponent);
|
||||
}
|
||||
if(auto testComponent = SHComponentManager::GetComponent_s<SHComponent_ENUM>(eid))
|
||||
if(auto colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(eid))
|
||||
{
|
||||
DrawComponent(testComponent);
|
||||
DrawComponent(colliderComponent);
|
||||
}
|
||||
if(auto rigidbodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(eid))
|
||||
{
|
||||
DrawComponent(rigidbodyComponent);
|
||||
}
|
||||
ImGui::Separator();
|
||||
// Render Scripts
|
||||
SHScriptEngine* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||
scriptEngine->RenderScriptsInInspector(eid);
|
||||
ImGui::Separator();
|
||||
if(ImGui::BeginMenu(std::format("{} Add Component", ICON_MD_LIBRARY_ADD).data()))
|
||||
{
|
||||
DrawAddComponentButton<SHTransformComponent>(eid);
|
||||
DrawAddComponentButton<SHRenderable>(eid);
|
||||
DrawAddComponentButton<SHComponent_ENUM>(eid);
|
||||
DrawAddComponentButton<SHColliderComponent>(eid);
|
||||
DrawAddComponentButton<SHRigidBodyComponent>(eid);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
// Render Scripts
|
||||
SHScriptEngine* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||
scriptEngine->RenderScriptsInInspector(eid);
|
||||
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
|
|
@ -843,7 +843,7 @@
|
|||
#define ICON_MD_FLIP_TO_FRONT "\xee\xa2\x83" // U+e883
|
||||
#define ICON_MD_FLOOD "\xee\xaf\xa6" // U+ebe6
|
||||
#define ICON_MD_FLOURESCENT "\xee\xb0\xb1" // U+ec31
|
||||
#define ICON_MD_FLOURESCENT "\xef\x80\x8d" // U+f00d
|
||||
#define ICON_MD_FLOURESCENT2 "\xef\x80\x8d" // U+f00d
|
||||
#define ICON_MD_FLUORESCENT "\xee\xb0\xb1" // U+ec31
|
||||
#define ICON_MD_FLUTTER_DASH "\xee\x80\x8b" // U+e00b
|
||||
#define ICON_MD_FMD_BAD "\xef\x80\x8e" // U+f00e
|
||||
|
|
|
@ -327,7 +327,7 @@ namespace SHADE
|
|||
ImGui::PushID(fieldLabel.c_str());
|
||||
ImGui::Text(fieldLabel.c_str()); ImGui::SameLine();
|
||||
|
||||
if (edited = ImGui::Combo("##Combo", &selected, list.data(), list.size()))
|
||||
if (edited = ImGui::Combo("##Combo", &selected, list.data(), static_cast<int>(list.size())))
|
||||
{
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), selected, set)), false);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#include "SHFileSystem.h"
|
||||
#include "fileapi.h"
|
||||
#include <filesystem>
|
||||
#include <cassert>
|
||||
#include <queue>
|
||||
|
||||
namespace SHADE
|
||||
|
@ -28,7 +27,10 @@ namespace SHADE
|
|||
|
||||
auto const count = static_cast<FolderCounter>(folders[here]->subFolders.size());
|
||||
|
||||
assert(count < FOLDER_MAX_COUNT, "Max subfolders reached\n");
|
||||
if (count >= FOLDER_MAX_COUNT)
|
||||
{
|
||||
SHLOG_ERROR("Max subfolder reached: {}\n", name);
|
||||
}
|
||||
|
||||
auto const location = static_cast<FolderLocation>(count);
|
||||
|
||||
|
@ -37,7 +39,10 @@ namespace SHADE
|
|||
return location;
|
||||
}
|
||||
|
||||
assert(folders.contains(here), "Folder creation location does not exist/invalid\n");
|
||||
if (!folders.contains(here))
|
||||
{
|
||||
SHLOG_ERROR("Folder creation location does not exist/invalid: {}\n", here);
|
||||
}
|
||||
|
||||
auto const count = static_cast<FolderCounter>(folders[here]->subFolders.size());
|
||||
|
||||
|
@ -45,7 +50,11 @@ namespace SHADE
|
|||
location <<= FOLDER_BIT_ALLOCATE;
|
||||
location |= count;
|
||||
|
||||
assert(count < FOLDER_MAX_COUNT, "Max subfolders reached\n");
|
||||
if (count >= FOLDER_MAX_COUNT)
|
||||
{
|
||||
SHLOG_ERROR("Max subfolder reached: {}\n", name);
|
||||
}
|
||||
|
||||
CreateFolder(folders[0]->path, here, location, name);
|
||||
|
||||
return location;
|
||||
|
@ -53,7 +62,10 @@ namespace SHADE
|
|||
|
||||
bool SHFileSystem::DeleteFolder(FolderPointer location) noexcept
|
||||
{
|
||||
assert(folders.contains(location->id), "Delete target does not exist/invalid.\n");
|
||||
if (!folders.contains(location->id))
|
||||
{
|
||||
SHLOG_ERROR("Delete target does not exist/invalid: {}\n", location->name);
|
||||
}
|
||||
|
||||
for (auto const& subFolder : folders[location->id]->subFolders)
|
||||
{
|
||||
|
@ -116,10 +128,11 @@ namespace SHADE
|
|||
|
||||
FolderPointer SHFileSystem::CreateFolder(FolderPath path, FolderLocation parent, FolderHandle location, FolderName name) noexcept
|
||||
{
|
||||
assert(
|
||||
CreateDirectoryA(path.c_str(), nullptr),
|
||||
"Failed to create folder\n"
|
||||
);
|
||||
|
||||
if (!CreateDirectoryA(path.c_str(), nullptr))
|
||||
{
|
||||
SHLOG_ERROR("Failed to create folder: {}\n", path);
|
||||
}
|
||||
|
||||
folders[location] = std::make_unique<SHFolder>(location, name);
|
||||
folders[location]->path = path;
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace SHADE
|
|||
/***************************************************************************/
|
||||
SHVkCommandBuffer::~SHVkCommandBuffer(void) noexcept
|
||||
{
|
||||
if (vkCommandBuffer)
|
||||
if (vkCommandBuffer && parentPool)
|
||||
parentPool->GetLogicalDevice()->GetVkLogicalDevice().freeCommandBuffers(parentPool->GetVkCommandPool(), commandBufferCount, &vkCommandBuffer);
|
||||
}
|
||||
|
||||
|
|
|
@ -102,8 +102,6 @@ namespace SHADE
|
|||
logicalDeviceHdl = rhs.logicalDeviceHdl;
|
||||
transient = rhs.transient;
|
||||
|
||||
static_cast<ISelfHandle<SHVkCommandPool>&>(*this) = static_cast<ISelfHandle<SHVkCommandPool>&>(rhs);
|
||||
|
||||
rhs.vkCommandPool = VK_NULL_HANDLE;
|
||||
|
||||
return *this;
|
||||
|
|
|
@ -208,7 +208,7 @@ namespace SHADE
|
|||
BindingAndSetHash bsHash = SHVkUtil::GenBindingSetHash(set, binding);
|
||||
|
||||
// to index a set
|
||||
uint32_t setIndex = setIndexing[bsHash];
|
||||
uint32_t setIndex = setIndexing[set];
|
||||
|
||||
// to index a write for a binding
|
||||
uint32_t writeInfoIndex = updater.writeHashMap[bsHash];
|
||||
|
@ -233,7 +233,7 @@ namespace SHADE
|
|||
BindingAndSetHash bsHash = SHVkUtil::GenBindingSetHash(set, binding);
|
||||
|
||||
// to index a set
|
||||
uint32_t setIndex = setIndexing[bsHash];
|
||||
uint32_t setIndex = setIndexing[set];
|
||||
|
||||
// to index a write for a binding
|
||||
uint32_t writeInfoIndex = updater.writeHashMap[bsHash];
|
||||
|
|
|
@ -92,7 +92,7 @@ namespace SHADE
|
|||
//uint32_t minBuffer
|
||||
if (alignmentSize > 0)
|
||||
{
|
||||
alignedSize = (alignedSize + alignmentSize - 1) & ~(alignmentSize - 1);
|
||||
alignedSize = (alignedSize + static_cast<uint32_t>(alignmentSize) - 1) & ~(alignmentSize - 1);
|
||||
}
|
||||
return alignedSize;
|
||||
}
|
||||
|
@ -195,6 +195,8 @@ namespace SHADE
|
|||
|
||||
vk::PhysicalDeviceDescriptorIndexingFeatures descIndexingFeature{};
|
||||
descIndexingFeature.descriptorBindingVariableDescriptorCount = true;
|
||||
descIndexingFeature.shaderSampledImageArrayNonUniformIndexing = true;
|
||||
descIndexingFeature.runtimeDescriptorArray = true;
|
||||
|
||||
// Prepare to create the device
|
||||
vk::DeviceCreateInfo deviceCreateInfo
|
||||
|
@ -249,6 +251,22 @@ namespace SHADE
|
|||
vkLogicalDevice.destroy(nullptr);
|
||||
}
|
||||
|
||||
SHVkLogicalDevice& SHVkLogicalDevice::operator=(SHVkLogicalDevice&& rhs) noexcept
|
||||
{
|
||||
if (this == &rhs)
|
||||
return *this;
|
||||
|
||||
vkLogicalDevice = std::move (rhs.vkLogicalDevice);
|
||||
queueFamilyIndices = std::move (rhs.queueFamilyIndices);
|
||||
vmaAllocator = rhs.vmaAllocator;
|
||||
nonDedicatedBestIndex = 0;
|
||||
parentPhysicalDeviceHdl = rhs.parentPhysicalDeviceHdl;
|
||||
|
||||
rhs.vkLogicalDevice = VK_NULL_HANDLE;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
|
|
|
@ -115,7 +115,7 @@ namespace SHADE
|
|||
~SHVkLogicalDevice (void) noexcept;
|
||||
|
||||
SHVkLogicalDevice& operator= (SHVkLogicalDevice const& rhs) noexcept = default;
|
||||
SHVkLogicalDevice& operator= (SHVkLogicalDevice&& rhs) noexcept = default;
|
||||
SHVkLogicalDevice& operator= (SHVkLogicalDevice&& rhs) noexcept;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* PUBLIC MEMBER VARIABLES */
|
||||
|
|
|
@ -98,6 +98,51 @@ namespace SHADE
|
|||
return *this;
|
||||
}
|
||||
|
||||
void SHVkFramebuffer::HandleResize(Handle<SHVkRenderpass> const& renderpassHdl, std::vector<Handle<SHVkImageView>> const& attachments, uint32_t inWidth, uint32_t inHeight) noexcept
|
||||
{
|
||||
width = inWidth;
|
||||
height = inHeight;
|
||||
|
||||
for (auto& attachment : attachments)
|
||||
{
|
||||
// Not sure if its an error to pass in diff dimension images.
|
||||
if (attachment->GetParentImage()->GetWidth() != (*attachments.begin())->GetParentImage()->GetWidth() || attachment->GetParentImage()->GetHeight() != (*attachments.begin())->GetParentImage()->GetHeight())
|
||||
{
|
||||
SHLOG_ERROR("Dimensions of images not same as each other. Cannot create framebuffer.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<vk::ImageView> vkAttachments(attachments.size());
|
||||
|
||||
uint32_t i = 0;
|
||||
for(auto const& attachment : attachments)
|
||||
{
|
||||
vkAttachments[i] = attachment->GetImageView();
|
||||
++i;
|
||||
}
|
||||
|
||||
vk::FramebufferCreateInfo createInfo
|
||||
{
|
||||
.renderPass = renderpassHdl->GetVkRenderpass(),
|
||||
.attachmentCount = static_cast<uint32_t>(vkAttachments.size()),
|
||||
.pAttachments = vkAttachments.data(),
|
||||
.width = width,
|
||||
.height = height,
|
||||
.layers = 1 // TODO: Find out why this is 1
|
||||
};
|
||||
|
||||
if (auto result = logicalDeviceHdl->GetVkLogicalDevice().createFramebuffer(&createInfo, nullptr, &vkFramebuffer); result != vk::Result::eSuccess)
|
||||
{
|
||||
SHVulkanDebugUtil::ReportVkError(result, "Failed to create framebuffer. ");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
SHVulkanDebugUtil::ReportVkSuccess("Successfully created framebuffer. ");
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
|
|
|
@ -37,6 +37,8 @@ namespace SHADE
|
|||
SHVkFramebuffer(SHVkFramebuffer&& rhs) noexcept;
|
||||
SHVkFramebuffer& operator=(SHVkFramebuffer&& rhs) noexcept;
|
||||
|
||||
void HandleResize (Handle<SHVkRenderpass> const& renderpassHdl, std::vector<Handle<SHVkImageView>> const& attachments, uint32_t inWidth, uint32_t inHeight) noexcept;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* SETTERS AND GETTERS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
|
|
@ -79,6 +79,41 @@ namespace SHADE
|
|||
vmaUnmapMemory(*vmaAllocator, stagingAlloc);
|
||||
}
|
||||
|
||||
void SHVkImage::CreateFramebufferImage(void) noexcept
|
||||
{
|
||||
vk::ImageCreateInfo imageCreateInfo{};
|
||||
imageCreateInfo.imageType = vk::ImageType::e2D;
|
||||
imageCreateInfo.extent.width = width;
|
||||
imageCreateInfo.extent.height = height;
|
||||
imageCreateInfo.extent.depth = depth;
|
||||
imageCreateInfo.mipLevels = mipLevelCount;
|
||||
imageCreateInfo.arrayLayers = layerCount;
|
||||
imageCreateInfo.format = imageFormat;
|
||||
imageCreateInfo.tiling = vk::ImageTiling::eOptimal;
|
||||
imageCreateInfo.initialLayout = vk::ImageLayout::eUndefined;
|
||||
imageCreateInfo.usage = usageFlags;
|
||||
imageCreateInfo.sharingMode = vk::SharingMode::eExclusive;
|
||||
imageCreateInfo.samples = vk::SampleCountFlagBits::e1;
|
||||
imageCreateInfo.flags = createFlags;
|
||||
|
||||
|
||||
// Prepare allocation parameters for call to create images later
|
||||
VmaAllocationCreateInfo allocCreateInfo{};
|
||||
allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
|
||||
allocCreateInfo.flags = {}; // TODO: Make sure the vk::MemoryPropertyFlags returned from vmaGetAllocationMemoryProperties has the device local bit set
|
||||
|
||||
VmaAllocationInfo allocInfo{};
|
||||
|
||||
VkImage tempImage;
|
||||
auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo & (), &allocCreateInfo, &tempImage, &alloc, &allocInfo);
|
||||
vkImage = tempImage;
|
||||
|
||||
if (result != VK_SUCCESS)
|
||||
SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan image. ");
|
||||
else
|
||||
SHVulkanDebugUtil::ReportVkSuccess("Successfully created image. ");
|
||||
}
|
||||
|
||||
SHVkImage::SHVkImage(
|
||||
VmaAllocator const* allocator,
|
||||
SHImageCreateParams const& imageDetails,
|
||||
|
@ -196,37 +231,7 @@ namespace SHADE
|
|||
, createFlags {create}
|
||||
, vmaAllocator {allocator}
|
||||
{
|
||||
vk::ImageCreateInfo imageCreateInfo{};
|
||||
imageCreateInfo.imageType = vk::ImageType::e2D;
|
||||
imageCreateInfo.extent.width = width;
|
||||
imageCreateInfo.extent.height = height;
|
||||
imageCreateInfo.extent.depth = depth;
|
||||
imageCreateInfo.mipLevels = mipLevelCount;
|
||||
imageCreateInfo.arrayLayers = layerCount;
|
||||
imageCreateInfo.format = imageFormat;
|
||||
imageCreateInfo.tiling = vk::ImageTiling::eOptimal;
|
||||
imageCreateInfo.initialLayout = vk::ImageLayout::eUndefined;
|
||||
imageCreateInfo.usage = usageFlags;
|
||||
imageCreateInfo.sharingMode = vk::SharingMode::eExclusive;
|
||||
imageCreateInfo.samples = vk::SampleCountFlagBits::e1;
|
||||
imageCreateInfo.flags = createFlags;
|
||||
|
||||
|
||||
// Prepare allocation parameters for call to create images later
|
||||
VmaAllocationCreateInfo allocCreateInfo{};
|
||||
allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
|
||||
allocCreateInfo.flags = {}; // TODO: Make sure the vk::MemoryPropertyFlags returned from vmaGetAllocationMemoryProperties has the device local bit set
|
||||
|
||||
VmaAllocationInfo allocInfo{};
|
||||
|
||||
VkImage tempImage;
|
||||
auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo & (), &allocCreateInfo, &tempImage, &alloc, &allocInfo);
|
||||
vkImage = tempImage;
|
||||
|
||||
if (result != VK_SUCCESS)
|
||||
SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan image. ");
|
||||
else
|
||||
SHVulkanDebugUtil::ReportVkSuccess("Successfully created image. ");
|
||||
CreateFramebufferImage();
|
||||
}
|
||||
|
||||
Handle<SHVkImageView> SHVkImage::CreateImageView(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) const noexcept
|
||||
|
@ -288,6 +293,16 @@ namespace SHADE
|
|||
barrier.subresourceRange.layerCount = layerCount;
|
||||
}
|
||||
|
||||
void SHVkImage::HandleResizeFramebufferImage(uint32_t newWidth, uint32_t newHeight) noexcept
|
||||
{
|
||||
vmaDestroyImage(*vmaAllocator, vkImage, alloc);
|
||||
|
||||
width = newWidth;
|
||||
height = newHeight;
|
||||
|
||||
CreateFramebufferImage();
|
||||
}
|
||||
|
||||
void SHVkImage::LinkWithExteriorImage(vk::Image inVkImage, vk::ImageType type, uint32_t inWidth, uint32_t inHeight, uint32_t inDepth, uint32_t layers, uint8_t levels, vk::Format format, vk::ImageUsageFlags flags) noexcept
|
||||
{
|
||||
vkImage = inVkImage;
|
||||
|
|
|
@ -108,7 +108,7 @@ namespace SHADE
|
|||
/* PRIVATE MEMBER FUNCTIONS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
void PrepStagingBuffer(const void* data, uint32_t srcSize) noexcept;
|
||||
|
||||
void CreateFramebufferImage (void) noexcept;
|
||||
|
||||
public:
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
@ -137,6 +137,7 @@ namespace SHADE
|
|||
Handle<SHVkImageView> CreateImageView (Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) const noexcept;
|
||||
void TransferToDeviceResource (Handle<SHVkCommandBuffer> cmdBufferHdl) noexcept;
|
||||
void PrepareImageTransitionInfo (vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept;
|
||||
void HandleResizeFramebufferImage(uint32_t newWidth, uint32_t newHeight) noexcept;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* GETTERS AND SETTERS */
|
||||
|
|
|
@ -6,27 +6,13 @@
|
|||
|
||||
namespace SHADE
|
||||
{
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
\brief
|
||||
Non-default ctor. Initializes image view with image that it is a view of.
|
||||
|
||||
\param parent
|
||||
Parent image the view is a view of.
|
||||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
SHVkImageView::SHVkImageView(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) noexcept
|
||||
: parentImage{ }
|
||||
, vkImageView{}
|
||||
, imageViewDetails{}
|
||||
, logicalDeviceHdl {inLogicalDeviceHdl}
|
||||
void SHVkImageView::Create(void) noexcept
|
||||
{
|
||||
auto parentImageCreateFlags = parent->GetImageeCreateFlags();
|
||||
auto parentImageCreateFlags = parentImage->GetImageeCreateFlags();
|
||||
|
||||
// 2D array image type means parent image must be 2D array compatible
|
||||
if (createParams.viewType == vk::ImageViewType::e2DArray)
|
||||
if (imageViewDetails.viewType == vk::ImageViewType::e2DArray)
|
||||
{
|
||||
if (!(parentImageCreateFlags & vk::ImageCreateFlagBits::e2DArrayCompatible))
|
||||
{
|
||||
|
@ -36,7 +22,7 @@ namespace SHADE
|
|||
}
|
||||
|
||||
// Check if its possible for the image view to have different format than parent image
|
||||
if (createParams.format != parent->GetImageFormat())
|
||||
if (imageViewDetails.format != parentImage->GetImageFormat())
|
||||
{
|
||||
if (!(parentImageCreateFlags & vk::ImageCreateFlagBits::eMutableFormat))
|
||||
{
|
||||
|
@ -49,9 +35,9 @@ namespace SHADE
|
|||
vk::ImageViewCreateInfo viewCreateInfo
|
||||
{
|
||||
.pNext = nullptr, // Can be used to override with a VkImageViewUsageCreateInfo to override usage. See Vulkan spec page 877 for more information
|
||||
.image = parent->GetVkImage(),
|
||||
.viewType = createParams.viewType,
|
||||
.format = createParams.format,
|
||||
.image = parentImage->GetVkImage(),
|
||||
.viewType = imageViewDetails.viewType,
|
||||
.format = imageViewDetails.format,
|
||||
.components
|
||||
{
|
||||
.r = vk::ComponentSwizzle::eR,
|
||||
|
@ -61,15 +47,15 @@ namespace SHADE
|
|||
},
|
||||
.subresourceRange
|
||||
{
|
||||
.aspectMask = createParams.imageAspectFlags,
|
||||
.baseMipLevel = createParams.baseMipLevel,
|
||||
.levelCount = createParams.mipLevelCount,
|
||||
.baseArrayLayer = createParams.baseArrayLayer,
|
||||
.layerCount = createParams.layerCount,
|
||||
.aspectMask = imageViewDetails.imageAspectFlags,
|
||||
.baseMipLevel = imageViewDetails.baseMipLevel,
|
||||
.levelCount = imageViewDetails.mipLevelCount,
|
||||
.baseArrayLayer = imageViewDetails.baseArrayLayer,
|
||||
.layerCount = imageViewDetails.layerCount,
|
||||
},
|
||||
};
|
||||
|
||||
if (auto result = inLogicalDeviceHdl->GetVkLogicalDevice().createImageView(&viewCreateInfo, nullptr, &vkImageView); result != vk::Result::eSuccess)
|
||||
if (auto result = logicalDeviceHdl->GetVkLogicalDevice().createImageView(&viewCreateInfo, nullptr, &vkImageView); result != vk::Result::eSuccess)
|
||||
{
|
||||
SHVulkanDebugUtil::ReportVkError(result, "Failed to create image view! ");
|
||||
return;
|
||||
|
@ -79,9 +65,26 @@ namespace SHADE
|
|||
SHVulkanDebugUtil::ReportVkSuccess("Successfully created image view. ");
|
||||
}
|
||||
|
||||
// After success, THEN assign variables
|
||||
parentImage = parent;
|
||||
imageViewDetails = createParams;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
\brief
|
||||
Non-default ctor. Initializes image view with image that it is a view of.
|
||||
|
||||
\param parent
|
||||
Parent image the view is a view of.
|
||||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
SHVkImageView::SHVkImageView(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) noexcept
|
||||
: parentImage{ parent }
|
||||
, vkImageView{}
|
||||
, imageViewDetails{createParams}
|
||||
, logicalDeviceHdl {inLogicalDeviceHdl}
|
||||
{
|
||||
Create();
|
||||
}
|
||||
|
||||
SHVkImageView::SHVkImageView(SHVkImageView&& rhs) noexcept
|
||||
|
@ -94,6 +97,17 @@ namespace SHADE
|
|||
}
|
||||
|
||||
|
||||
void SHVkImageView::ViewNewImage(Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) noexcept
|
||||
{
|
||||
imageViewDetails = createParams;
|
||||
parentImage = parent;
|
||||
|
||||
if (vkImageView)
|
||||
logicalDeviceHdl->GetVkLogicalDevice().destroyImageView(vkImageView, nullptr);
|
||||
|
||||
Create();
|
||||
}
|
||||
|
||||
Handle<SHVkImage> const& SHVkImageView::GetParentImage(void) const noexcept
|
||||
{
|
||||
return parentImage;
|
||||
|
|
|
@ -25,12 +25,17 @@ namespace SHADE
|
|||
//! Logical Device needed for creation and destruction
|
||||
Handle<SHVkLogicalDevice> logicalDeviceHdl;
|
||||
|
||||
//! Create new image view
|
||||
void Create (void) noexcept;
|
||||
|
||||
public:
|
||||
SHVkImageView(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) noexcept;
|
||||
~SHVkImageView(void) noexcept;
|
||||
SHVkImageView(SHVkImageView&& rhs) noexcept;
|
||||
SHVkImageView& operator=(SHVkImageView&& rhs) noexcept;
|
||||
|
||||
void ViewNewImage (Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) noexcept;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* GETTERS AND SETTERS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
|
|
@ -249,7 +249,7 @@ namespace SHADE
|
|||
if (!EMPTY_MAT_PROPS)
|
||||
{
|
||||
singleMatPropSize = SHADER_INFO->GetBytesRequired();
|
||||
singleMatPropAlignedSize = device->PadSSBOSize(singleMatPropSize);
|
||||
singleMatPropAlignedSize = device->PadSSBOSize(static_cast<uint32_t>(singleMatPropSize));
|
||||
matPropTotalBytes = numTotalElements * singleMatPropAlignedSize;
|
||||
if (matPropsDataSize < matPropTotalBytes)
|
||||
{
|
||||
|
@ -386,7 +386,7 @@ namespace SHADE
|
|||
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
|
||||
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA,
|
||||
bufferList,
|
||||
0, matPropsDataSize
|
||||
0, static_cast<uint32_t>(matPropsDataSize)
|
||||
);
|
||||
matPropsDescSet[frameIndex]->UpdateDescriptorSetBuffer
|
||||
(
|
||||
|
|
|
@ -69,7 +69,7 @@ namespace SHADE
|
|||
SHMatrix inverseViewMatrix;
|
||||
SHMatrix inverseProjMatrix;
|
||||
SHMatrix inverseVpMatrix;
|
||||
bool isDirty;
|
||||
bool isDirty = true;
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Helper Functions */
|
||||
|
|
|
@ -67,9 +67,17 @@ namespace SHADE
|
|||
// Register callback to notify render context upon a window resize
|
||||
window->RegisterWindowSizeCallback([&]([[maybe_unused]] uint32_t width, [[maybe_unused]] uint32_t height)
|
||||
{
|
||||
if (width == 0 || height == 0)
|
||||
return;
|
||||
|
||||
renderContext.SetIsResized(true);
|
||||
});
|
||||
|
||||
window->RegisterWindowCloseCallback([&](void)
|
||||
{
|
||||
renderContext.SetWindowIsDead(true);
|
||||
}
|
||||
);
|
||||
// Create graphics queue
|
||||
graphicsQueue = device->GetQueue(SH_Q_FAM::GRAPHICS, 0);
|
||||
transferQueue = device->GetQueue(SH_Q_FAM::TRANSFER, 0);
|
||||
|
@ -116,8 +124,8 @@ namespace SHADE
|
|||
screenCamera = resourceManager.Create<SHCamera>();
|
||||
screenCamera->SetLookAt(SHVec3(0.0f, 0.0f, -1.0f), SHVec3(0.0f, 0.0f, 1.0f), SHVec3(0.0f, 1.0f, 0.0f));
|
||||
screenCamera->SetOrthographic(static_cast<float>(windowDims.first), static_cast<float>(windowDims.second), 0.01f, 100.0f);
|
||||
|
||||
worldCamera = resourceManager.Create<SHCamera>();
|
||||
//worldCamera->SetLookAt(SHVec3(1.0f, 0.0f, -1.0f), SHVec3(0.0f, 0.0f, 2.0f), SHVec3(0.0f, 1.0f, 0.0f));
|
||||
worldCamera->SetLookAt(SHVec3(0.0f, 0.0f, 0.0f), SHVec3(0.0f, 0.0f, -2.0f), SHVec3(0.0f, 1.0f, 0.0f));
|
||||
worldCamera->SetPerspective(90.0f, static_cast<float>(windowDims.first), static_cast<float>(windowDims.second), 0.0f, 100.0f);
|
||||
|
||||
|
@ -125,7 +133,7 @@ namespace SHADE
|
|||
defaultViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast<float>(window->GetWindowSize().first), static_cast<float>(window->GetWindowSize().second), 0.0f, 1.0f));
|
||||
|
||||
// Get render graph from default viewport world renderer
|
||||
auto worldRenderGraph = resourceManager.Create<SHRenderGraph>();
|
||||
worldRenderGraph = resourceManager.Create<SHRenderGraph>();
|
||||
|
||||
std::vector<Handle<SHVkCommandPool>> renderContextCmdPools{swapchain->GetNumImages()};
|
||||
for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i)
|
||||
|
@ -210,6 +218,15 @@ namespace SHADE
|
|||
/***************************************************************************/
|
||||
void SHGraphicsSystem::Run(double) noexcept
|
||||
{
|
||||
if (window->IsMinimized() || renderContext.GetWindowIsDead())
|
||||
return;
|
||||
|
||||
if (renderContext.GetResized())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Frame data for the current frame
|
||||
auto const& frameData = renderContext.GetCurrentFrameData();
|
||||
uint32_t frameIndex = renderContext.GetCurrentFrame();
|
||||
|
@ -249,6 +266,10 @@ namespace SHADE
|
|||
// Begin recording the command buffer
|
||||
currentCmdBuffer->BeginRecording();
|
||||
|
||||
uint32_t w = static_cast<uint32_t>(viewports[vpIndex]->GetWidth());
|
||||
uint32_t h = static_cast<uint32_t>(viewports[vpIndex]->GetHeight());
|
||||
currentCmdBuffer->SetViewportScissor (static_cast<float>(w), static_cast<float>(h), w, h);
|
||||
|
||||
currentCmdBuffer->ForceSetPipelineLayout(SHGraphicsGlobalData::GetDummyPipelineLayout());
|
||||
|
||||
// Bind all the buffers required for meshes
|
||||
|
@ -304,13 +325,6 @@ namespace SHADE
|
|||
|
||||
void SHGraphicsSystem::Exit(void)
|
||||
{
|
||||
renderContext.Destroy();
|
||||
graphicsQueue.Free();
|
||||
swapchain.Free();
|
||||
surface.Free();
|
||||
device.Free();
|
||||
|
||||
SHVkInstance::Destroy();
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -328,6 +342,9 @@ namespace SHADE
|
|||
/***************************************************************************/
|
||||
void SHGraphicsSystem::BeginRender()
|
||||
{
|
||||
if (window->IsMinimized() || renderContext.GetWindowIsDead())
|
||||
return;
|
||||
|
||||
// Finalise all batches
|
||||
for (auto vp : viewports)
|
||||
for (auto renderer : vp->GetRenderers())
|
||||
|
@ -341,10 +358,7 @@ namespace SHADE
|
|||
{
|
||||
device->WaitIdle();
|
||||
|
||||
// Resize the swapchain
|
||||
swapchain->Resize(surface, windowDims.first, windowDims.second);
|
||||
|
||||
renderContext.HandleResize();
|
||||
HandleResize();
|
||||
}
|
||||
|
||||
const uint32_t CURR_FRAME_IDX = renderContext.GetCurrentFrame();
|
||||
|
@ -377,6 +391,16 @@ namespace SHADE
|
|||
/***************************************************************************/
|
||||
void SHGraphicsSystem::EndRender()
|
||||
{
|
||||
if (window->IsMinimized() || renderContext.GetWindowIsDead())
|
||||
return;
|
||||
|
||||
if (renderContext.GetResized())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const uint32_t CURR_FRAME_IDX = renderContext.GetCurrentFrame();
|
||||
auto& currFrameData = renderContext.GetCurrentFrameData();
|
||||
|
||||
|
@ -387,10 +411,8 @@ namespace SHADE
|
|||
// If swapchain is incompatible/outdated
|
||||
if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR)
|
||||
{
|
||||
auto windowDims = window->GetWindowSize();
|
||||
swapchain->Resize(surface, windowDims.first, windowDims.second);
|
||||
|
||||
renderContext.HandleResize();
|
||||
HandleResize();
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -509,25 +531,79 @@ namespace SHADE
|
|||
);
|
||||
}
|
||||
|
||||
void SHGraphicsSystem::HandleResize(void) noexcept
|
||||
{
|
||||
if (window->IsMinimized() || renderContext.GetWindowIsDead())
|
||||
return;
|
||||
|
||||
auto windowDims = window->GetWindowSize();
|
||||
|
||||
// Resize the swapchain
|
||||
swapchain->Resize(surface, windowDims.first, windowDims.second);
|
||||
|
||||
renderContext.HandleResize();
|
||||
|
||||
worldRenderGraph->HandleResize(windowDims.first, windowDims.second);
|
||||
|
||||
defaultViewport->SetWidth(static_cast<float>(windowDims.first));
|
||||
defaultViewport->SetHeight(static_cast<float>(windowDims.second));
|
||||
|
||||
worldCamera->SetPerspective(90.0f, static_cast<float>(windowDims.first), static_cast<float>(windowDims.second), 0.0f, 100.0f);
|
||||
}
|
||||
|
||||
void SHGraphicsSystem::AwaitGraphicsExecution()
|
||||
{
|
||||
device->WaitIdle();
|
||||
}
|
||||
|
||||
void SHGraphicsSystem::SetWindow(SHWindow* wind) noexcept
|
||||
{
|
||||
window = wind;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* System Routine Functions - BeginRoutine */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
SHGraphicsSystem::BeginRoutine::BeginRoutine()
|
||||
: SHSystemRoutine("Graphics System Frame Set Up", false)
|
||||
{}
|
||||
|
||||
void SHGraphicsSystem::BeginRoutine::Execute(double) noexcept
|
||||
{
|
||||
reinterpret_cast<SHGraphicsSystem*>(system)->BeginRender();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* System Routine Functions - RenderRoutine */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
SHGraphicsSystem::RenderRoutine::RenderRoutine()
|
||||
: SHSystemRoutine("Graphics System Render", false)
|
||||
{}
|
||||
|
||||
void SHGraphicsSystem::RenderRoutine::Execute(double dt) noexcept
|
||||
{
|
||||
reinterpret_cast<SHGraphicsSystem*>(system)->Run(dt);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* System Routine Functions - EndRoutine */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
SHGraphicsSystem::EndRoutine::EndRoutine()
|
||||
: SHSystemRoutine("Graphics System Frame Clean Up", false)
|
||||
{}
|
||||
|
||||
void SHGraphicsSystem::EndRoutine::Execute(double) noexcept
|
||||
{
|
||||
reinterpret_cast<SHGraphicsSystem*>(system)->EndRender();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* System Routine Functions - BatcherDispatcherRoutine */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
SHGraphicsSystem::BatcherDispatcherRoutine::BatcherDispatcherRoutine()
|
||||
: SHSystemRoutine("Graphics System Batcher Dispatcher", false)
|
||||
{}
|
||||
|
||||
void SHGraphicsSystem::BatcherDispatcherRoutine::Execute(double) noexcept
|
||||
{
|
||||
auto& renderables = SHComponentManager::GetDense<SHRenderable>();
|
||||
|
|
|
@ -69,21 +69,25 @@ namespace SHADE
|
|||
class SH_API BeginRoutine final : public SHSystemRoutine
|
||||
{
|
||||
public:
|
||||
BeginRoutine();
|
||||
virtual void Execute(double dt) noexcept override final;
|
||||
};
|
||||
class SH_API RenderRoutine final : public SHSystemRoutine
|
||||
{
|
||||
public:
|
||||
RenderRoutine();
|
||||
virtual void Execute(double dt) noexcept override final;
|
||||
};
|
||||
class SH_API EndRoutine final : public SHSystemRoutine
|
||||
{
|
||||
public:
|
||||
EndRoutine();
|
||||
virtual void Execute(double dt) noexcept override final;
|
||||
};
|
||||
class SH_API BatcherDispatcherRoutine final : public SHSystemRoutine
|
||||
{
|
||||
public:
|
||||
BatcherDispatcherRoutine();
|
||||
virtual void Execute(double dt) noexcept override final;
|
||||
};
|
||||
|
||||
|
@ -246,6 +250,9 @@ namespace SHADE
|
|||
/***************************************************************************/
|
||||
void BuildTextures();
|
||||
|
||||
void HandleResize(void) noexcept;
|
||||
void AwaitGraphicsExecution();
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Setters */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
@ -279,7 +286,6 @@ namespace SHADE
|
|||
Handle<SHVkQueue> transferQueue;
|
||||
Handle<SHVkDescriptorPool> descPool;
|
||||
Handle<SHVkCommandPool> graphicsCmdPool;
|
||||
Handle<SHVkCommandPool> transferCmdPool;
|
||||
Handle<SHVkCommandBuffer> transferCmdBuffer;
|
||||
Handle<SHVkCommandBuffer> graphicsTexCmdBuffer;
|
||||
SHRenderContext renderContext;
|
||||
|
@ -314,5 +320,7 @@ namespace SHADE
|
|||
|
||||
// Temp Materials
|
||||
Handle<SHMaterial> defaultMaterial;
|
||||
|
||||
Handle<SHRenderGraph> worldRenderGraph;
|
||||
};
|
||||
}
|
|
@ -63,7 +63,7 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------------*/
|
||||
Handle<SHVkPipeline> pipeline;
|
||||
std::unique_ptr<char> propMemory;
|
||||
Byte propMemorySize;
|
||||
Byte propMemorySize = 0;
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Helper Functions */
|
||||
|
|
|
@ -49,6 +49,14 @@ namespace SHADE
|
|||
cameraDescriptorSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA);
|
||||
}
|
||||
|
||||
SHRenderer::~SHRenderer(void)
|
||||
{
|
||||
//for (auto& cmdBuffer : commandBuffers)
|
||||
//{
|
||||
// cmdBuffer.Free();
|
||||
//}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Camera Registration */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
|
|
@ -65,6 +65,7 @@ namespace SHADE
|
|||
/* Constructor/Destructors */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
SHRenderer(Handle<SHVkLogicalDevice> logicalDevice, uint32_t numFrames, std::vector<Handle<SHVkCommandPool>>& cmdPools, Handle<SHVkDescriptorPool> descriptorPool, Handle<SHVkDescriptorSetLayout> cameraDescLayout, Handle<SHViewport> viewport, Handle<SHRenderGraph> renderGraph);
|
||||
~SHRenderer(void);
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Camera Registration */
|
||||
|
|
|
@ -73,4 +73,16 @@ namespace SHADE
|
|||
iter->Free();
|
||||
renderers.erase(iter);
|
||||
}
|
||||
|
||||
void SHViewport::SetWidth(float w) noexcept
|
||||
{
|
||||
viewport.width = w;
|
||||
}
|
||||
|
||||
void SHViewport::SetHeight(float h) noexcept
|
||||
{
|
||||
viewport.height = h;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -62,6 +62,12 @@ namespace SHADE
|
|||
Handle<SHRenderer> AddRenderer(ResourceManager& resourceManager, uint32_t numFrames, std::vector<Handle<SHVkCommandPool>>& cmdPools, Handle<SHVkDescriptorPool> descriptorPool, Handle<SHVkDescriptorSetLayout> cameraDescLayout, Handle<SHRenderGraph> renderGraph);
|
||||
void RemoveRenderer(Handle<SHRenderer> renderer);
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Setters */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
void SetWidth(float w) noexcept;
|
||||
void SetHeight (float h) noexcept;
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Getters */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
|
|
@ -196,12 +196,12 @@ namespace SHADE
|
|||
static SHMeshData meshData = Cube();
|
||||
return meshLibrary.AddMesh
|
||||
(
|
||||
meshData.VertexPositions.size(),
|
||||
static_cast<uint32_t>(meshData.VertexPositions.size()),
|
||||
meshData.VertexPositions.data(),
|
||||
meshData.VertexTexCoords.data(),
|
||||
meshData.VertexTangents.data(),
|
||||
meshData.VertexNormals.data(),
|
||||
meshData.Indices.size(),
|
||||
static_cast<uint32_t>(meshData.Indices.size()),
|
||||
meshData.Indices.data()
|
||||
);
|
||||
}
|
||||
|
@ -211,12 +211,12 @@ namespace SHADE
|
|||
static SHMeshData meshData = Cube();
|
||||
return gfxSystem.AddMesh
|
||||
(
|
||||
meshData.VertexPositions.size(),
|
||||
static_cast<uint32_t>(meshData.VertexPositions.size()),
|
||||
meshData.VertexPositions.data(),
|
||||
meshData.VertexTexCoords.data(),
|
||||
meshData.VertexTangents.data(),
|
||||
meshData.VertexNormals.data(),
|
||||
meshData.Indices.size(),
|
||||
static_cast<uint32_t>(meshData.Indices.size()),
|
||||
meshData.Indices.data()
|
||||
);
|
||||
}
|
||||
|
|
|
@ -168,6 +168,11 @@ namespace SHADE
|
|||
isResized = resized;
|
||||
}
|
||||
|
||||
void SHRenderContext::SetWindowIsDead(bool dead) noexcept
|
||||
{
|
||||
windowIsDead = dead;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
|
@ -197,6 +202,11 @@ namespace SHADE
|
|||
return currentFrame;
|
||||
}
|
||||
|
||||
bool SHRenderContext::GetResized(void) noexcept
|
||||
{
|
||||
return isResized;
|
||||
}
|
||||
|
||||
bool SHRenderContext::GetResizeAndReset(void) noexcept
|
||||
{
|
||||
bool b = isResized;
|
||||
|
@ -204,4 +214,9 @@ namespace SHADE
|
|||
return b;
|
||||
}
|
||||
|
||||
bool SHRenderContext::GetWindowIsDead(void) const noexcept
|
||||
{
|
||||
return windowIsDead;
|
||||
}
|
||||
|
||||
}
|
|
@ -36,6 +36,7 @@ namespace SHADE
|
|||
uint32_t currentFrame;
|
||||
|
||||
bool isResized{ false };
|
||||
bool windowIsDead {false};
|
||||
|
||||
public:
|
||||
SHRenderContext(void) noexcept;
|
||||
|
@ -51,12 +52,15 @@ namespace SHADE
|
|||
bool WaitForFence (void) noexcept;
|
||||
void ResetFence (void) noexcept;
|
||||
|
||||
void SetIsResized (bool resized) noexcept;
|
||||
void SetIsResized (bool resized) noexcept;
|
||||
void SetWindowIsDead (bool dead) noexcept;
|
||||
|
||||
SHPerFrameData& GetCurrentFrameData(void) noexcept;
|
||||
SHPerFrameData& GetFrameData (uint32_t index) noexcept;
|
||||
uint32_t GetCurrentFrame (void) const noexcept;
|
||||
bool GetResized (void) noexcept;
|
||||
bool GetResizeAndReset (void) noexcept;
|
||||
bool GetWindowIsDead (void) const noexcept;
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
@ -149,7 +149,7 @@ namespace SHADE
|
|||
{
|
||||
texOrder.emplace_back(job.TextureHandle);
|
||||
combinedImageSamplers.emplace_back(std::make_tuple(job.TextureHandle->ImageView, job.Sampler, vk::ImageLayout::eShaderReadOnlyOptimal));
|
||||
job.TextureHandle->TextureArrayIndex = texOrder.size() - 1;
|
||||
job.TextureHandle->TextureArrayIndex = static_cast<uint32_t>(texOrder.size()) - 1U;
|
||||
}
|
||||
addJobs.clear();
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace SHADE
|
|||
class SHVkDescriptorSetLayout;
|
||||
class SHVkDescriptorSetGroup;
|
||||
class SHVkSampler;
|
||||
class SHTextureAsset;
|
||||
struct SHTextureAsset;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
|
|
|
@ -46,7 +46,7 @@ namespace SHADE
|
|||
if (w == static_cast<uint32_t>(-1) && h == static_cast<uint32_t>(-1))
|
||||
{
|
||||
w = swapchainHdl->GetSwapchainImage(0)->GetWidth();
|
||||
w = swapchainHdl->GetSwapchainImage(0)->GetHeight();
|
||||
h = swapchainHdl->GetSwapchainImage(0)->GetHeight();
|
||||
format = swapchainHdl->GetSurfaceFormatKHR().format;
|
||||
}
|
||||
|
||||
|
@ -465,9 +465,6 @@ namespace SHADE
|
|||
// better way to manage these
|
||||
void SHRenderGraph::Execute(uint32_t frameIndex, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkDescriptorPool> descPool) noexcept
|
||||
{
|
||||
// TODO: DON'T HARDCODE THIS
|
||||
cmdBuffer->SetViewportScissor(1920.0f, 1080.0f, 1920, 1080);
|
||||
|
||||
for (auto& node : nodes)
|
||||
node->Execute(cmdBuffer, descPool, frameIndex);
|
||||
}
|
||||
|
@ -480,6 +477,18 @@ namespace SHADE
|
|||
}
|
||||
}
|
||||
|
||||
void SHRenderGraph::HandleResize(uint32_t newWidth, uint32_t newHeight) noexcept
|
||||
{
|
||||
// resize resources
|
||||
for (auto& [name, resource]: graphResources)
|
||||
resource->HandleResize(newWidth, newHeight);
|
||||
|
||||
for (auto& node : nodes)
|
||||
{
|
||||
node->HandleResize();
|
||||
}
|
||||
}
|
||||
|
||||
Handle<SHRenderGraphNode> SHRenderGraph::GetNode(std::string const& nodeName) const noexcept
|
||||
{
|
||||
if (nodeIndexing.contains(nodeName))
|
||||
|
|
|
@ -80,6 +80,7 @@ namespace SHADE
|
|||
void Generate (void) noexcept;
|
||||
void Execute (uint32_t frameIndex, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkDescriptorPool> descPool) noexcept;
|
||||
void FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
|
||||
void HandleResize (uint32_t newWidth, uint32_t newHeight) noexcept;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* SETTERS AND GETTERS */
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||
#include "Graphics/Images/SHVkImageView.h"
|
||||
#include "Graphics/Swapchain/SHVkSwapchain.h"
|
||||
#include "Graphics/Framebuffer/SHVkFramebuffer.h"
|
||||
#include "SHRenderGraphResource.h"
|
||||
#include "SHSubpass.h"
|
||||
|
||||
|
@ -56,6 +57,33 @@ namespace SHADE
|
|||
}
|
||||
}
|
||||
|
||||
void SHRenderGraphNode::HandleResize(void) noexcept
|
||||
{
|
||||
renderpass->HandleResize();
|
||||
|
||||
for (uint32_t i = 0; i < framebuffers.size(); ++i)
|
||||
{
|
||||
std::vector<Handle<SHVkImageView>> imageViews(attResources.size());
|
||||
uint32_t fbWidth = std::numeric_limits<uint32_t>::max();
|
||||
uint32_t fbHeight = std::numeric_limits<uint32_t>::max();
|
||||
|
||||
for (uint32_t j = 0; j < attResources.size(); ++j)
|
||||
{
|
||||
uint32_t imageViewIndex = (attResources[j]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT) ? i : 0;
|
||||
imageViews[j] = attResources[j]->imageViews[imageViewIndex];
|
||||
|
||||
// We want the minimum dimensions for the framebuffer because the image attachments referenced cannot have dimensions smaller than the framebuffer's
|
||||
if (fbWidth > attResources[j]->width)
|
||||
fbWidth = attResources[j]->width;
|
||||
if (fbHeight > attResources[j]->height)
|
||||
fbHeight = attResources[j]->height;
|
||||
}
|
||||
|
||||
|
||||
framebuffers[i]->HandleResize(renderpass, imageViews, fbWidth, fbHeight);
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
|
|
|
@ -81,6 +81,7 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------*/
|
||||
void CreateRenderpass(void) noexcept;
|
||||
void CreateFramebuffer(void) noexcept;
|
||||
void HandleResize (void) noexcept;
|
||||
|
||||
public:
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
|
|
@ -2,9 +2,11 @@
|
|||
#include "SHRenderGraphResource.h"
|
||||
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||
#include "Graphics/Swapchain/SHVkSwapchain.h"
|
||||
#include "Graphics/Images/SHVkImageView.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
|
@ -42,7 +44,9 @@ namespace SHADE
|
|||
*/
|
||||
/***************************************************************************/
|
||||
SHRenderGraphResource::SHRenderGraphResource(Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::string const& name, SH_ATT_DESC_TYPE type, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageCreateFlagBits createFlags) noexcept
|
||||
: resourceType{ type }
|
||||
: logicalDevice {logicalDevice}
|
||||
, swapchain{ swapchain }
|
||||
, resourceType{ type }
|
||||
, resourceFormat{ format }
|
||||
, images{}
|
||||
, imageViews{}
|
||||
|
@ -52,10 +56,10 @@ namespace SHADE
|
|||
, resourceName{ name }
|
||||
{
|
||||
// If the resource type is an arbitrary image and not swapchain image
|
||||
if (type != SH_ATT_DESC_TYPE::COLOR_PRESENT)
|
||||
if (resourceType != SH_ATT_DESC_TYPE::COLOR_PRESENT)
|
||||
{
|
||||
vk::ImageAspectFlags imageAspectFlags;
|
||||
vk::ImageUsageFlags usage = {};
|
||||
imageAspectFlags = vk::ImageAspectFlags{};
|
||||
usage = {};
|
||||
|
||||
// Check the resource type and set image usage flags and image aspect flags accordingly
|
||||
switch (resourceType)
|
||||
|
@ -142,6 +146,7 @@ namespace SHADE
|
|||
, width{ rhs.width }
|
||||
, height{ rhs.height }
|
||||
, mipLevels{ rhs.mipLevels }
|
||||
, imageAspectFlags{ rhs.imageAspectFlags }
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -172,6 +177,7 @@ namespace SHADE
|
|||
width = rhs.width;
|
||||
height = rhs.height;
|
||||
mipLevels = rhs.mipLevels;
|
||||
imageAspectFlags = rhs.imageAspectFlags;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
@ -189,4 +195,51 @@ namespace SHADE
|
|||
|
||||
}
|
||||
|
||||
void SHRenderGraphResource::HandleResize(uint32_t newWidth, uint32_t newHeight) noexcept
|
||||
{
|
||||
width = newWidth;
|
||||
height = newHeight;
|
||||
|
||||
if (resourceType != SH_ATT_DESC_TYPE::COLOR_PRESENT)
|
||||
{
|
||||
// prepare image view details
|
||||
SHImageViewDetails viewDetails
|
||||
{
|
||||
.viewType = vk::ImageViewType::e2D,
|
||||
.format = images[0]->GetImageFormat(),
|
||||
.imageAspectFlags = imageAspectFlags,
|
||||
.baseMipLevel = 0,
|
||||
.mipLevelCount = mipLevels,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
};
|
||||
|
||||
for (uint32_t i = 0; i < images.size(); ++i)
|
||||
{
|
||||
images[i]->HandleResizeFramebufferImage(width, height);
|
||||
imageViews[i]->ViewNewImage(images[i], viewDetails);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Prepare image view details
|
||||
SHImageViewDetails viewDetails
|
||||
{
|
||||
.viewType = vk::ImageViewType::e2D,
|
||||
.format = swapchain->GetSurfaceFormatKHR().format,
|
||||
.imageAspectFlags = vk::ImageAspectFlagBits::eColor,
|
||||
.baseMipLevel = 0,
|
||||
.mipLevelCount = 1,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
};
|
||||
|
||||
for (uint32_t i = 0; i < swapchain->GetNumImages(); ++i)
|
||||
{
|
||||
images[i] = swapchain->GetSwapchainImage(i);
|
||||
imageViews[i]->ViewNewImage(images[i], viewDetails);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -20,6 +20,12 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------*/
|
||||
/* PRIVATE MEMBER VARIABLES */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
// for creation/recreation
|
||||
Handle<SHVkLogicalDevice> logicalDevice;
|
||||
|
||||
// for creation/recreation
|
||||
Handle<SHVkSwapchain> swapchain;
|
||||
|
||||
//! Name of the resource
|
||||
std::string resourceName;
|
||||
|
||||
|
@ -47,6 +53,14 @@ namespace SHADE
|
|||
|
||||
//! Number of mipmap levels
|
||||
uint8_t mipLevels;
|
||||
|
||||
//! image aspect flags
|
||||
vk::ImageAspectFlags imageAspectFlags;
|
||||
|
||||
//! usage flags
|
||||
vk::ImageUsageFlags usage = {};
|
||||
|
||||
|
||||
public:
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* CTORS AND DTORS */
|
||||
|
@ -56,6 +70,8 @@ namespace SHADE
|
|||
SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept;
|
||||
~SHRenderGraphResource(void) noexcept;
|
||||
|
||||
void HandleResize (uint32_t newWidth, uint32_t newHeight) noexcept;
|
||||
|
||||
friend class SHRenderGraphNode;
|
||||
friend class SHRenderGraph;
|
||||
};
|
||||
|
|
|
@ -30,7 +30,10 @@ namespace SHADE
|
|||
SHVkRenderpass::SHVkRenderpass(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, std::span<vk::AttachmentDescription> const vkDescriptions, std::vector<SHVkSubpassParams> const& subpasses) noexcept
|
||||
: logicalDeviceHdl {inLogicalDeviceHdl}
|
||||
, numAttDescs {static_cast<uint32_t>(vkDescriptions.size())}
|
||||
, vkSubpassDescriptions{}
|
||||
, vkSubpassDeps{}
|
||||
, clearColors{}
|
||||
, vkAttachmentDescriptions{}
|
||||
{
|
||||
for (uint32_t i = 0; i < vkDescriptions.size(); ++i)
|
||||
{
|
||||
|
@ -42,7 +45,6 @@ namespace SHADE
|
|||
|
||||
|
||||
vk::RenderPassCreateInfo renderPassCreateInfo{};
|
||||
std::vector<vk::SubpassDependency> subpassDeps;
|
||||
|
||||
// For validating the depth ref
|
||||
auto isValidDepthRef = [&](vk::AttachmentReference const& depthRef) -> bool
|
||||
|
@ -50,13 +52,16 @@ namespace SHADE
|
|||
return !(depthRef.attachment == static_cast<uint32_t> (-1) && depthRef.layout == vk::ImageLayout::eUndefined);
|
||||
};
|
||||
|
||||
for (uint32_t i = 0; i < vkDescriptions.size(); ++i)
|
||||
vkAttachmentDescriptions[i] = vkDescriptions[i];
|
||||
|
||||
uint32_t subpassIndex = 0;
|
||||
if (!subpasses.empty())
|
||||
{
|
||||
for (auto& subpass : subpasses)
|
||||
{
|
||||
subpassDescriptions.emplace_back();
|
||||
auto& spDesc = subpassDescriptions.back();
|
||||
vkSubpassDescriptions.emplace_back();
|
||||
auto& spDesc = vkSubpassDescriptions.back();
|
||||
|
||||
spDesc.pColorAttachments = subpass.colorRefs.data();
|
||||
spDesc.colorAttachmentCount = static_cast<uint32_t>(subpass.colorRefs.size());
|
||||
|
@ -88,18 +93,18 @@ namespace SHADE
|
|||
};
|
||||
|
||||
// Push a new dependency
|
||||
subpassDeps.push_back(dependency);
|
||||
vkSubpassDeps.push_back(dependency);
|
||||
|
||||
++subpassIndex;
|
||||
}
|
||||
|
||||
// Renderpass create info for render pass creation
|
||||
renderPassCreateInfo.attachmentCount = static_cast<uint32_t>(vkDescriptions.size());
|
||||
renderPassCreateInfo.pAttachments = vkDescriptions.data();
|
||||
renderPassCreateInfo.subpassCount = static_cast<uint32_t>(subpassDescriptions.size());
|
||||
renderPassCreateInfo.pSubpasses = subpassDescriptions.data();
|
||||
renderPassCreateInfo.dependencyCount = static_cast<uint32_t>(subpassDeps.size());
|
||||
renderPassCreateInfo.pDependencies = subpassDeps.data();
|
||||
renderPassCreateInfo.attachmentCount = static_cast<uint32_t>(vkAttachmentDescriptions.size());
|
||||
renderPassCreateInfo.pAttachments = vkAttachmentDescriptions.data();
|
||||
renderPassCreateInfo.subpassCount = static_cast<uint32_t>(vkSubpassDescriptions.size());
|
||||
renderPassCreateInfo.pSubpasses = vkSubpassDescriptions.data();
|
||||
renderPassCreateInfo.dependencyCount = static_cast<uint32_t>(vkSubpassDeps.size());
|
||||
renderPassCreateInfo.pDependencies = vkSubpassDeps.data();
|
||||
|
||||
}
|
||||
// No subpasses passed in, create a default one.
|
||||
|
@ -172,6 +177,8 @@ namespace SHADE
|
|||
: logicalDeviceHdl{ inLogicalDeviceHdl }
|
||||
, numAttDescs{ static_cast<uint32_t>(vkDescriptions.size()) }
|
||||
, clearColors{}
|
||||
, vkSubpassDescriptions{ }
|
||||
, vkSubpassDeps{ }
|
||||
{
|
||||
for (uint32_t i = 0; i < vkDescriptions.size(); ++i)
|
||||
{
|
||||
|
@ -181,18 +188,24 @@ namespace SHADE
|
|||
clearColors[i].color = { {{0.0f, 0.0f, 0.0f, 1.0f}} };
|
||||
}
|
||||
|
||||
subpassDescriptions.resize (spDescs.size());
|
||||
for (uint32_t i = 0; i < subpassDescriptions.size(); ++i)
|
||||
{
|
||||
subpassDescriptions[i] = spDescs[i];
|
||||
}
|
||||
vkAttachmentDescriptions.resize(vkDescriptions.size());
|
||||
for (uint32_t i = 0; i < vkDescriptions.size(); ++i)
|
||||
vkAttachmentDescriptions[i] = vkDescriptions[i];
|
||||
|
||||
vkSubpassDescriptions.resize (spDescs.size());
|
||||
for (uint32_t i = 0; i < vkSubpassDescriptions.size(); ++i)
|
||||
vkSubpassDescriptions[i] = spDescs[i];
|
||||
|
||||
vkSubpassDeps.resize(spDeps.size());
|
||||
for (uint32_t i = 0; i < vkSubpassDeps.size(); ++i)
|
||||
vkSubpassDeps[i] = spDeps[i];
|
||||
|
||||
vk::RenderPassCreateInfo renderPassCreateInfo{};
|
||||
|
||||
renderPassCreateInfo.attachmentCount = static_cast<uint32_t>(vkDescriptions.size());
|
||||
renderPassCreateInfo.pAttachments = vkDescriptions.data();
|
||||
renderPassCreateInfo.subpassCount = static_cast<uint32_t>(subpassDescriptions.size());
|
||||
renderPassCreateInfo.pSubpasses = subpassDescriptions.data();
|
||||
renderPassCreateInfo.subpassCount = static_cast<uint32_t>(vkSubpassDescriptions.size());
|
||||
renderPassCreateInfo.pSubpasses = vkSubpassDescriptions.data();
|
||||
renderPassCreateInfo.dependencyCount = static_cast<uint32_t>(spDeps.size());
|
||||
renderPassCreateInfo.pDependencies = spDeps.data();
|
||||
|
||||
|
@ -210,8 +223,11 @@ namespace SHADE
|
|||
SHVkRenderpass::SHVkRenderpass(SHVkRenderpass&& rhs) noexcept
|
||||
: vkRenderpass {rhs.vkRenderpass}
|
||||
, logicalDeviceHdl {rhs.logicalDeviceHdl}
|
||||
, subpassDescriptions {std::move (rhs.subpassDescriptions)}
|
||||
, clearColors {std::move (rhs.clearColors)}
|
||||
, vkSubpassDescriptions{ std::move(rhs.vkSubpassDescriptions) }
|
||||
, vkSubpassDeps{ std::move(rhs.vkSubpassDeps) }
|
||||
, clearColors{ std::move(rhs.clearColors) }
|
||||
, vkAttachmentDescriptions{ std::move(rhs.vkAttachmentDescriptions) }
|
||||
, numAttDescs{rhs.numAttDescs}
|
||||
{
|
||||
rhs.vkRenderpass = VK_NULL_HANDLE;
|
||||
}
|
||||
|
@ -224,8 +240,11 @@ namespace SHADE
|
|||
|
||||
vkRenderpass = rhs.vkRenderpass;
|
||||
logicalDeviceHdl = rhs.logicalDeviceHdl;
|
||||
subpassDescriptions = std::move(rhs.subpassDescriptions);
|
||||
vkSubpassDescriptions = std::move(rhs.vkSubpassDescriptions);
|
||||
vkSubpassDeps = std::move(rhs.vkSubpassDeps);
|
||||
clearColors = std::move(rhs.clearColors);
|
||||
vkAttachmentDescriptions = std::move(rhs.vkAttachmentDescriptions);
|
||||
numAttDescs = std::move(rhs.numAttDescs);
|
||||
|
||||
rhs.vkRenderpass = VK_NULL_HANDLE;
|
||||
|
||||
|
@ -238,6 +257,31 @@ namespace SHADE
|
|||
}
|
||||
|
||||
|
||||
void SHVkRenderpass::HandleResize(void) noexcept
|
||||
{
|
||||
logicalDeviceHdl->GetVkLogicalDevice().destroyRenderPass(vkRenderpass, nullptr);
|
||||
|
||||
vk::RenderPassCreateInfo renderPassCreateInfo{};
|
||||
|
||||
renderPassCreateInfo.attachmentCount = static_cast<uint32_t>(vkAttachmentDescriptions.size());
|
||||
renderPassCreateInfo.pAttachments = vkAttachmentDescriptions.data();
|
||||
renderPassCreateInfo.subpassCount = static_cast<uint32_t>(vkSubpassDescriptions.size());
|
||||
renderPassCreateInfo.pSubpasses = vkSubpassDescriptions.data();
|
||||
renderPassCreateInfo.dependencyCount = static_cast<uint32_t>(vkSubpassDeps.size());
|
||||
renderPassCreateInfo.pDependencies = vkSubpassDeps.data();
|
||||
|
||||
|
||||
if (auto result = logicalDeviceHdl->GetVkLogicalDevice().createRenderPass(&renderPassCreateInfo, nullptr, &vkRenderpass); result != vk::Result::eSuccess)
|
||||
{
|
||||
SHVulkanDebugUtil::ReportVkError(result, "Failed to create Renderpass. ");
|
||||
}
|
||||
else
|
||||
{
|
||||
SHVulkanDebugUtil::ReportVkSuccess("Successfully created Renderpass. ");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
vk::RenderPass SHVkRenderpass::GetVkRenderpass(void) const noexcept
|
||||
{
|
||||
return vkRenderpass;
|
||||
|
|
|
@ -29,7 +29,13 @@ namespace SHADE
|
|||
Handle<SHVkLogicalDevice> logicalDeviceHdl;
|
||||
|
||||
//! Container of subpass information used to construct subpasses
|
||||
std::vector<vk::SubpassDescription> subpassDescriptions;
|
||||
std::vector<vk::SubpassDescription> vkSubpassDescriptions;
|
||||
|
||||
//! Container of subpass dependencies used to create renderpass
|
||||
std::vector<vk::SubpassDependency> vkSubpassDeps;
|
||||
|
||||
//! Attachment descriptions
|
||||
std::vector<vk::AttachmentDescription> vkAttachmentDescriptions;
|
||||
|
||||
//! Clear colors for the color and depth
|
||||
std::array<vk::ClearValue, NUM_CLEAR_COLORS> clearColors;
|
||||
|
@ -49,6 +55,8 @@ namespace SHADE
|
|||
SHVkRenderpass(SHVkRenderpass&& rhs) noexcept;
|
||||
SHVkRenderpass& operator=(SHVkRenderpass&& rhs) noexcept;
|
||||
|
||||
void HandleResize (void) noexcept;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* PUBLIC MEMBER FUNCTIONS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
|
|
@ -272,6 +272,17 @@ namespace SHADE
|
|||
windowResizeCallbacks.erase(callbackid);
|
||||
}
|
||||
|
||||
SHWindow::CALLBACKID SHWindow::RegisterWindowCloseCallback(WindowCloseCallbackFn windowCloseCallback)
|
||||
{
|
||||
windowCloseCallbacks.try_emplace(windowResizeCallbackCount, windowCloseCallback);
|
||||
return windowCloseCallbackCount++;
|
||||
}
|
||||
|
||||
void SHWindow::UnregisterWindowCloseCallback(CALLBACKID const& callbackid)
|
||||
{
|
||||
windowCloseCallbacks.erase(callbackid);
|
||||
}
|
||||
|
||||
LRESULT SHWindow::WndProcStatic(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
auto window = windowMap.GetWindow(hwnd);
|
||||
|
@ -307,6 +318,8 @@ namespace SHADE
|
|||
case WM_CREATE:
|
||||
OnCreate(hwnd, reinterpret_cast<LPCREATESTRUCT>(wparam));
|
||||
break;
|
||||
case WM_CLOSE:
|
||||
|
||||
case WM_DESTROY:
|
||||
OnDestroy();
|
||||
return 0;
|
||||
|
@ -362,8 +375,17 @@ namespace SHADE
|
|||
|
||||
}
|
||||
|
||||
void SHADE::SHWindow::OnClose()
|
||||
{
|
||||
for (const auto& callbackFn : windowCloseCallbacks | std::views::values)
|
||||
{
|
||||
callbackFn();
|
||||
}
|
||||
}
|
||||
|
||||
void SHWindow::OnDestroy()
|
||||
{
|
||||
OnClose();
|
||||
this->Destroy();
|
||||
}
|
||||
|
||||
|
@ -375,6 +397,14 @@ namespace SHADE
|
|||
{
|
||||
wndData.width = static_cast<unsigned>(size.cx);
|
||||
wndData.height = static_cast<unsigned>(size.cy);
|
||||
|
||||
if (type == SIZE_MINIMIZED)
|
||||
{
|
||||
wndData.isMinimised = true;
|
||||
}
|
||||
else
|
||||
wndData.isMinimised = false;
|
||||
|
||||
for (auto const& entry : windowResizeCallbacks)
|
||||
{
|
||||
entry.second(static_cast<uint32_t>(wndData.width), static_cast<uint32_t>(wndData.height));
|
||||
|
|
|
@ -61,6 +61,8 @@ namespace SHADE
|
|||
|
||||
bool modal = false;
|
||||
|
||||
bool isMinimised = false;
|
||||
|
||||
std::wstring title = L"SHADE ENGINE";
|
||||
|
||||
std::wstring name = L"SHADEEngineApp";
|
||||
|
@ -73,6 +75,7 @@ namespace SHADE
|
|||
public:
|
||||
using SHVec2 = std::pair<uint32_t, uint32_t>;
|
||||
typedef std::function<void(uint32_t width, uint32_t height)> WindowResizeCallbackFn;
|
||||
typedef std::function<void(void)> WindowCloseCallbackFn;
|
||||
typedef uint16_t CALLBACKID;
|
||||
SHWindow();
|
||||
|
||||
|
@ -123,6 +126,9 @@ namespace SHADE
|
|||
|
||||
CALLBACKID RegisterWindowSizeCallback(WindowResizeCallbackFn);
|
||||
void UnregisterWindowSizeCallback(CALLBACKID const& callbackid);
|
||||
CALLBACKID RegisterWindowCloseCallback(WindowCloseCallbackFn);
|
||||
void UnregisterWindowCloseCallback(CALLBACKID const& callbackid);
|
||||
bool IsMinimized() const { return wndData.isMinimised; }
|
||||
|
||||
protected:
|
||||
static LRESULT CALLBACK WndProcStatic(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
||||
|
@ -154,10 +160,13 @@ namespace SHADE
|
|||
HFONT font;
|
||||
|
||||
std::unordered_map<CALLBACKID, WindowResizeCallbackFn> windowResizeCallbacks;
|
||||
std::unordered_map<CALLBACKID, WindowCloseCallbackFn> windowCloseCallbacks;
|
||||
CALLBACKID windowResizeCallbackCount{};
|
||||
CALLBACKID windowCloseCallbackCount{};
|
||||
//TODO: Shift to events abstraction
|
||||
|
||||
void OnCreate(HWND hwnd, LPCREATESTRUCT create_struct);
|
||||
void OnClose();
|
||||
void OnDestroy();
|
||||
//void OnFileDrop(HDROP drop);
|
||||
void OnSize(UINT msg, UINT type, SIZE size);
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace SHADE
|
|||
/* Constructors & Destructor Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
SHBoundingBox::SHBoundingBox(const SHVec3& c, SHVec3& hE) noexcept
|
||||
SHBoundingBox::SHBoundingBox(const SHVec3& c, const SHVec3& hE) noexcept
|
||||
: SHShape {}
|
||||
, center { c }
|
||||
, halfExtents { hE }
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <DirectXCollision.h>
|
||||
|
||||
// Project Headers
|
||||
#include "SHShape.h"
|
||||
#include "SH_API.h"
|
||||
|
@ -20,6 +22,7 @@ namespace SHADE
|
|||
/* Type Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
// TODO(Diren): Use DirectX BoundingBox instead of custom
|
||||
class SH_API SHBoundingBox : public SHShape
|
||||
{
|
||||
public:
|
||||
|
@ -27,15 +30,15 @@ namespace SHADE
|
|||
/* Constructors & Destructor */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
SHBoundingBox (const SHVec3& center, SHVec3& halfExtents) noexcept;
|
||||
SHBoundingBox (const SHVec3* vertices, size_t numVertices) noexcept;
|
||||
SHBoundingBox (const SHBoundingBox* boxes, size_t numBoxes) noexcept;
|
||||
SHBoundingBox (const SHVec3& center, const SHVec3& halfExtents) noexcept;
|
||||
SHBoundingBox (const SHVec3* vertices, size_t numVertices) noexcept;
|
||||
SHBoundingBox (const SHBoundingBox* boxes, size_t numBoxes) noexcept;
|
||||
|
||||
SHBoundingBox (const SHBoundingBox& rhs) noexcept;
|
||||
SHBoundingBox (SHBoundingBox&& rhs) noexcept;
|
||||
SHBoundingBox (const SHBoundingBox& rhs) noexcept;
|
||||
SHBoundingBox (SHBoundingBox&& rhs) noexcept;
|
||||
|
||||
SHBoundingBox& operator= (const SHBoundingBox& rhs) noexcept;
|
||||
SHBoundingBox& operator= (SHBoundingBox&& rhs) noexcept;
|
||||
SHBoundingBox& operator= (const SHBoundingBox& rhs) noexcept;
|
||||
SHBoundingBox& operator= (SHBoundingBox&& rhs) noexcept;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Getter Functions */
|
||||
|
|
|
@ -23,4 +23,14 @@ namespace SHADE
|
|||
: type { Type::NONE }
|
||||
{}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Getter Function Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
SHShape::Type SHShape::GetType() const
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
} // namespace SHADE
|
|
@ -30,7 +30,9 @@ namespace SHADE
|
|||
enum class Type
|
||||
{
|
||||
BOUNDING_BOX
|
||||
, RAY
|
||||
, SPHERE
|
||||
, CAPSULE
|
||||
, CONVEX_HULL
|
||||
, TRIANGLE
|
||||
|
||||
, COUNT
|
||||
|
|
|
@ -103,6 +103,9 @@ namespace SHADE
|
|||
template <IsArithmetic T>
|
||||
T SHMath::GenerateRandomNumber(T lowerBound, T upperBound)
|
||||
{
|
||||
if (lowerBound > upperBound)
|
||||
std::swap(lowerBound, upperBound);
|
||||
|
||||
if constexpr (IsIntegral<T>)
|
||||
{
|
||||
std::uniform_int_distribution<T> distribution(lowerBound, upperBound);
|
||||
|
@ -120,7 +123,7 @@ namespace SHADE
|
|||
bool SHMath::CompareFloat(T lhs, T rhs, T absTolerance, T relTolerance)
|
||||
{
|
||||
const T RTOL = relTolerance * Max(std::fabs(lhs), std::fabs(rhs));
|
||||
return std::fabs(lhs - rhs) <= MAX(absTolerance, RTOL);
|
||||
return std::fabs(lhs - rhs) <= Max(absTolerance, RTOL);
|
||||
}
|
||||
|
||||
} // namespace SHADE
|
|
@ -15,6 +15,7 @@
|
|||
// Project Headers
|
||||
#include "Vector/SHVec3.h"
|
||||
#include "SHMatrix.h"
|
||||
#include "SHMathHelpers.h"
|
||||
#include "Tools/SHLogger.h"
|
||||
|
||||
using namespace DirectX;
|
||||
|
@ -249,9 +250,30 @@ namespace SHADE
|
|||
|
||||
SHVec3 SHQuaternion::ToEuler() const noexcept
|
||||
{
|
||||
// TODO (Diren)
|
||||
const float xx = x * x;
|
||||
const float yy = y * y;
|
||||
const float zz = z * z;
|
||||
|
||||
return SHVec3::Zero;
|
||||
const float m31 = 2.f * x * z + 2.f * y * w;
|
||||
const float m32 = 2.f * y * z - 2.f * x * w;
|
||||
const float m33 = 1.f - 2.f * xx - 2.f * yy;
|
||||
|
||||
const float cy = sqrtf(m33 * m33 + m31 * m31);
|
||||
const float cx = atan2f(-m32, cy);
|
||||
if (cy > 16.0f * SHMath::EPSILON)
|
||||
{
|
||||
const float m12 = 2.f * x * y + 2.f * z * w;
|
||||
const float m22 = 1.f - 2.f * xx - 2.f * zz;
|
||||
|
||||
return SHVec3(cx, atan2f(m31, m33), atan2f(m12, m22));
|
||||
}
|
||||
else
|
||||
{
|
||||
const float m11 = 1.f - 2.f * yy - 2.f * zz;
|
||||
const float m21 = 2.f * x * y - 2.f * z * w;
|
||||
|
||||
return SHVec3(cx, 0.f, atan2f(-m21, m11));
|
||||
}
|
||||
}
|
||||
|
||||
std::string SHQuaternion::ToString() const noexcept
|
||||
|
|
|
@ -24,43 +24,6 @@ namespace SHADE
|
|||
, dirty { true }
|
||||
{}
|
||||
|
||||
SHTransformComponent::SHTransformComponent(const SHTransformComponent& rhs) noexcept
|
||||
: SHComponent {}
|
||||
, dirty { true }
|
||||
, local { rhs.local }
|
||||
, world { rhs.world }
|
||||
{}
|
||||
|
||||
SHTransformComponent::SHTransformComponent(SHTransformComponent&& rhs) noexcept
|
||||
: SHComponent {}
|
||||
, dirty { true }
|
||||
, local { std::move(rhs.local) }
|
||||
, world { std::move(rhs.world) }
|
||||
{}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Operator Overload Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
SHTransformComponent& SHTransformComponent::operator=(const SHTransformComponent& rhs) noexcept
|
||||
{
|
||||
dirty = true;
|
||||
local = rhs.local;
|
||||
world = rhs.world;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
SHTransformComponent& SHTransformComponent::operator=(SHTransformComponent&& rhs) noexcept
|
||||
{
|
||||
dirty = true;
|
||||
local = std::move(rhs.local);
|
||||
world = std::move(rhs.world);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Getter Function Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -189,7 +152,7 @@ RTTR_REGISTRATION
|
|||
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);
|
||||
.property("Translate" , &SHTransformComponent::GetLocalPosition , &SHTransformComponent::SetLocalPosition )
|
||||
.property("Rotate" , &SHTransformComponent::GetLocalRotation , select_overload<void(SHVec3 const&)>(&SHTransformComponent::SetLocalRotation) )
|
||||
.property("Scale" , &SHTransformComponent::GetLocalScale , &SHTransformComponent::SetLocalScale );
|
||||
}
|
|
@ -13,6 +13,7 @@
|
|||
#include <queue>
|
||||
|
||||
#include <rttr/registration>
|
||||
|
||||
// Project Headers
|
||||
#include "SH_API.h"
|
||||
#include "ECS_Base/Components/SHComponent.h"
|
||||
|
@ -41,15 +42,15 @@ namespace SHADE
|
|||
~SHTransformComponent () override = default;
|
||||
|
||||
SHTransformComponent () noexcept;
|
||||
SHTransformComponent (const SHTransformComponent& rhs) noexcept;
|
||||
SHTransformComponent (SHTransformComponent&& rhs) noexcept;
|
||||
SHTransformComponent (const SHTransformComponent& rhs) noexcept = default;
|
||||
SHTransformComponent (SHTransformComponent&& rhs) noexcept = default;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Operator Overloads */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
SHTransformComponent& operator=(const SHTransformComponent& rhs) noexcept;
|
||||
SHTransformComponent& operator=(SHTransformComponent&& rhs) noexcept;
|
||||
SHTransformComponent& operator=(const SHTransformComponent& rhs) noexcept = default;
|
||||
SHTransformComponent& operator=(SHTransformComponent&& rhs) noexcept = default;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Getter Functions */
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
/****************************************************************************************
|
||||
* \file SHColliderComponent.cpp
|
||||
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||
* \brief Implementation for a Collider Component.
|
||||
*
|
||||
* \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.
|
||||
****************************************************************************************/
|
||||
|
||||
#include <SHpch.h>
|
||||
|
||||
// Primary Header
|
||||
#include "SHColliderComponent.h"
|
||||
|
||||
// Project Headers
|
||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
#include "Physics/SHPhysicsSystem.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Constructors & Destructor Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
SHColliderComponent::SHColliderComponent() noexcept
|
||||
: system { nullptr }
|
||||
{}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Getter Function Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
const SHVec3& SHColliderComponent::GetPosition() const noexcept
|
||||
{
|
||||
return position;
|
||||
}
|
||||
|
||||
const SHQuaternion& SHColliderComponent::GetOrientation() const noexcept
|
||||
{
|
||||
return orientation;
|
||||
}
|
||||
|
||||
SHVec3 SHColliderComponent::GetRotation() const noexcept
|
||||
{
|
||||
return orientation.ToEuler();
|
||||
}
|
||||
|
||||
const SHColliderComponent::Colliders& SHColliderComponent::GetColliders() const noexcept
|
||||
{
|
||||
return colliders;
|
||||
}
|
||||
|
||||
SHCollider& SHColliderComponent::GetCollider(int index)
|
||||
{
|
||||
if (index < 0 || static_cast<size_t>(index) >= colliders.size())
|
||||
throw std::invalid_argument("Out-of-range access!");
|
||||
|
||||
return colliders[index].first;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Public Function Member Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
void SHColliderComponent::OnCreate()
|
||||
{
|
||||
system = SHSystemManager::GetSystem<SHPhysicsSystem>();
|
||||
if (!system)
|
||||
{
|
||||
SHLOG_ERROR("Physics system does not exist, Collider Component not added!")
|
||||
return;
|
||||
}
|
||||
|
||||
system->AddCollider(GetEID());
|
||||
}
|
||||
|
||||
void SHColliderComponent::OnDestroy()
|
||||
{
|
||||
if (!system)
|
||||
{
|
||||
SHLOG_ERROR("Physics system does not exist, unable to remove Collider component!")
|
||||
return;
|
||||
}
|
||||
|
||||
system->RemoveCollider(GetEID());
|
||||
}
|
||||
|
||||
SHBoundingBox* SHColliderComponent::AddBoundingBox() noexcept
|
||||
{
|
||||
const auto TYPE = SHCollider::Type::BOX;
|
||||
|
||||
const auto BOX_PAIR = std::make_pair(SHCollider{TYPE}, true);
|
||||
auto& collider = colliders.emplace_back(BOX_PAIR).first;
|
||||
|
||||
if (!system)
|
||||
{
|
||||
SHLOG_ERROR("Physics system does not exist, unable to add Box Collider!")
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Notify Physics System
|
||||
system->AddCollisionShape(GetEID(), collider.GetShape());
|
||||
|
||||
return reinterpret_cast<SHBoundingBox*>(collider.GetShape());
|
||||
}
|
||||
|
||||
//void SHColliderComponent::AddSphere() noexcept
|
||||
//{
|
||||
// const auto TYPE = SHCollider::Type::SPHERE;
|
||||
|
||||
// if (!system)
|
||||
// {
|
||||
// SHLOG_ERROR("Physics system does not exist, unable to add Sphere Collider!")
|
||||
// return;
|
||||
// }
|
||||
|
||||
// // Notify Physics System
|
||||
//}
|
||||
|
||||
void SHColliderComponent::RemoveCollider(int index)
|
||||
{
|
||||
if (index < 0 || static_cast<size_t>(index) >= colliders.size())
|
||||
throw std::invalid_argument("Out-of-range access!");
|
||||
|
||||
int idx = 0;
|
||||
auto it = colliders.begin();
|
||||
for (; it != colliders.end(); ++it)
|
||||
{
|
||||
if (idx == index)
|
||||
break;
|
||||
|
||||
++idx;
|
||||
}
|
||||
|
||||
it = colliders.erase(it);
|
||||
|
||||
// Notify Physics System
|
||||
if (!system)
|
||||
{
|
||||
SHLOG_ERROR("Physics system does not exist, unable to remove Collider!")
|
||||
return;
|
||||
}
|
||||
|
||||
system->RemoveCollisionShape(GetEID(), index);
|
||||
}
|
||||
|
||||
} // namespace SHADE
|
|
@ -0,0 +1,96 @@
|
|||
/****************************************************************************************
|
||||
* \file SHColliderComponent.h
|
||||
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||
* \brief Interface for a Collider Component.
|
||||
*
|
||||
* \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.
|
||||
****************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <rttr/registration>
|
||||
|
||||
// Project Headers
|
||||
#include "ECS_Base/Components/SHComponent.h"
|
||||
#include "Physics/SHCollider.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
class SH_API SHColliderComponent : public SHComponent
|
||||
{
|
||||
private:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Friends */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
friend class SHPhysicsSystem;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
using ColliderDirtyPair = std::pair<SHCollider, bool>;
|
||||
using Colliders = std::vector<ColliderDirtyPair>;
|
||||
|
||||
public:
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constructors & Destructor */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
SHColliderComponent () noexcept;
|
||||
SHColliderComponent (const SHColliderComponent& rhs) noexcept = default;
|
||||
SHColliderComponent (SHColliderComponent&& rhs) noexcept = default;
|
||||
~SHColliderComponent () override = default;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Operator Overloads */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
SHColliderComponent& operator=(const SHColliderComponent& rhs) noexcept = default;
|
||||
SHColliderComponent& operator=(SHColliderComponent&& rhs) noexcept = default;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Getter Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
[[nodiscard]] bool HasChanged () const noexcept;
|
||||
|
||||
[[nodiscard]] const SHVec3& GetPosition () const noexcept;
|
||||
[[nodiscard]] const SHQuaternion& GetOrientation () const noexcept;
|
||||
[[nodiscard]] SHVec3 GetRotation () const noexcept;
|
||||
|
||||
[[nodiscard]] const Colliders& GetColliders () const noexcept;
|
||||
[[nodiscard]] SHCollider& GetCollider (int index);
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Function Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
void OnCreate () override;
|
||||
void OnDestroy () override;
|
||||
|
||||
SHBoundingBox* AddBoundingBox () noexcept;
|
||||
|
||||
void RemoveCollider (int index);
|
||||
|
||||
private:
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
SHPhysicsSystem* system;
|
||||
|
||||
SHVec3 position;
|
||||
SHQuaternion orientation;
|
||||
Colliders colliders;
|
||||
|
||||
};
|
||||
} // namespace SHADE
|
|
@ -0,0 +1,413 @@
|
|||
/****************************************************************************************
|
||||
* \file SHRigidBodyComponent.cpp
|
||||
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||
* \brief Implementation for a Rigidbody Component.
|
||||
*
|
||||
* \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.
|
||||
****************************************************************************************/
|
||||
|
||||
#include <SHpch.h>
|
||||
|
||||
// Primary Header
|
||||
#include "SHRigidBodyComponent.h"
|
||||
|
||||
// Project Headers
|
||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
#include "Physics/SHPhysicsSystem.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Constructors & Destructor Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
SHRigidBodyComponent::SHRigidBodyComponent() noexcept
|
||||
: type { Type::DYNAMIC }
|
||||
, flags { 0 }
|
||||
, dirtyFlags { 0 }
|
||||
, interpolate { true }
|
||||
, system { nullptr }
|
||||
, mass { 1.0f }
|
||||
, drag { 0.01f }
|
||||
, angularDrag { 0.01f }
|
||||
|
||||
{
|
||||
// Set default flags: Gravity & Sleeping enabled
|
||||
flags |= 1U << 0;
|
||||
flags |= 1U << 1;
|
||||
|
||||
// Set all dirty flags to true
|
||||
dirtyFlags = 1023;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Getter Function Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
bool SHRigidBodyComponent::IsGravityEnabled() const noexcept
|
||||
{
|
||||
return flags & (1U << 0);
|
||||
}
|
||||
|
||||
bool SHRigidBodyComponent::IsAllowedToSleep() const noexcept
|
||||
{
|
||||
return flags & (1U << 1);
|
||||
}
|
||||
|
||||
bool SHRigidBodyComponent::IsInterpolating() const noexcept
|
||||
{
|
||||
return interpolate;
|
||||
}
|
||||
|
||||
SHRigidBodyComponent::Type SHRigidBodyComponent::GetType() const noexcept
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
float SHRigidBodyComponent::GetMass() const noexcept
|
||||
{
|
||||
return mass;
|
||||
}
|
||||
|
||||
float SHRigidBodyComponent::GetDrag() const noexcept
|
||||
{
|
||||
return drag;
|
||||
}
|
||||
|
||||
float SHRigidBodyComponent::GetAngularDrag() const noexcept
|
||||
{
|
||||
return angularDrag;
|
||||
}
|
||||
|
||||
bool SHRigidBodyComponent::GetFreezePositionX() const noexcept
|
||||
{
|
||||
return flags & (1U << 2);
|
||||
}
|
||||
|
||||
bool SHRigidBodyComponent::GetFreezePositionY() const noexcept
|
||||
{
|
||||
return flags & (1U << 3);
|
||||
}
|
||||
|
||||
bool SHRigidBodyComponent::GetFreezePositionZ() const noexcept
|
||||
{
|
||||
return flags & (1U << 4);
|
||||
}
|
||||
|
||||
bool SHRigidBodyComponent::GetFreezeRotationX() const noexcept
|
||||
{
|
||||
return flags & (1U << 5);
|
||||
}
|
||||
|
||||
bool SHRigidBodyComponent::GetFreezeRotationY() const noexcept
|
||||
{
|
||||
return flags & (1U << 6);
|
||||
}
|
||||
|
||||
bool SHRigidBodyComponent::GetFreezeRotationZ() const noexcept
|
||||
{
|
||||
return flags & (1U << 7);
|
||||
}
|
||||
|
||||
const SHVec3& SHRigidBodyComponent::GetForce() const noexcept
|
||||
{
|
||||
return force;
|
||||
}
|
||||
|
||||
const SHVec3& SHRigidBodyComponent::GetTorque() const noexcept
|
||||
{
|
||||
return torque;
|
||||
}
|
||||
|
||||
const SHVec3& SHRigidBodyComponent::GetLinearVelocity() const noexcept
|
||||
{
|
||||
return linearVelocity;
|
||||
}
|
||||
|
||||
const SHVec3& SHRigidBodyComponent::GetAngularVelocity() const noexcept
|
||||
{
|
||||
return angularVelocity;
|
||||
}
|
||||
|
||||
const SHVec3& SHRigidBodyComponent::GetPosition() const noexcept
|
||||
{
|
||||
return position;
|
||||
}
|
||||
|
||||
const SHQuaternion& SHRigidBodyComponent::GetOrientation() const noexcept
|
||||
{
|
||||
return orientation;
|
||||
}
|
||||
|
||||
SHVec3 SHRigidBodyComponent::GetRotation() const noexcept
|
||||
{
|
||||
return orientation.ToEuler();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Setter Function Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
void SHRigidBodyComponent::SetType(Type newType) noexcept
|
||||
{
|
||||
if (type == newType)
|
||||
return;
|
||||
|
||||
dirtyFlags |= 1U << 4;
|
||||
type = newType;
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::SetGravityEnabled(bool enableGravity) noexcept
|
||||
{
|
||||
constexpr int FLAG_POS = 0;
|
||||
|
||||
dirtyFlags |= 1U << FLAG_POS;
|
||||
enableGravity ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::SetIsAllowedToSleep(bool isAllowedToSleep) noexcept
|
||||
{
|
||||
constexpr int FLAG_POS = 1;
|
||||
|
||||
dirtyFlags |= 1U << 1;
|
||||
isAllowedToSleep ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::SetFreezePositionX(bool freezePositionX) noexcept
|
||||
{
|
||||
constexpr int FLAG_POS = 2;
|
||||
|
||||
dirtyFlags |= 1U << 2;
|
||||
freezePositionX ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::SetFreezePositionY(bool freezePositionY) noexcept
|
||||
{
|
||||
constexpr int FLAG_POS = 3;
|
||||
|
||||
dirtyFlags |= 1U << 2;
|
||||
freezePositionY ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::SetFreezePositionZ(bool freezePositionZ) noexcept
|
||||
{
|
||||
constexpr int FLAG_POS = 4;
|
||||
|
||||
dirtyFlags |= 1U << 2;
|
||||
freezePositionZ ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::SetFreezeRotationX(bool freezeRotationX) noexcept
|
||||
{
|
||||
constexpr int FLAG_POS = 5;
|
||||
|
||||
dirtyFlags |= 1U << 3;
|
||||
freezeRotationX ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::SetFreezeRotationY(bool freezeRotationY) noexcept
|
||||
{
|
||||
constexpr int FLAG_POS = 6;
|
||||
|
||||
dirtyFlags |= 1U << 3;
|
||||
freezeRotationY ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::SetFreezeRotationZ(bool freezeRotationZ) noexcept
|
||||
{
|
||||
constexpr int FLAG_POS = 7;
|
||||
|
||||
dirtyFlags |= 1U << 3;
|
||||
freezeRotationZ ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::SetInterpolate(bool allowInterpolation) noexcept
|
||||
{
|
||||
interpolate = allowInterpolation;
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::SetMass(float newMass) noexcept
|
||||
{
|
||||
dirtyFlags |= 1U << 5;
|
||||
mass = newMass;
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::SetDrag(float newDrag) noexcept
|
||||
{
|
||||
dirtyFlags |= 1U << 6;
|
||||
drag = newDrag;
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::SetAngularDrag(float newAngularDrag) noexcept
|
||||
{
|
||||
dirtyFlags |= 1U << 7;
|
||||
angularDrag = newAngularDrag;
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::SetLinearVelocity(const SHVec3& newLinearVelocity) noexcept
|
||||
{
|
||||
dirtyFlags |= 1U << 8;
|
||||
linearVelocity = newLinearVelocity;
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::SetAngularVelocity(const SHVec3& newAngularVelocity) noexcept
|
||||
{
|
||||
dirtyFlags |= 1U << 9;
|
||||
angularVelocity = newAngularVelocity;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Public Function Member Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
void SHRigidBodyComponent::OnCreate()
|
||||
{
|
||||
system = SHSystemManager::GetSystem<SHPhysicsSystem>();
|
||||
if (!system)
|
||||
{
|
||||
SHLOG_ERROR("Physics system does not exist, Rigid Body Component not added!")
|
||||
return;
|
||||
}
|
||||
|
||||
// Notify Physics System
|
||||
system->AddRigidBody(GetEID());
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::OnDestroy()
|
||||
{
|
||||
// Notify Physics System
|
||||
if (!system)
|
||||
{
|
||||
SHLOG_ERROR("Physics system does not exist, unable to remove Rigid Body Component!")
|
||||
return;
|
||||
}
|
||||
|
||||
system->RemoveRigidBody(GetEID());
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::AddForce(const SHVec3& force) const noexcept
|
||||
{
|
||||
if (!system)
|
||||
{
|
||||
SHLOG_ERROR("Physics system does not exist, unable to Add Force to a body!")
|
||||
return;
|
||||
}
|
||||
|
||||
// Notify Physics Systems
|
||||
system->AddForce(GetEID(), force);
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::AddForceAtLocalPos(const SHVec3& force, const SHVec3& localPos) const noexcept
|
||||
{
|
||||
if (!system)
|
||||
{
|
||||
SHLOG_ERROR("Physics system does not exist, unable to Add Force to a body!")
|
||||
return;
|
||||
}
|
||||
|
||||
// Notify Physics Systems
|
||||
system->AddForceAtLocalPos(GetEID(), force, localPos);
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::AddForceAtWorldPos(const SHVec3& force, const SHVec3& worldPos) const noexcept
|
||||
{
|
||||
if (!system)
|
||||
{
|
||||
SHLOG_ERROR("Physics system does not exist, unable to Add Force to a body!")
|
||||
return;
|
||||
}
|
||||
|
||||
// Notify Physics Systems
|
||||
system->AddForceAtWorldPos(GetEID(), force, worldPos);
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::AddRelativeForce(const SHVec3& relativeForce) const noexcept
|
||||
{
|
||||
if (!system)
|
||||
{
|
||||
SHLOG_ERROR("Physics system does not exist, unable to Add Force to a body!")
|
||||
return;
|
||||
}
|
||||
|
||||
// Notify Physics Systems
|
||||
system->AddRelativeForce(GetEID(), force);
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::AddRelativeForceAtLocalPos(const SHVec3& relativeForce, const SHVec3& localPos) const noexcept
|
||||
{
|
||||
if (!system)
|
||||
{
|
||||
SHLOG_ERROR("Physics system does not exist, unable to Add Force to a body!")
|
||||
return;
|
||||
}
|
||||
|
||||
// Notify Physics Systems
|
||||
system->AddRelativeForceAtLocalPos(GetEID(), force, localPos);
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::AddRelativeForceAtWorldPos(const SHVec3& relativeForce, const SHVec3& worldPos) const noexcept
|
||||
{
|
||||
if (!system)
|
||||
{
|
||||
SHLOG_ERROR("Physics system does not exist, unable to Add Force to a body!")
|
||||
return;
|
||||
}
|
||||
|
||||
// Notify Physics Systems
|
||||
system->AddRelativeForceAtWorldPos(GetEID(), force, worldPos);
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::AddTorque(const SHVec3& torque) const noexcept
|
||||
{
|
||||
if (!system)
|
||||
{
|
||||
SHLOG_ERROR("Physics system does not exist, unable to Add Force to a body!")
|
||||
return;
|
||||
}
|
||||
|
||||
// Notify Physics Systems
|
||||
system->AddTorque(GetEID(), torque);
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::AddRelativeTorque(const SHVec3& relativeTorque) const noexcept
|
||||
{
|
||||
if (!system)
|
||||
{
|
||||
SHLOG_ERROR("Physics system does not exist, unable to Add Force to a body!")
|
||||
return;
|
||||
}
|
||||
|
||||
// Notify Physics Systems
|
||||
system->AddRelativeTorque(GetEID(), relativeTorque);
|
||||
}
|
||||
|
||||
} // namespace SHADE
|
||||
|
||||
RTTR_REGISTRATION
|
||||
{
|
||||
using namespace SHADE;
|
||||
using namespace rttr;
|
||||
|
||||
registration::enumeration<SHRigidBodyComponent::Type>("RigidBody Type")
|
||||
(
|
||||
value("Static", SHRigidBodyComponent::Type::STATIC),
|
||||
value("Dynamic", SHRigidBodyComponent::Type::DYNAMIC),
|
||||
value("Kinematic", SHRigidBodyComponent::Type::KINEMATIC)
|
||||
);
|
||||
|
||||
registration::class_<SHRigidBodyComponent>("RigidBody Component")
|
||||
.property("Type" , &SHRigidBodyComponent::GetType , &SHRigidBodyComponent::SetType )
|
||||
.property("Mass" , &SHRigidBodyComponent::GetMass , &SHRigidBodyComponent::SetMass )
|
||||
.property("Drag" , &SHRigidBodyComponent::GetDrag , &SHRigidBodyComponent::SetDrag )
|
||||
.property("Angular Drag" , &SHRigidBodyComponent::GetAngularDrag , &SHRigidBodyComponent::SetAngularDrag )
|
||||
.property("Use Gravity" , &SHRigidBodyComponent::IsGravityEnabled , &SHRigidBodyComponent::SetGravityEnabled )
|
||||
.property("Interpolate" , &SHRigidBodyComponent::IsInterpolating , &SHRigidBodyComponent::SetInterpolate )
|
||||
.property("Freeze Position X" , &SHRigidBodyComponent::GetFreezePositionX , &SHRigidBodyComponent::SetFreezePositionX )
|
||||
.property("Freeze Position Y" , &SHRigidBodyComponent::GetFreezePositionY , &SHRigidBodyComponent::SetFreezePositionY )
|
||||
.property("Freeze Position Z" , &SHRigidBodyComponent::GetFreezePositionZ , &SHRigidBodyComponent::SetFreezePositionZ )
|
||||
.property("Freeze Rotation X" , &SHRigidBodyComponent::GetFreezeRotationX , &SHRigidBodyComponent::SetFreezeRotationX )
|
||||
.property("Freeze Rotation Y" , &SHRigidBodyComponent::GetFreezeRotationY , &SHRigidBodyComponent::SetFreezeRotationY )
|
||||
.property("Freeze Rotation Z" , &SHRigidBodyComponent::GetFreezeRotationZ , &SHRigidBodyComponent::SetFreezeRotationZ );
|
||||
}
|
|
@ -0,0 +1,171 @@
|
|||
/****************************************************************************************
|
||||
* \file SHRigidBodyComponent.h
|
||||
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||
* \brief Interface for a Rigidbody Component.
|
||||
*
|
||||
* \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.
|
||||
****************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <rttr/registration>
|
||||
|
||||
// Project Headers
|
||||
#include "ECS_Base/Components/SHComponent.h"
|
||||
#include "Physics/SHPhysicsObject.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
class SH_API SHRigidBodyComponent : public SHComponent
|
||||
{
|
||||
private:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Friends */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
friend class SHPhysicsSystem;
|
||||
|
||||
public:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
enum class Type
|
||||
{
|
||||
STATIC
|
||||
, KINEMATIC
|
||||
, DYNAMIC
|
||||
|
||||
, COUNT
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constructors & Destructor */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
SHRigidBodyComponent () noexcept;
|
||||
SHRigidBodyComponent (const SHRigidBodyComponent& rhs) noexcept = default;
|
||||
SHRigidBodyComponent (SHRigidBodyComponent&& rhs) noexcept = default;
|
||||
~SHRigidBodyComponent () override = default;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Operator Overloads */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
SHRigidBodyComponent& operator=(const SHRigidBodyComponent& rhs) noexcept = default;
|
||||
SHRigidBodyComponent& operator=(SHRigidBodyComponent&& rhs) noexcept = default;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Getter Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
[[nodiscard]] bool IsGravityEnabled () const noexcept;
|
||||
[[nodiscard]] bool IsAllowedToSleep () const noexcept;
|
||||
[[nodiscard]] bool IsInterpolating () const noexcept;
|
||||
|
||||
[[nodiscard]] Type GetType () const noexcept;
|
||||
[[nodiscard]] float GetMass () const noexcept;
|
||||
[[nodiscard]] float GetDrag () const noexcept;
|
||||
[[nodiscard]] float GetAngularDrag () const noexcept;
|
||||
|
||||
[[nodiscard]] bool GetFreezePositionX () const noexcept;
|
||||
[[nodiscard]] bool GetFreezePositionY () const noexcept;
|
||||
[[nodiscard]] bool GetFreezePositionZ () const noexcept;
|
||||
|
||||
[[nodiscard]] bool GetFreezeRotationX () const noexcept;
|
||||
[[nodiscard]] bool GetFreezeRotationY () const noexcept;
|
||||
[[nodiscard]] bool GetFreezeRotationZ () const noexcept;
|
||||
|
||||
[[nodiscard]] const SHVec3& GetForce () const noexcept;
|
||||
[[nodiscard]] const SHVec3& GetTorque () const noexcept;
|
||||
[[nodiscard]] const SHVec3& GetLinearVelocity () const noexcept;
|
||||
[[nodiscard]] const SHVec3& GetAngularVelocity () const noexcept;
|
||||
|
||||
[[nodiscard]] const SHVec3& GetPosition () const noexcept;
|
||||
[[nodiscard]] const SHQuaternion& GetOrientation () const noexcept;
|
||||
[[nodiscard]] SHVec3 GetRotation () const noexcept;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Setter Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
void SetType (Type newType) noexcept;
|
||||
|
||||
void SetGravityEnabled (bool enableGravity) noexcept;
|
||||
void SetIsAllowedToSleep(bool isAllowedToSleep) noexcept;
|
||||
void SetFreezePositionX (bool freezePositionX) noexcept;
|
||||
void SetFreezePositionY (bool freezePositionY) noexcept;
|
||||
void SetFreezePositionZ (bool freezePositionZ) noexcept;
|
||||
void SetFreezeRotationX (bool freezeRotationX) noexcept;
|
||||
void SetFreezeRotationY (bool freezeRotationY) noexcept;
|
||||
void SetFreezeRotationZ (bool freezeRotationZ) noexcept;
|
||||
void SetInterpolate (bool allowInterpolation) noexcept;
|
||||
|
||||
void SetMass (float newMass) noexcept;
|
||||
void SetDrag (float newDrag) noexcept;
|
||||
void SetAngularDrag (float newAngularDrag) noexcept;
|
||||
|
||||
void SetLinearVelocity (const SHVec3& newLinearVelocity) noexcept;
|
||||
void SetAngularVelocity (const SHVec3& newAngularVelocity) noexcept;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Function Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
void OnCreate () override;
|
||||
void OnDestroy () override;
|
||||
|
||||
void AddForce (const SHVec3& force) const noexcept;
|
||||
void AddForceAtLocalPos (const SHVec3& force, const SHVec3& localPos) const noexcept;
|
||||
void AddForceAtWorldPos (const SHVec3& force, const SHVec3& worldPos) const noexcept;
|
||||
|
||||
void AddRelativeForce (const SHVec3& relativeForce) const noexcept;
|
||||
void AddRelativeForceAtLocalPos (const SHVec3& relativeForce, const SHVec3& localPos) const noexcept;
|
||||
void AddRelativeForceAtWorldPos (const SHVec3& relativeForce, const SHVec3& worldPos) const noexcept;
|
||||
|
||||
void AddTorque (const SHVec3& torque) const noexcept;
|
||||
void AddRelativeTorque (const SHVec3& relativeTorque) const noexcept;
|
||||
|
||||
private:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
Type type;
|
||||
|
||||
// rX rY rZ pX pY pZ slp g
|
||||
uint8_t flags;
|
||||
// 0 0 0 0 0 0 aV lV aD d m t ag lc slp g
|
||||
uint16_t dirtyFlags;
|
||||
bool interpolate;
|
||||
|
||||
SHPhysicsSystem* system;
|
||||
|
||||
float mass;
|
||||
float drag;
|
||||
float angularDrag;
|
||||
|
||||
SHVec3 force;
|
||||
SHVec3 linearVelocity;
|
||||
|
||||
SHVec3 torque;
|
||||
SHVec3 angularVelocity;
|
||||
|
||||
// TODO(Diren): Once quaternions have replaced euler angles in transforms, store it for the rigidbody.
|
||||
|
||||
SHVec3 position;
|
||||
SHQuaternion orientation;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Function Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
RTTR_ENABLE()
|
||||
};
|
||||
} // namespace SHADE
|
|
@ -0,0 +1,215 @@
|
|||
/****************************************************************************************
|
||||
* \file SHCollider.cpp
|
||||
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||
* \brief Implementation for a Collider.
|
||||
*
|
||||
* \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.
|
||||
****************************************************************************************/
|
||||
|
||||
#include <SHpch.h>
|
||||
|
||||
// Primary Header
|
||||
#include "SHCollider.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Constructors & Destructor Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
SHCollider::SHCollider(Type colliderType)
|
||||
: type { colliderType }
|
||||
, isTrigger { false }
|
||||
, dirty { true }
|
||||
, shape { nullptr }
|
||||
{
|
||||
CreateShape();
|
||||
}
|
||||
|
||||
SHCollider::SHCollider(const SHCollider& rhs) noexcept
|
||||
: type { rhs.type}
|
||||
, isTrigger { rhs.isTrigger }
|
||||
, dirty { true }
|
||||
, shape { nullptr }
|
||||
{
|
||||
CreateShape();
|
||||
|
||||
// TODO(Diren): Copy transform data over
|
||||
}
|
||||
|
||||
SHCollider::SHCollider(SHCollider&& rhs) noexcept
|
||||
: type { rhs.type}
|
||||
, isTrigger { rhs.isTrigger }
|
||||
, dirty { true }
|
||||
, shape { nullptr }
|
||||
{
|
||||
CreateShape();
|
||||
|
||||
// TODO(Diren): Copy transform data over
|
||||
}
|
||||
|
||||
SHCollider::~SHCollider() noexcept
|
||||
{
|
||||
delete shape;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Operator Overload Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
SHCollider& SHCollider::operator=(const SHCollider& rhs) noexcept
|
||||
{
|
||||
type = rhs.type;
|
||||
isTrigger = rhs.isTrigger;
|
||||
dirty = true;
|
||||
|
||||
CreateShape();
|
||||
|
||||
// TODO(Diren): Copy transform data over
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
SHCollider& SHCollider::operator=(SHCollider&& rhs) noexcept
|
||||
{
|
||||
type = rhs.type;
|
||||
isTrigger = rhs.isTrigger;
|
||||
dirty = true;
|
||||
|
||||
CreateShape();
|
||||
|
||||
// TODO(Diren): Copy transform data over
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Getter Function Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
bool SHCollider::HasChanged() const noexcept
|
||||
{
|
||||
return dirty;
|
||||
}
|
||||
|
||||
bool SHCollider::IsTrigger() const noexcept
|
||||
{
|
||||
return isTrigger;
|
||||
}
|
||||
|
||||
SHCollider::Type SHCollider::GetType() const noexcept
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
SHShape* SHCollider::GetShape() const noexcept
|
||||
{
|
||||
return shape;
|
||||
}
|
||||
|
||||
float SHCollider::GetFriction() const noexcept
|
||||
{
|
||||
// TODO(Diren): Fix after implementing materials
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float SHCollider::GetBounciness() const noexcept
|
||||
{
|
||||
// TODO(Diren): Fix after implementing materials
|
||||
return 0.0f;
|
||||
}
|
||||
float SHCollider::GetDensity() const noexcept
|
||||
{
|
||||
// TODO(Diren): Fix after implementing materials
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
SHVec3 SHCollider::GetPosition() const noexcept
|
||||
{
|
||||
// TODO(Diren): Fix after linking transform data
|
||||
return SHVec3::Zero;
|
||||
}
|
||||
|
||||
const SHVec3& SHCollider::GetPositionOffset() const noexcept
|
||||
{
|
||||
return positionOffset;
|
||||
}
|
||||
|
||||
SHQuaternion SHCollider::GetOrientation() const noexcept
|
||||
{
|
||||
// TODO(Diren): Fix after linking transform data
|
||||
return SHQuaternion::Identity;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Setter Function Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
void SHCollider::SetType(Type newType) noexcept
|
||||
{
|
||||
if (type == newType)
|
||||
return;
|
||||
|
||||
dirty = true;
|
||||
|
||||
type = newType;
|
||||
CreateShape();
|
||||
}
|
||||
|
||||
void SHCollider::SetIsTrigger(bool trigger) noexcept
|
||||
{
|
||||
dirty = true;
|
||||
isTrigger = trigger;
|
||||
}
|
||||
|
||||
void SHCollider::SetFriction(float friction) noexcept
|
||||
{
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
void SHCollider::SetBounciness(float bounciness) noexcept
|
||||
{
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
void SHCollider::SetDensity(float density) noexcept
|
||||
{
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
void SHCollider::SetPositionOffset(const SHVec3& posOffset) noexcept
|
||||
{
|
||||
dirty = true;
|
||||
positionOffset = posOffset;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Private Member Function Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
void SHCollider::CreateShape()
|
||||
{
|
||||
// Remove current shape
|
||||
delete shape;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case Type::BOX: CreateBoundingBox(); break;
|
||||
case Type::SPHERE: CreateSphere(); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
void SHCollider::CreateBoundingBox()
|
||||
{
|
||||
shape = new SHBoundingBox{ SHVec3::Zero, SHVec3::One };
|
||||
}
|
||||
|
||||
void SHCollider::CreateSphere()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
} // namespace SHADE
|
|
@ -0,0 +1,108 @@
|
|||
/****************************************************************************************
|
||||
* \file SHCollider.h
|
||||
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||
* \brief Interface for a Collider.
|
||||
*
|
||||
* \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.
|
||||
****************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
// Project Headers
|
||||
#include "Math/Geometry/SHBoundingBox.h"
|
||||
#include "Math/SHQuaternion.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
class SH_API SHCollider
|
||||
{
|
||||
public:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
enum class Type
|
||||
{
|
||||
BOX
|
||||
, SPHERE
|
||||
, CAPSULE
|
||||
, CONVEX_HULL
|
||||
, CONVEX_MESH
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constructors & Destructor */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
SHCollider (Type colliderType);
|
||||
|
||||
SHCollider (const SHCollider& rhs) noexcept;
|
||||
SHCollider (SHCollider&& rhs) noexcept;
|
||||
~SHCollider () noexcept;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Operator Overloads */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
SHCollider& operator=(const SHCollider& rhs) noexcept;
|
||||
SHCollider& operator=(SHCollider&& rhs) noexcept;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Getter Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
[[nodiscard]] bool HasChanged () const noexcept;
|
||||
|
||||
[[nodiscard]] bool IsTrigger () const noexcept;
|
||||
|
||||
[[nodiscard]] Type GetType () const noexcept;
|
||||
[[nodiscard]] SHShape* GetShape () const noexcept;
|
||||
|
||||
[[nodiscard]] float GetFriction () const noexcept;
|
||||
[[nodiscard]] float GetBounciness () const noexcept;
|
||||
[[nodiscard]] float GetDensity () const noexcept;
|
||||
|
||||
[[nodiscard]] SHVec3 GetPosition () const noexcept;
|
||||
[[nodiscard]] const SHVec3& GetPositionOffset () const noexcept;
|
||||
[[nodiscard]] SHQuaternion GetOrientation () const noexcept;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Setter Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
void SetType (Type newType) noexcept;
|
||||
|
||||
void SetIsTrigger (bool isTrigger) noexcept;
|
||||
void SetFriction (float friction) noexcept;
|
||||
void SetBounciness (float bounciness) noexcept;
|
||||
void SetDensity (float density) noexcept;
|
||||
|
||||
void SetPositionOffset (const SHVec3& positionOffset) noexcept;
|
||||
|
||||
private:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
Type type;
|
||||
bool isTrigger;
|
||||
bool dirty;
|
||||
SHShape* shape;
|
||||
SHVec3 positionOffset;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Function Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
void CreateShape ();
|
||||
void CreateBoundingBox ();
|
||||
void CreateSphere ();
|
||||
};
|
||||
|
||||
} // namespace SHADE
|
|
@ -0,0 +1,121 @@
|
|||
/****************************************************************************************
|
||||
* \file SHPhysicsObject.cpp
|
||||
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||
* \brief Implementation for a Physics Object.
|
||||
*
|
||||
* \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.
|
||||
****************************************************************************************/
|
||||
|
||||
#include <SHpch.h>
|
||||
|
||||
// Primary Header
|
||||
#include "SHPhysicsObject.h"
|
||||
|
||||
// Project Headers
|
||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
#include "SHPhysicsSystem.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Constructors & Destructor Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
SHPhysicsObject::SHPhysicsObject() noexcept
|
||||
: entityID { MAX_EID }
|
||||
, isRigidBody { false }
|
||||
, hasColliders{ false }
|
||||
, rp3dBody { nullptr }
|
||||
{}
|
||||
|
||||
SHPhysicsObject::~SHPhysicsObject() noexcept
|
||||
{
|
||||
rp3dBody = nullptr;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Getter Function Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
SHVec3 SHPhysicsObject::GetPosition() const noexcept
|
||||
{
|
||||
SHVec3 result;
|
||||
|
||||
if (rp3dBody)
|
||||
{
|
||||
const auto& RP3D_RESULT = rp3dBody->getTransform().getPosition();
|
||||
result = SHVec3{ RP3D_RESULT.x, RP3D_RESULT.y, RP3D_RESULT.z };
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
SHQuaternion SHPhysicsObject::GetOrientation() const noexcept
|
||||
{
|
||||
SHQuaternion result;
|
||||
|
||||
if (rp3dBody)
|
||||
{
|
||||
const auto& RP3D_RESULT = rp3dBody->getTransform().getOrientation();
|
||||
result = SHQuaternion{ RP3D_RESULT.x, RP3D_RESULT.y, RP3D_RESULT.z, RP3D_RESULT.w };
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
SHVec3 SHPhysicsObject::GetRotation() const noexcept
|
||||
{
|
||||
SHVec3 result;
|
||||
|
||||
if (rp3dBody)
|
||||
{
|
||||
const auto& RP3D_RESULT = rp3dBody->getTransform().getOrientation();
|
||||
result = SHQuaternion{ RP3D_RESULT.x, RP3D_RESULT.y, RP3D_RESULT.z, RP3D_RESULT.w }.ToEuler();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Setter Function Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
void SHPhysicsObject::SetPosition(const SHVec3& position) noexcept
|
||||
{
|
||||
const rp3d::Vector3 RP3D_POS { position.x, position.y, position.z };
|
||||
|
||||
rp3d::Transform rp3dTF;
|
||||
rp3dTF.setPosition(RP3D_POS);
|
||||
rp3dTF.setOrientation(rp3dBody->getTransform().getOrientation());
|
||||
|
||||
rp3dBody->setTransform(rp3dTF);
|
||||
prevTransform = rp3dTF;
|
||||
}
|
||||
|
||||
void SHPhysicsObject::SetOrientation(const SHQuaternion& orientation) noexcept
|
||||
{
|
||||
const rp3d::Quaternion RP3D_ORIENTATION { orientation.x, orientation.y, orientation.z, orientation.w };
|
||||
|
||||
rp3d::Transform rp3dTF;
|
||||
rp3dTF.setPosition(rp3dBody->getTransform().getPosition());
|
||||
rp3dTF.setOrientation(RP3D_ORIENTATION);
|
||||
|
||||
rp3dBody->setTransform(rp3dTF);
|
||||
prevTransform = rp3dTF;
|
||||
}
|
||||
|
||||
void SHPhysicsObject::SetRotation(const SHVec3& rotation) noexcept
|
||||
{
|
||||
const rp3d::Quaternion RP3D_ORIENTATION = rp3d::Quaternion::fromEulerAngles( rotation.x, rotation.y, rotation.z );
|
||||
|
||||
rp3d::Transform rp3dTF;
|
||||
rp3dTF.setPosition(rp3dBody->getTransform().getPosition());
|
||||
rp3dTF.setOrientation(RP3D_ORIENTATION);
|
||||
|
||||
rp3dBody->setTransform(rp3dTF);
|
||||
prevTransform = rp3dTF;
|
||||
}
|
||||
|
||||
} // namespace SHADE
|
|
@ -0,0 +1,89 @@
|
|||
/****************************************************************************************
|
||||
* \file SHPhysicsObject.h
|
||||
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||
* \brief Interface for a Physics Object.
|
||||
*
|
||||
* \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.
|
||||
****************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <reactphysics3d/reactphysics3d.h>
|
||||
|
||||
// Project Headers
|
||||
#include "Math/Vector/SHVec3.h"
|
||||
#include "Math/SHQuaternion.h"
|
||||
#include "ECS_Base/Entity/SHEntity.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
class SH_API SHPhysicsObject
|
||||
{
|
||||
private:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Friends */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
friend class SHPhysicsSystem;
|
||||
friend class SHRigidBodyComponent;
|
||||
friend class SHColliderComponent;
|
||||
|
||||
public:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constructors & Destructor */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
SHPhysicsObject () noexcept;
|
||||
SHPhysicsObject (const SHPhysicsObject& rhs) noexcept = default;
|
||||
SHPhysicsObject (SHPhysicsObject&& rhs) noexcept = default;
|
||||
virtual ~SHPhysicsObject () noexcept;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Operator Overloads */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
SHPhysicsObject& operator=(const SHPhysicsObject& rhs) noexcept = default;
|
||||
SHPhysicsObject& operator=(SHPhysicsObject&& rhs) noexcept = default;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Getter Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
[[nodiscard]] SHVec3 GetPosition () const noexcept;
|
||||
[[nodiscard]] SHQuaternion GetOrientation () const noexcept;
|
||||
[[nodiscard]] SHVec3 GetRotation () const noexcept;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Setter Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
void SetPosition (const SHVec3& position) noexcept;
|
||||
void SetOrientation (const SHQuaternion& orientation) noexcept;
|
||||
void SetRotation (const SHVec3& rotation) noexcept;
|
||||
|
||||
private:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
EntityID entityID;
|
||||
bool isRigidBody;
|
||||
bool hasColliders;
|
||||
|
||||
rp3d::CollisionBody* rp3dBody; // Can be either a collision body or a rigid body
|
||||
rp3d::Transform prevTransform; // Cached transform for interpolation
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Function Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
};
|
||||
} // namespace SHADE
|
|
@ -0,0 +1,747 @@
|
|||
/****************************************************************************************
|
||||
* \file SHPhysicsSystem.cpp
|
||||
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||
* \brief Implementation for the Physics System
|
||||
*
|
||||
* \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.
|
||||
****************************************************************************************/
|
||||
|
||||
#include <SHpch.h>
|
||||
|
||||
// Primary Header
|
||||
#include "SHPhysicsSystem.h"
|
||||
|
||||
// Project Headers
|
||||
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||
#include "Scene/SHSceneManager.h"
|
||||
#include "Math/Transform/SHTransformComponent.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Constructors & Destructor Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
SHPhysicsSystem::SHPhysicsSystem()
|
||||
: worldUpdated { false }
|
||||
, interpolationFactor { 0.0 }
|
||||
, fixedDT { 60.0 }
|
||||
, world { nullptr }
|
||||
{}
|
||||
|
||||
SHPhysicsSystem::PhysicsPreUpdate::PhysicsPreUpdate()
|
||||
: SHSystemRoutine { "Physics PreUpdate", true }
|
||||
{}
|
||||
|
||||
SHPhysicsSystem::PhysicsFixedUpdate::PhysicsFixedUpdate()
|
||||
: SHFixedSystemRoutine { DEFAULT_FIXED_STEP, "Physics FixedUpdate", false }
|
||||
{}
|
||||
|
||||
SHPhysicsSystem::PhysicsPostUpdate::PhysicsPostUpdate()
|
||||
: SHSystemRoutine { "Physics PostUpdate", false }
|
||||
{}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Getter Function Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
double SHPhysicsSystem::GetFixedDT() const noexcept
|
||||
{
|
||||
return fixedDT;
|
||||
}
|
||||
|
||||
bool SHPhysicsSystem::IsSleepingEnabled() const noexcept
|
||||
{
|
||||
if (world)
|
||||
return world->isSleepingEnabled();
|
||||
|
||||
SHLOGV_WARNING("No physics world has been initialised!")
|
||||
return false;
|
||||
}
|
||||
|
||||
SHVec3 SHPhysicsSystem::GetWorldGravity() const noexcept
|
||||
{
|
||||
SHVec3 result;
|
||||
|
||||
if (world)
|
||||
{
|
||||
const auto RP3D_GRAVITY = world->getGravity();
|
||||
result.x = RP3D_GRAVITY.x;
|
||||
result.y = RP3D_GRAVITY.y;
|
||||
result.z = RP3D_GRAVITY.z;
|
||||
}
|
||||
else
|
||||
{
|
||||
SHLOGV_WARNING("No physics world has been initialised!")
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
uint16_t SHPhysicsSystem::GetNumberVelocityIterations() const noexcept
|
||||
{
|
||||
if (world)
|
||||
return world->getNbIterationsVelocitySolver();
|
||||
|
||||
SHLOGV_WARNING("No physics world has been initialised!")
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t SHPhysicsSystem::GetNumberPositionIterations() const noexcept
|
||||
{
|
||||
if (world)
|
||||
return world->getNbIterationsPositionSolver();
|
||||
|
||||
SHLOGV_WARNING("No physics world has been initialised!")
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Setter Function Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
void SHPhysicsSystem::SetFixedDT(double fixedUpdateRate) noexcept
|
||||
{
|
||||
fixedDT = fixedUpdateRate;
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::SetWorldGravity(const SHVec3& gravity) const noexcept
|
||||
{
|
||||
if (world)
|
||||
{
|
||||
const rp3d::Vector3 G { gravity.x, gravity.y, gravity.z };
|
||||
world->setGravity(G);
|
||||
}
|
||||
else
|
||||
{
|
||||
SHLOGV_WARNING("No physics world has been initialised!")
|
||||
}
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::SetNumberVelocityIterations(uint16_t numVelIterations) const noexcept
|
||||
{
|
||||
if (world)
|
||||
{
|
||||
world->setNbIterationsVelocitySolver(numVelIterations);
|
||||
}
|
||||
else
|
||||
{
|
||||
SHLOGV_WARNING("No physics world has been initialised!")
|
||||
}
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::SetNumberPositionIterations(uint16_t numPosIterations) const noexcept
|
||||
{
|
||||
if (world)
|
||||
{
|
||||
world->setNbIterationsPositionSolver(numPosIterations);
|
||||
}
|
||||
else
|
||||
{
|
||||
SHLOGV_WARNING("No physics world has been initialised!")
|
||||
}
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::SetSleepingEnabled(bool enableSleeping) const noexcept
|
||||
{
|
||||
if (world)
|
||||
{
|
||||
world->enableSleeping(enableSleeping);
|
||||
}
|
||||
else
|
||||
{
|
||||
SHLOGV_WARNING("No physics world has been initialised!")
|
||||
}
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::SetWorldSettings(const WorldSettings& settings) const noexcept
|
||||
{
|
||||
if (world)
|
||||
{
|
||||
const rp3d::Vector3 G { settings.gravity.x, settings.gravity.y, settings.gravity.z };
|
||||
world->setGravity(G);
|
||||
world->setNbIterationsVelocitySolver(settings.numVelocitySolverIterations);
|
||||
world->setNbIterationsPositionSolver(settings.numPositionSolverIterations);
|
||||
world->enableSleeping(settings.sleepingEnabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
SHLOGV_WARNING("No physics world has been initialised!")
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Public Function Member Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
void SHPhysicsSystem::Init()
|
||||
{
|
||||
using namespace rp3d;
|
||||
|
||||
// Create a physics world with the default settings
|
||||
PhysicsWorld::WorldSettings settings;
|
||||
settings.gravity = Vector3{ 0.0f, -9.81f, 0.0f };
|
||||
settings.isSleepingEnabled = true;
|
||||
settings.defaultVelocitySolverNbIterations = 8;
|
||||
settings.defaultPositionSolverNbIterations = 3;
|
||||
settings.defaultFrictionCoefficient = 0.4f;
|
||||
settings.defaultBounciness = 0.0f;
|
||||
|
||||
world = factory.createPhysicsWorld(settings);
|
||||
|
||||
// Set up solvers
|
||||
world->setContactsPositionCorrectionTechnique(rp3d::ContactsPositionCorrectionTechnique::SPLIT_IMPULSES);
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::Exit()
|
||||
{
|
||||
factory.destroyPhysicsWorld(world);
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::AddRigidBody(EntityID entityID) noexcept
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
SHLOG_INFO("Adding a Rigidbody to the Physics World.")
|
||||
#endif
|
||||
|
||||
// Check if entity is already a physics object
|
||||
auto* physicsObject = GetPhysicsObject(entityID);
|
||||
if (!physicsObject)
|
||||
{
|
||||
physicsObject = &(map.emplace(entityID, SHPhysicsObject{}).first->second);
|
||||
physicsObject->entityID = entityID;
|
||||
}
|
||||
|
||||
// Get entity transform
|
||||
auto const* SHADE_TF = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
|
||||
|
||||
// Possibly redundant
|
||||
if (!SHADE_TF)
|
||||
{
|
||||
SHComponentManager::AddComponent<SHTransformComponent>(entityID);
|
||||
SHADE_TF = SHComponentManager::GetComponent<SHTransformComponent>(entityID);
|
||||
}
|
||||
|
||||
const SHVec3& SHADE_POS = SHADE_TF->GetWorldPosition();
|
||||
const SHVec3& SHADE_ROT = SHADE_TF->GetWorldRotation();
|
||||
|
||||
const rp3d::Vector3 RP3D_POS { SHADE_POS.x, SHADE_POS.y, SHADE_POS.z };
|
||||
const rp3d::Quaternion RP3D_ROT = rp3d::Quaternion::fromEulerAngles( SHADE_ROT.x, SHADE_ROT.y, SHADE_ROT.z );
|
||||
|
||||
const rp3d::Transform RP3D_TF { RP3D_POS, RP3D_ROT };
|
||||
|
||||
// If collider already exists
|
||||
if (physicsObject->hasColliders)
|
||||
world->destroyCollisionBody(physicsObject->rp3dBody);
|
||||
|
||||
physicsObject->rp3dBody = world->createRigidBody(RP3D_TF);
|
||||
physicsObject->isRigidBody = true;
|
||||
|
||||
// Recreate colliders
|
||||
if (physicsObject->hasColliders)
|
||||
{
|
||||
const auto& COLLIDERS = SHComponentManager::GetComponent<SHColliderComponent>(entityID)->GetColliders();
|
||||
for (const auto& collider : COLLIDERS | std::views::keys)
|
||||
{
|
||||
switch (collider.GetType())
|
||||
{
|
||||
case SHCollider::Type::BOX:
|
||||
{
|
||||
SHBoundingBox* box = reinterpret_cast<SHBoundingBox*>(collider.GetShape());
|
||||
const SHVec3& SHADE_EXTENTS = box->GetHalfExtents();
|
||||
|
||||
rp3d::Vector3 RP3D_EXTENTS { SHADE_EXTENTS.x, SHADE_EXTENTS.y, SHADE_EXTENTS.z };
|
||||
rp3d::BoxShape* newBox = factory.createBoxShape(RP3D_EXTENTS);
|
||||
|
||||
// TODO(Diren): Handle offsets
|
||||
physicsObject->rp3dBody->addCollider(newBox, RP3D_TF);
|
||||
break;
|
||||
}
|
||||
case SHCollider::Type::SPHERE:
|
||||
{
|
||||
break;
|
||||
}
|
||||
// TODO(Diren): Add more collider shapes
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::AddCollider(EntityID entityID) noexcept
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
SHLOG_INFO("Adding a Collider to the Physics World.")
|
||||
#endif
|
||||
|
||||
// Check if entity is already a physics object
|
||||
auto* physicsObject = GetPhysicsObject(entityID);
|
||||
if (!physicsObject)
|
||||
{
|
||||
physicsObject = &(map.emplace(entityID, SHPhysicsObject{}).first->second);
|
||||
physicsObject->entityID = entityID;
|
||||
}
|
||||
|
||||
// Get entity transform
|
||||
auto const* SHADE_TF = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
|
||||
|
||||
// Possibly redundant
|
||||
if (!SHADE_TF)
|
||||
{
|
||||
SHComponentManager::AddComponent<SHTransformComponent>(entityID);
|
||||
SHADE_TF = SHComponentManager::GetComponent<SHTransformComponent>(entityID);
|
||||
}
|
||||
|
||||
const SHVec3& SHADE_POS = SHADE_TF->GetWorldPosition();
|
||||
const SHVec3& SHADE_ROT = SHADE_TF->GetWorldRotation();
|
||||
|
||||
const rp3d::Vector3 RP3D_POS { SHADE_POS.x, SHADE_POS.y, SHADE_POS.z };
|
||||
const rp3d::Quaternion RP3D_ROT = rp3d::Quaternion::fromEulerAngles( SHADE_ROT.x, SHADE_ROT.y, SHADE_ROT.z );
|
||||
|
||||
const rp3d::Transform RP3D_TF { RP3D_POS, RP3D_ROT };
|
||||
|
||||
// No rb
|
||||
if (!physicsObject->isRigidBody)
|
||||
physicsObject->rp3dBody = world->createCollisionBody(RP3D_TF);
|
||||
|
||||
const auto& COLLIDERS = SHComponentManager::GetComponent<SHColliderComponent>(entityID)->GetColliders();
|
||||
for (const auto& collider : COLLIDERS | std::views::keys)
|
||||
{
|
||||
switch (collider.GetType())
|
||||
{
|
||||
case SHCollider::Type::BOX:
|
||||
{
|
||||
SHBoundingBox* box = reinterpret_cast<SHBoundingBox*>(collider.GetShape());
|
||||
const SHVec3& SHADE_EXTENTS = box->GetHalfExtents();
|
||||
|
||||
rp3d::Vector3 RP3D_EXTENTS { SHADE_EXTENTS.x, SHADE_EXTENTS.y, SHADE_EXTENTS.z };
|
||||
rp3d::BoxShape* newBox = factory.createBoxShape(RP3D_EXTENTS);
|
||||
|
||||
// TODO(Diren): Handle offsets
|
||||
physicsObject->rp3dBody->addCollider(newBox, RP3D_TF);
|
||||
break;
|
||||
}
|
||||
case SHCollider::Type::SPHERE:
|
||||
{
|
||||
break;
|
||||
}
|
||||
// TODO(Diren): Add more collider shapes
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
physicsObject->hasColliders = true;
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::RemoveRigidBody(EntityID entityID) noexcept
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
SHLOG_INFO("Removing a Rigidbody from the Physics World.")
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::RemoveCollider(EntityID entityID) noexcept
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
SHLOG_INFO("Removing a Collider from the Physics World.")
|
||||
#endif
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::AddForce(EntityID entityID, const SHVec3& force) const noexcept
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::AddForceAtLocalPos(EntityID entityID, const SHVec3& force, const SHVec3& localPos) const noexcept
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::AddForceAtWorldPos(EntityID entityID, const SHVec3& force, const SHVec3& worldPos) const noexcept
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::AddRelativeForce(EntityID entityID, const SHVec3& relativeForce) const noexcept
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::AddRelativeForceAtLocalPos(EntityID entityID, const SHVec3& relativeForce, const SHVec3& localPos) const noexcept
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::AddRelativeForceAtWorldPos(EntityID entityID, const SHVec3& relativeForce, const SHVec3& worldPos) const noexcept
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::AddTorque(EntityID entityID, const SHVec3& torque) const noexcept
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::AddRelativeTorque(EntityID entityID, const SHVec3& relativeTorque) const noexcept
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::AddCollisionShape(EntityID entityID, SHShape* shape)
|
||||
{
|
||||
auto* physicsObject = GetPhysicsObject(entityID);
|
||||
|
||||
switch (shape->GetType())
|
||||
{
|
||||
case SHShape::Type::BOUNDING_BOX:
|
||||
{
|
||||
auto* box = reinterpret_cast<SHBoundingBox*>(shape);
|
||||
const SHVec3& SHADE_EXTENTS = box->GetHalfExtents();
|
||||
|
||||
rp3d::Vector3 RP3D_EXTENTS { SHADE_EXTENTS.x, SHADE_EXTENTS.y, SHADE_EXTENTS.z };
|
||||
rp3d::BoxShape* newBox = factory.createBoxShape(RP3D_EXTENTS);
|
||||
|
||||
// TODO(Diren): Handle offsets
|
||||
|
||||
rp3d::Transform tf = rp3d::Transform::identity();
|
||||
physicsObject->rp3dBody->addCollider(newBox, tf);
|
||||
break;
|
||||
}
|
||||
case SHShape::Type::SPHERE:
|
||||
{
|
||||
break;
|
||||
}
|
||||
// TODO(Diren): Add more collider shapes
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::RemoveCollisionShape(EntityID entityID, int index)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::PhysicsPreUpdate::Execute(double) noexcept
|
||||
{
|
||||
auto* system = reinterpret_cast<SHPhysicsSystem*>(GetSystem());
|
||||
|
||||
// Update bodies and colliders if component is dirty
|
||||
system->SyncRigidBodyComponents(SHComponentManager::GetDense<SHRigidBodyComponent>());
|
||||
system->SyncColliderComponents(SHComponentManager::GetDense<SHColliderComponent>());
|
||||
|
||||
// Sync transforms
|
||||
for (auto& physicsObject : system->map | std::views::values)
|
||||
{
|
||||
const auto* TF = SHComponentManager::GetComponent<SHTransformComponent>(physicsObject.entityID);
|
||||
if (TF->HasChanged())
|
||||
{
|
||||
physicsObject.SetPosition(TF->GetWorldPosition());
|
||||
physicsObject.SetRotation(TF->GetWorldRotation());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::PhysicsFixedUpdate::Execute(double dt) noexcept
|
||||
{
|
||||
auto* system = reinterpret_cast<SHPhysicsSystem*>(GetSystem());
|
||||
fixedTimeStep = 1.0 / system->fixedDT;
|
||||
accumulatedTime += dt;
|
||||
|
||||
int count = 0;
|
||||
while (accumulatedTime > fixedTimeStep)
|
||||
{
|
||||
system->world->update(static_cast<rp3d::decimal>(fixedTimeStep));
|
||||
|
||||
accumulatedTime -= fixedTimeStep;
|
||||
++count;
|
||||
}
|
||||
|
||||
stats.numSteps = count;
|
||||
system->worldUpdated = count > 0;
|
||||
|
||||
system->interpolationFactor = accumulatedTime / fixedTimeStep;
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::PhysicsPostUpdate::Execute(double) noexcept
|
||||
{
|
||||
auto* system = reinterpret_cast<SHPhysicsSystem*>(GetSystem());
|
||||
|
||||
// Interpolate transforms for rendering
|
||||
if (system->worldUpdated)
|
||||
{
|
||||
system->SyncTransforms();
|
||||
// TODO(Diren): Handle trigger messages for scripting
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Private Function Member Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
SHPhysicsObject* SHPhysicsSystem::GetPhysicsObject(EntityID entityID) noexcept
|
||||
{
|
||||
const auto it = map.find(entityID);
|
||||
if (it == map.end())
|
||||
{
|
||||
SHLOG_ERROR("Entity {} is not in the physics system!", entityID)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &(it->second);
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::SyncRigidBodyComponents(std::vector<SHRigidBodyComponent>& denseArray) noexcept
|
||||
{
|
||||
if (denseArray.empty())
|
||||
return;
|
||||
|
||||
for (auto& comp : denseArray)
|
||||
{
|
||||
const EntityID ENTITY_ID = comp.GetEID();
|
||||
|
||||
// Get physicsObject
|
||||
auto const* physicsObject = GetPhysicsObject(ENTITY_ID);
|
||||
|
||||
const bool RP3D_ACTIVE = physicsObject->rp3dBody->isActive();
|
||||
// TODO(Diren): Check if active in hierarchy
|
||||
const bool COMPONENT_ACTIVE = comp.isActive;
|
||||
|
||||
if (RP3D_ACTIVE != COMPONENT_ACTIVE)
|
||||
physicsObject->rp3dBody->setIsActive(COMPONENT_ACTIVE);
|
||||
|
||||
if (!COMPONENT_ACTIVE)
|
||||
continue;
|
||||
|
||||
if (comp.dirtyFlags > 0)
|
||||
{
|
||||
SyncRigidBody(physicsObject, &comp);
|
||||
comp.dirtyFlags = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::SyncColliderComponents(std::vector<SHColliderComponent>& denseArray) noexcept
|
||||
{
|
||||
if (denseArray.empty())
|
||||
return;
|
||||
|
||||
for (auto& comp : denseArray)
|
||||
{
|
||||
const EntityID ENTITY_ID = comp.GetEID();
|
||||
|
||||
// Get physicsObject
|
||||
auto const* physicsObject = GetPhysicsObject(ENTITY_ID);
|
||||
|
||||
const bool RP3D_ACTIVE = physicsObject->rp3dBody->isActive();
|
||||
// TODO(Diren): Check if active in hierarchy
|
||||
const bool COMPONENT_ACTIVE = comp.isActive;
|
||||
|
||||
if (RP3D_ACTIVE != COMPONENT_ACTIVE)
|
||||
physicsObject->rp3dBody->setIsActive(COMPONENT_ACTIVE);
|
||||
|
||||
if (!COMPONENT_ACTIVE)
|
||||
continue;
|
||||
|
||||
SyncCollider(physicsObject, &comp);
|
||||
}
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::SyncTransforms() noexcept
|
||||
{
|
||||
for (auto& pair : map)
|
||||
{
|
||||
const EntityID ENTITY_ID = pair.first;
|
||||
SHPhysicsObject& physicsObject = pair.second;
|
||||
|
||||
rp3d::Vector3 rp3dPos;
|
||||
rp3d::Quaternion rp3dRot;
|
||||
|
||||
const rp3d::Transform CURRENT_TF = physicsObject.rp3dBody->getTransform();
|
||||
|
||||
// Check if transform should be interpolated
|
||||
|
||||
if (physicsObject.isRigidBody)
|
||||
{
|
||||
auto const* rbComponent = SHComponentManager::GetComponent<SHRigidBodyComponent>(ENTITY_ID);
|
||||
if (rbComponent->GetType() == SHRigidBodyComponent::Type::STATIC)
|
||||
continue;
|
||||
|
||||
if (rbComponent->IsInterpolating())
|
||||
{
|
||||
const rp3d::Transform PREV_TF = physicsObject.prevTransform;
|
||||
const rp3d::Transform INTERPOLATED_TF = rp3d::Transform::interpolateTransforms(PREV_TF, CURRENT_TF, static_cast<rp3d::decimal>(interpolationFactor));
|
||||
|
||||
|
||||
rp3dPos = INTERPOLATED_TF.getPosition();
|
||||
rp3dRot = INTERPOLATED_TF.getOrientation();
|
||||
}
|
||||
else
|
||||
{
|
||||
rp3dPos = CURRENT_TF.getPosition();
|
||||
rp3dRot = CURRENT_TF.getOrientation();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rp3dPos = CURRENT_TF.getPosition();
|
||||
rp3dRot = CURRENT_TF.getOrientation();
|
||||
}
|
||||
|
||||
// Convert RP3D Transform to SHADE
|
||||
const SHVec3 SHADE_POS = SHVec3{ rp3dPos.x, rp3dPos.y, rp3dPos.z };
|
||||
const SHVec3 SHADE_ROT = SHQuaternion{ rp3dRot.x, rp3dRot.y, rp3dRot.z, rp3dRot.w }.ToEuler();
|
||||
|
||||
auto* tfComponent = SHComponentManager::GetComponent<SHTransformComponent>(ENTITY_ID);
|
||||
tfComponent->SetWorldPosition(SHADE_POS);
|
||||
tfComponent->SetWorldRotation(SHADE_ROT);
|
||||
|
||||
// Cache transforms
|
||||
physicsObject.prevTransform = CURRENT_TF;
|
||||
}
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::SyncRigidBody(SHPhysicsObject const* physicsObject, const SHRigidBodyComponent* comp) noexcept
|
||||
{
|
||||
auto* rigidBody = reinterpret_cast<rp3d::RigidBody*>(physicsObject->rp3dBody);
|
||||
|
||||
const uint16_t RB_FLAGS = comp->dirtyFlags;
|
||||
const size_t NUM_FLAGS = sizeof(RB_FLAGS) * 8U;
|
||||
for (size_t i = 0; i < NUM_FLAGS; ++i)
|
||||
{
|
||||
// Check if current dirty flag has been set to true
|
||||
if (RB_FLAGS & 1U << i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0: // Gravity
|
||||
{
|
||||
rigidBody->enableGravity(comp->IsGravityEnabled());
|
||||
break;
|
||||
}
|
||||
case 1: // Sleeping
|
||||
{
|
||||
rigidBody->setIsAllowedToSleep(comp->IsAllowedToSleep());
|
||||
break;
|
||||
}
|
||||
case 2: // Linear Constraints
|
||||
{
|
||||
SetRP3DLinearConstraints(rigidBody, comp->flags);
|
||||
break;
|
||||
}
|
||||
case 3: // Angular Constraints
|
||||
{
|
||||
SetRP3DAngularConstraints(rigidBody, comp->flags);
|
||||
break;
|
||||
}
|
||||
case 4: // Type
|
||||
{
|
||||
rigidBody->setType(static_cast<rp3d::BodyType>(comp->GetType()));
|
||||
break;
|
||||
}
|
||||
case 5: // Mass
|
||||
{
|
||||
rigidBody->setMass(comp->GetMass());
|
||||
break;
|
||||
}
|
||||
case 6: // Drag
|
||||
{
|
||||
rigidBody->setLinearDamping(comp->GetDrag());
|
||||
break;
|
||||
}
|
||||
case 7: // Angular Drag
|
||||
{
|
||||
rigidBody->setAngularDamping(comp->GetAngularDrag());
|
||||
break;
|
||||
}
|
||||
case 8: // Linear Velocity
|
||||
{
|
||||
const SHVec3& SHADE_VEL = comp->GetLinearVelocity();
|
||||
rp3d::Vector3 RP3D_VEL { SHADE_VEL.x, SHADE_VEL.y, SHADE_VEL.z };
|
||||
|
||||
rigidBody->setLinearVelocity(RP3D_VEL);
|
||||
break;
|
||||
}
|
||||
case 9: // Angular Velocity
|
||||
{
|
||||
const SHVec3& SHADE_VEL = comp->GetAngularVelocity();
|
||||
rp3d::Vector3 RP3D_VEL { SHADE_VEL.x, SHADE_VEL.y, SHADE_VEL.z };
|
||||
|
||||
rigidBody->setAngularVelocity(RP3D_VEL);
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::SetRP3DLinearConstraints(rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept
|
||||
{
|
||||
const rp3d::Vector3 CONSTRAINTS
|
||||
{
|
||||
rbFlags & 1U << 2 ? 0.0f : 1.0f,
|
||||
rbFlags & 1U << 3 ? 0.0f : 1.0f,
|
||||
rbFlags & 1U << 4 ? 0.0f : 1.0f
|
||||
};
|
||||
|
||||
|
||||
rp3dRigidBody->setLinearLockAxisFactor(CONSTRAINTS);
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::SetRP3DAngularConstraints(rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept
|
||||
{
|
||||
const rp3d::Vector3 CONSTRAINTS
|
||||
{
|
||||
rbFlags & 1U << 5 ? 0.0f : 1.0f,
|
||||
rbFlags & 1U << 6 ? 0.0f : 1.0f,
|
||||
rbFlags & 1U << 7 ? 0.0f : 1.0f
|
||||
};
|
||||
|
||||
rp3dRigidBody->setAngularLockAxisFactor(CONSTRAINTS);
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::SyncCollider(SHPhysicsObject const* physicsObject, SHColliderComponent* comp) noexcept
|
||||
{
|
||||
int index = 0;
|
||||
for (auto& [collider, dirty] : comp->colliders)
|
||||
{
|
||||
if (!dirty)
|
||||
continue;
|
||||
|
||||
switch (collider.GetType())
|
||||
{
|
||||
case SHCollider::Type::BOX:
|
||||
{
|
||||
SHBoundingBox* box = reinterpret_cast<SHBoundingBox*>(collider.GetShape());
|
||||
const SHVec3& SHADE_EXTENTS = box->GetHalfExtents();
|
||||
|
||||
rp3d::Vector3 RP3D_EXTENTS { SHADE_EXTENTS.x, SHADE_EXTENTS.y, SHADE_EXTENTS.z };
|
||||
|
||||
auto* rp3dBoxShape = reinterpret_cast<rp3d::BoxShape*>(physicsObject->rp3dBody->getCollider(index)->getCollisionShape());
|
||||
rp3dBoxShape->setHalfExtents(RP3D_EXTENTS);
|
||||
|
||||
if (rp3dBoxShape)
|
||||
{
|
||||
SHLOG_INFO("Updating box things")
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case SHCollider::Type::SPHERE:
|
||||
{
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
|
||||
dirty = false;
|
||||
++index;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace SHADE
|
|
@ -0,0 +1,203 @@
|
|||
/****************************************************************************************
|
||||
* \file SHPhysicsSystem.h
|
||||
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||
* \brief Interface for the Physics System
|
||||
*
|
||||
* \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.
|
||||
****************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <queue>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <reactphysics3d/reactphysics3d.h>
|
||||
|
||||
// Project Headers
|
||||
#include "SHPhysicsObject.h"
|
||||
#include "Components/SHRigidBodyComponent.h"
|
||||
#include "Components/SHColliderComponent.h"
|
||||
|
||||
#include "Scene/SHSceneGraph.h"
|
||||
#include "ECS_Base/System/SHSystemRoutine.h"
|
||||
#include "ECS_Base/System/SHFixedSystemRoutine.h"
|
||||
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
class SH_API SHPhysicsSystem : public SHSystem
|
||||
{
|
||||
public:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
struct WorldSettings
|
||||
{
|
||||
SHVec3 gravity;
|
||||
uint16_t numVelocitySolverIterations;
|
||||
uint16_t numPositionSolverIterations;
|
||||
bool sleepingEnabled;
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constructors & Destructor */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
SHPhysicsSystem();
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Getter Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
[[nodiscard]] double GetFixedDT () const noexcept;
|
||||
|
||||
[[nodiscard]] bool IsSleepingEnabled () const noexcept;
|
||||
|
||||
[[nodiscard]] SHVec3 GetWorldGravity () const noexcept;
|
||||
[[nodiscard]] uint16_t GetNumberVelocityIterations () const noexcept;
|
||||
[[nodiscard]] uint16_t GetNumberPositionIterations () const noexcept;
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Setter Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
void SetFixedDT (double fixedUpdateRate) noexcept;
|
||||
void SetWorldGravity (const SHVec3& gravity) const noexcept;
|
||||
void SetNumberVelocityIterations (uint16_t numVelIterations) const noexcept;
|
||||
void SetNumberPositionIterations (uint16_t numPosIterations) const noexcept;
|
||||
void SetSleepingEnabled (bool enableSleeping) const noexcept;
|
||||
|
||||
void SetWorldSettings (const WorldSettings& settings) const noexcept;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Function Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
void Init () override;
|
||||
void Exit () override;
|
||||
|
||||
void AddRigidBody (EntityID entityID) noexcept;
|
||||
void AddCollider (EntityID entityID) noexcept;
|
||||
void RemoveRigidBody (EntityID entityID) noexcept;
|
||||
void RemoveCollider (EntityID entityID) noexcept;
|
||||
|
||||
void AddForce (EntityID entityID, const SHVec3& force) const noexcept;
|
||||
void AddForceAtLocalPos (EntityID entityID, const SHVec3& force, const SHVec3& localPos) const noexcept;
|
||||
void AddForceAtWorldPos (EntityID entityID, const SHVec3& force, const SHVec3& worldPos) const noexcept;
|
||||
|
||||
void AddRelativeForce (EntityID entityID, const SHVec3& relativeForce) const noexcept;
|
||||
void AddRelativeForceAtLocalPos (EntityID entityID, const SHVec3& relativeForce, const SHVec3& localPos) const noexcept;
|
||||
void AddRelativeForceAtWorldPos (EntityID entityID, const SHVec3& relativeForce, const SHVec3& worldPos) const noexcept;
|
||||
|
||||
void AddTorque (EntityID entityID, const SHVec3& torque) const noexcept;
|
||||
void AddRelativeTorque (EntityID entityID, const SHVec3& relativeTorque) const noexcept;
|
||||
|
||||
void AddCollisionShape (EntityID entityID, SHShape* shape);
|
||||
void RemoveCollisionShape (EntityID entityID, int index);
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* System Routines */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Synchronises RP3D with SHADE
|
||||
*/
|
||||
class SH_API PhysicsPreUpdate : public SHSystemRoutine
|
||||
{
|
||||
public:
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
/* Constructors & Destructor */
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
|
||||
PhysicsPreUpdate();
|
||||
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
/* Function Members */
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
|
||||
void Execute(double dt) noexcept override;
|
||||
};
|
||||
|
||||
class SH_API PhysicsFixedUpdate : public SHFixedSystemRoutine
|
||||
{
|
||||
public:
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
/* Constructors & Destructor */
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
|
||||
PhysicsFixedUpdate();
|
||||
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
/* Function Members */
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
|
||||
void Execute (double dt) noexcept override;
|
||||
};
|
||||
|
||||
class SH_API PhysicsPostUpdate : public SHSystemRoutine
|
||||
{
|
||||
public:
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
/* Constructors & Destructor */
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
|
||||
PhysicsPostUpdate();
|
||||
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
/* Function Members */
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
|
||||
void Execute(double dt) noexcept override;
|
||||
};
|
||||
|
||||
private:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
using EntityObjectMap = std::unordered_map<EntityID, SHPhysicsObject>;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
// TODO(Diren): Store interpFactor
|
||||
|
||||
bool worldUpdated;
|
||||
|
||||
double interpolationFactor;
|
||||
double fixedDT;
|
||||
rp3d::PhysicsWorld* world;
|
||||
|
||||
rp3d::PhysicsCommon factory;
|
||||
EntityObjectMap map;
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Function Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept;
|
||||
|
||||
void SyncRigidBodyComponents (std::vector<SHRigidBodyComponent>& denseArray) noexcept;
|
||||
void SyncColliderComponents (std::vector<SHColliderComponent>& denseArray) noexcept;
|
||||
void SyncTransforms () noexcept;
|
||||
// TODO(Diren): Trigger handling
|
||||
|
||||
static void SyncRigidBody (SHPhysicsObject const* physicsObject, const SHRigidBodyComponent* comp) noexcept;
|
||||
static void SetRP3DLinearConstraints (rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept;
|
||||
static void SetRP3DAngularConstraints (rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept;
|
||||
|
||||
static void SyncCollider (SHPhysicsObject const* physicsObject, SHColliderComponent* comp) noexcept;
|
||||
};
|
||||
|
||||
|
||||
} // namespace SHADE
|
|
@ -8,9 +8,9 @@ namespace SHADE
|
|||
ResourceManager::~ResourceManager()
|
||||
{
|
||||
// Delete all resources libraries
|
||||
for (const auto& deleter : deleters)
|
||||
for (auto iter = deleters.rbegin(); iter != deleters.rend(); ++iter)
|
||||
{
|
||||
deleter();
|
||||
(*iter)();
|
||||
}
|
||||
deleters.clear();
|
||||
}
|
||||
|
|
|
@ -38,3 +38,4 @@
|
|||
|
||||
#include "Common/SHCommonTypes.h"
|
||||
#include "Tools/SHLogger.h"
|
||||
#include "Tools/SHException.h"
|
||||
|
|
|
@ -90,10 +90,15 @@ namespace SHADE
|
|||
#endif
|
||||
|
||||
// Go through the map and release all the nodes
|
||||
for (auto* node : entityNodeMap | std::views::values)
|
||||
ReleaseNode(node);
|
||||
for (auto*& node : entityNodeMap | std::views::values)
|
||||
{
|
||||
delete node;
|
||||
node = nullptr;
|
||||
}
|
||||
|
||||
delete root;
|
||||
entityNodeMap.clear();
|
||||
|
||||
//delete root;
|
||||
|
||||
#ifdef _DEBUG
|
||||
SHLOG_INFO("Scene Graph Destroyed Successfully!")
|
||||
|
|
|
@ -153,6 +153,16 @@ namespace SHADE
|
|||
csEditorRenderScripts(entity);
|
||||
}
|
||||
|
||||
void SHScriptEngine::UndoScriptInspectorChanges() const
|
||||
{
|
||||
csEditorUndo();
|
||||
}
|
||||
|
||||
void SHScriptEngine::RedoScriptInspectorChanges() const
|
||||
{
|
||||
csEditorRedo();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Static Utility Functions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -400,6 +410,18 @@ namespace SHADE
|
|||
DEFAULT_CSHARP_NAMESPACE + ".Editor",
|
||||
"RenderScriptsInInspector"
|
||||
);
|
||||
csEditorUndo = dotNet.GetFunctionPtr<CsFuncPtr>
|
||||
(
|
||||
DEFAULT_CSHARP_LIB_NAME,
|
||||
DEFAULT_CSHARP_NAMESPACE + ".Editor",
|
||||
"Undo"
|
||||
);
|
||||
csEditorRedo = dotNet.GetFunctionPtr<CsFuncPtr>
|
||||
(
|
||||
DEFAULT_CSHARP_LIB_NAME,
|
||||
DEFAULT_CSHARP_NAMESPACE + ".Editor",
|
||||
"Redo"
|
||||
);
|
||||
}
|
||||
|
||||
void SHScriptEngine::registerEvents()
|
||||
|
|
|
@ -171,6 +171,14 @@ namespace SHADE
|
|||
/// </summary>
|
||||
/// <param name="entity">The Entity to render the Scripts of.</param>
|
||||
void RenderScriptsInInspector(EntityID entity) const;
|
||||
/// <summary>
|
||||
/// Performs an undo for script inspector changes if it exists.
|
||||
/// </summary>
|
||||
void UndoScriptInspectorChanges() const;
|
||||
/// <summary>
|
||||
/// Performs a redo for script inspector changes if it exists.
|
||||
/// </summary>
|
||||
void RedoScriptInspectorChanges() const;
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Static Utility Functions */
|
||||
|
@ -243,9 +251,8 @@ namespace SHADE
|
|||
CsScriptSerialiseYamlFuncPtr csScriptDeserialiseYaml = nullptr;
|
||||
// - Editor
|
||||
CsScriptEditorFuncPtr csEditorRenderScripts = nullptr;
|
||||
// Delegates
|
||||
/*ECS::EntityEvent::Delegate onEntityCreate;
|
||||
ECS::EntityEvent::Delegate onEntityDestroy;*/
|
||||
CsFuncPtr csEditorUndo = nullptr;
|
||||
CsFuncPtr csEditorRedo = nullptr;
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Event Handler Functions */
|
||||
|
|
|
@ -75,10 +75,13 @@ namespace SHADE
|
|||
};
|
||||
}
|
||||
|
||||
#define SHASSERT(cond, msg) \
|
||||
if (!(cond)) \
|
||||
{ \
|
||||
SHLOGV_CRITICAL(msg) \
|
||||
std::abort(); \
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define SHASSERT(cond, msg) \
|
||||
if (!(cond)) \
|
||||
{ \
|
||||
SHLOGV_CRITICAL(msg) \
|
||||
std::abort(); \
|
||||
}
|
||||
#else
|
||||
#define SHASSERT(cond, msg) { }
|
||||
#endif
|
||||
|
|
|
@ -31,6 +31,7 @@ project "SHADE_Managed"
|
|||
"%{IncludeDir.imnodes}",
|
||||
"%{IncludeDir.yamlcpp}",
|
||||
"%{IncludeDir.RTTR}/include",
|
||||
"%{IncludeDir.dotnet}\\include",
|
||||
"%{wks.location}/SHADE_Engine/src"
|
||||
}
|
||||
|
||||
|
@ -85,3 +86,8 @@ project "SHADE_Managed"
|
|||
optimize "On"
|
||||
defines{"_RELEASE"}
|
||||
links{"librttr_core.lib"}
|
||||
|
||||
filter "configurations:Publish"
|
||||
optimize "On"
|
||||
defines{"_RELEASE"}
|
||||
links{"librttr_core.lib"}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Sep 27, 2022
|
||||
\brief Contains the definition of the functions for the ScriptStore managed
|
||||
\brief Contains the definition of the functions for the Editor managed
|
||||
static class.
|
||||
|
||||
Note: This file is written in C++17/CLI.
|
||||
|
@ -16,6 +16,8 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include "SHpch.h"
|
||||
// Primary Header
|
||||
#include "Editor/Editor.hxx"
|
||||
// STL Includes
|
||||
#include <memory>
|
||||
// External Dependencies
|
||||
#include "Editor/SHEditorUI.h"
|
||||
// Project Headers
|
||||
|
@ -25,6 +27,8 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include "Utility/Debug.hxx"
|
||||
#include "Serialisation/ReflectionUtilities.hxx"
|
||||
#include "Editor/IconsMaterialDesign.h"
|
||||
#include "Editor/Command/SHCommandManager.h"
|
||||
#include "Editor/Command/SHCommand.hpp"
|
||||
|
||||
// Using Directives
|
||||
using namespace System;
|
||||
|
@ -48,9 +52,11 @@ using namespace System::Collections::Generic;
|
|||
(field->FieldType == MANAGED_TYPE::typeid) \
|
||||
{ \
|
||||
NATIVE_TYPE val = safe_cast<NATIVE_TYPE>(field->GetValue(object)); \
|
||||
NATIVE_TYPE oldVal = val; \
|
||||
if (SHEditorUI::FUNC(Convert::ToNative(field->Name), val)) \
|
||||
{ \
|
||||
field->SetValue(object, val); \
|
||||
registerUndoAction(object, field, val, oldVal); \
|
||||
} \
|
||||
} \
|
||||
/// <summary>
|
||||
|
@ -69,9 +75,11 @@ using namespace System::Collections::Generic;
|
|||
(field->FieldType == MANAGED_TYPE::typeid) \
|
||||
{ \
|
||||
NATIVE_TYPE val = Convert::ToNative(safe_cast<MANAGED_TYPE>(field->GetValue(object))); \
|
||||
NATIVE_TYPE oldVal = val; \
|
||||
if (SHEditorUI::FUNC(Convert::ToNative(field->Name), val)) \
|
||||
{ \
|
||||
field->SetValue(object, Convert::ToCLI(val)); \
|
||||
registerUndoAction(object, field, Convert::ToCLI(val), Convert::ToCLI(oldVal)); \
|
||||
} \
|
||||
} \
|
||||
|
||||
|
@ -105,26 +113,43 @@ namespace SHADE
|
|||
SAFE_NATIVE_CALL_END_N("SHADE_Managed.Editor.RenderScriptsInInspector")
|
||||
}
|
||||
|
||||
void Editor::RenderScriptAddButton(Entity entity)
|
||||
{
|
||||
// Get list of Scripts
|
||||
auto scriptTypes = ScriptStore::GetAvailableScriptList();
|
||||
void Editor::RenderScriptAddButton(Entity entity)
|
||||
{
|
||||
// Get list of Scripts
|
||||
auto scriptTypes = ScriptStore::GetAvailableScriptList();
|
||||
|
||||
// Define pop up
|
||||
if (SHEditorUI::BeginMenu("Add Script", ICON_MD_LIBRARY_ADD))
|
||||
{
|
||||
for each (Type ^ type in scriptTypes)
|
||||
{
|
||||
if (SHEditorUI::Selectable(Convert::ToNative(type->Name)))
|
||||
{
|
||||
// Add the script
|
||||
ScriptStore::AddScriptViaName(entity, type->Name);
|
||||
}
|
||||
}
|
||||
// Define pop up
|
||||
if (SHEditorUI::BeginMenu("Add Script", ICON_MD_LIBRARY_ADD))
|
||||
{
|
||||
for each (Type ^ type in scriptTypes)
|
||||
{
|
||||
if (SHEditorUI::Selectable(Convert::ToNative(type->Name)))
|
||||
{
|
||||
// Add the script
|
||||
ScriptStore::AddScriptViaName(entity, type->Name);
|
||||
}
|
||||
}
|
||||
|
||||
SHEditorUI::EndMenu();
|
||||
}
|
||||
}
|
||||
SHEditorUI::EndMenu();
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* UndoRedoStack Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
void Editor::Undo()
|
||||
{
|
||||
SAFE_NATIVE_CALL_BEGIN
|
||||
actionStack.Undo();
|
||||
SAFE_NATIVE_CALL_END_N("SHADE_Managed.Editor.Undo")
|
||||
}
|
||||
|
||||
void Editor::Redo()
|
||||
{
|
||||
SAFE_NATIVE_CALL_BEGIN
|
||||
actionStack.Redo();
|
||||
SAFE_NATIVE_CALL_END_N("SHADE_Managed.Editor.Redo")
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Helper Functions */
|
||||
|
@ -192,9 +217,11 @@ namespace SHADE
|
|||
}
|
||||
|
||||
int val = safe_cast<int>(field->GetValue(object));
|
||||
int oldVal = val;
|
||||
if (SHEditorUI::InputEnumCombo(Convert::ToNative(field->Name), val, nativeEnumNames))
|
||||
{
|
||||
field->SetValue(object, val);
|
||||
registerUndoAction(object, field, val, oldVal);
|
||||
}
|
||||
}
|
||||
else if RENDER_FIELD_CASTED(Vector2, SHVec2, InputVec2)
|
||||
|
@ -210,9 +237,11 @@ namespace SHADE
|
|||
|
||||
// Actual Field
|
||||
std::string val = Convert::ToNative(stringVal);
|
||||
std::string oldVal = val;
|
||||
if (SHEditorUI::InputTextField(Convert::ToNative(field->Name), val))
|
||||
{
|
||||
field->SetValue(object, Convert::ToCLI(val));
|
||||
registerUndoAction(object, field, Convert::ToCLI(val), Convert::ToCLI(oldVal));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -231,4 +260,18 @@ namespace SHADE
|
|||
}
|
||||
}
|
||||
|
||||
void Editor::registerUndoAction(System::Object^ object, System::Reflection::FieldInfo^ field, System::Object^ newData, System::Object^ oldData)
|
||||
{
|
||||
// Create command and add it into the undo stack
|
||||
UndoRedoStack::Command cmd;
|
||||
cmd.Field = field;
|
||||
cmd.Object = object;
|
||||
cmd.NewData = newData;
|
||||
cmd.OldData = oldData;
|
||||
actionStack.Add(cmd);
|
||||
|
||||
// Inform the C++ Undo-Redo stack
|
||||
SHCommandManager::RegisterCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCLICommand>()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ of DigiPen Institute of Technology is prohibited.
|
|||
// Project Includes
|
||||
#include "Engine/Entity.hxx"
|
||||
#include "Scripts/Script.hxx"
|
||||
#include "UndoRedoStack.hxx"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -36,15 +37,26 @@ namespace SHADE
|
|||
/// rendering code.
|
||||
/// </summary>
|
||||
/// <param name="entity">The Entity to render the Scripts of.</param>
|
||||
static void RenderScriptsInInspector(Entity entity);
|
||||
/// <summary>
|
||||
/// Renders a dropdown button that allows for the addition of PlushieScripts
|
||||
/// onto the specified Entity.
|
||||
/// </summary>
|
||||
/// <param name="entity">The Entity to add PlushieScripts to.</param>
|
||||
static void RenderScriptAddButton(Entity entity);
|
||||
static void RenderScriptsInInspector(Entity entity);
|
||||
/// <summary>
|
||||
/// Renders a dropdown button that allows for the addition of PlushieScripts
|
||||
/// onto the specified Entity.
|
||||
/// </summary>
|
||||
/// <param name="entity">The Entity to add PlushieScripts to.</param>
|
||||
static void RenderScriptAddButton(Entity entity);
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* UndoRedoStack Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
static void Undo();
|
||||
static void Redo();
|
||||
|
||||
private:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
static UndoRedoStack actionStack;
|
||||
|
||||
private:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Helper Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
@ -73,5 +85,6 @@ namespace SHADE
|
|||
/// <param name="entity">The Entity to render the Scripts of.</param>
|
||||
/// <param name="script">The Script to render the inspector for.</param>
|
||||
static void renderScriptContextMenu(Entity entity, Script^ script);
|
||||
static void registerUndoAction(System::Object^ object, System::Reflection::FieldInfo^ field, System::Object^ newData, System::Object^ oldData);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/************************************************************************************//*!
|
||||
\file UndoRedoStack.cxx
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Sep 29, 2022
|
||||
\brief Contains the definition of the functions for the UndoRedoStack managed
|
||||
class.
|
||||
|
||||
Note: This file is written in C++17/CLI.
|
||||
|
||||
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.
|
||||
*//*************************************************************************************/
|
||||
// Precompiled Headers
|
||||
#include "SHpch.h"
|
||||
// Primary Header
|
||||
#include "UndoRedoStack.hxx"
|
||||
// External Dependencies
|
||||
#include "Editor/SHEditorUI.h"
|
||||
// Project Headers
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
bool UndoRedoStack::UndoActionPresent::get()
|
||||
{
|
||||
return commandStack->Count > 0 && latestActionIndex >= 0;
|
||||
}
|
||||
|
||||
bool UndoRedoStack::RedoActionPresent::get()
|
||||
{
|
||||
return latestActionIndex >= 0 && latestActionIndex < commandStack->Count - 1;
|
||||
}
|
||||
|
||||
void UndoRedoStack::Add(Command command)
|
||||
{
|
||||
// Erase any other actions ahead of the current action
|
||||
if (latestActionIndex >= 0 && latestActionIndex < commandStack->Count - 1)
|
||||
{
|
||||
commandStack->RemoveRange(latestActionIndex, commandStack->Count - latestActionIndex);
|
||||
}
|
||||
|
||||
// Add the command
|
||||
commandStack->Add(command);
|
||||
|
||||
// Set the latest command
|
||||
latestActionIndex = commandStack->Count - 1;
|
||||
}
|
||||
|
||||
void UndoRedoStack::Undo()
|
||||
{
|
||||
if (!UndoActionPresent)
|
||||
return;
|
||||
|
||||
Command cmd = commandStack[latestActionIndex];
|
||||
cmd.Field->SetValue(cmd.Object, cmd.OldData);
|
||||
--latestActionIndex;
|
||||
}
|
||||
|
||||
void UndoRedoStack::Redo()
|
||||
{
|
||||
if (!RedoActionPresent)
|
||||
return;
|
||||
|
||||
Command cmd = commandStack[latestActionIndex];
|
||||
cmd.Field->SetValue(cmd.Object, cmd.NewData);
|
||||
++latestActionIndex;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/************************************************************************************//*!
|
||||
\file UndoRedoStack.hxx
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Sep 29, 2022
|
||||
\brief Contains the definition of the managed UndoRedoStack class.
|
||||
|
||||
Note: This file is written in C++17/CLI.
|
||||
|
||||
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.
|
||||
*//*************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/// <summary>
|
||||
/// Class that is able to store a stack of actions that can be done and redone.
|
||||
/// </summary>
|
||||
private ref class UndoRedoStack sealed
|
||||
{
|
||||
public:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Command for the stack that represents a data modification.
|
||||
/// </summary>
|
||||
value struct Command
|
||||
{
|
||||
public:
|
||||
System::Object^ Object;
|
||||
System::Reflection::FieldInfo^ Field;
|
||||
System::Object^ NewData;
|
||||
System::Object^ OldData;
|
||||
};
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Properties */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// True if there is an undoable action in the stack.
|
||||
/// </summary>
|
||||
property bool UndoActionPresent { bool get(); }
|
||||
/// <summary>
|
||||
/// True if there is a redoable action in the stack.
|
||||
/// </summary>
|
||||
property bool RedoActionPresent { bool get(); }
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Usage Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Adds a command onto the stack.
|
||||
/// </summary>
|
||||
/// <param name="command"></param>
|
||||
void Add(Command command);
|
||||
/// <summary>
|
||||
/// Undos the last added command if it exists.
|
||||
/// </summary>
|
||||
void Undo();
|
||||
/// <summary>
|
||||
/// Redoes the last undo-ed command if it exists.
|
||||
/// </summary>
|
||||
void Redo();
|
||||
|
||||
private:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
int latestActionIndex = -1;
|
||||
System::Collections::Generic::List<Command>^ commandStack = gcnew System::Collections::Generic::List<Command>();
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue