Merge remote-tracking branch 'origin/main' into SP3-1-Rendering
This commit is contained in:
parent
73be299aae
commit
ebc94225e7
|
@ -0,0 +1,17 @@
|
||||||
|
#version 450
|
||||||
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
|
#extension GL_ARB_shading_language_420pack : enable
|
||||||
|
#extension GL_EXT_nonuniform_qualifier : require
|
||||||
|
|
||||||
|
layout(location = 0) in struct
|
||||||
|
{
|
||||||
|
vec4 vertColor;
|
||||||
|
} In;
|
||||||
|
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 outColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
outColor = In.vertColor;
|
||||||
|
}
|
Binary file not shown.
|
@ -0,0 +1,3 @@
|
||||||
|
Name: DebugDraw_FS
|
||||||
|
ID: 36671027
|
||||||
|
Type: 2
|
|
@ -0,0 +1,24 @@
|
||||||
|
#version 450
|
||||||
|
#extension GL_KHR_vulkan_glsl : enable
|
||||||
|
|
||||||
|
layout(location = 0) in vec4 aVertexPos;
|
||||||
|
layout(location = 1) in vec4 aVertColor;
|
||||||
|
|
||||||
|
|
||||||
|
layout(location = 0) out struct
|
||||||
|
{
|
||||||
|
vec4 vertColor; // location 0
|
||||||
|
|
||||||
|
} Out;
|
||||||
|
|
||||||
|
layout(set = 2, binding = 0) uniform CameraData
|
||||||
|
{
|
||||||
|
vec4 position;
|
||||||
|
mat4 vpMat;
|
||||||
|
} cameraData;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = cameraData.vpMat * vec4 (aVertexPos.xyz, 1.0f);
|
||||||
|
Out.vertColor = aVertColor;
|
||||||
|
}
|
Binary file not shown.
|
@ -0,0 +1,3 @@
|
||||||
|
Name: DebugDraw_VS
|
||||||
|
ID: 48002439
|
||||||
|
Type: 2
|
Binary file not shown.
|
@ -1,3 +1,3 @@
|
||||||
Name: DeferredComposite_CS
|
Name: DeferredComposite_CS
|
||||||
ID: 42814284
|
ID: 45072428
|
||||||
Type: 2
|
Type: 2
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,3 +1,3 @@
|
||||||
Name: TestCube_FS
|
Name: TestCube_FS
|
||||||
ID: 37450402
|
ID: 46377769
|
||||||
Type: 2
|
Type: 2
|
||||||
|
|
Binary file not shown.
|
@ -1,3 +1,3 @@
|
||||||
Name: TestCube_VS
|
Name: TestCube_VS
|
||||||
ID: 41688429
|
ID: 39210065
|
||||||
Type: 2
|
Type: 2
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
//#define SHEDITOR
|
//#define SHEDITOR
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
#include "Editor/SHEditor.hpp"
|
#include "Editor/SHEditor.h"
|
||||||
//#include "Scenes/SBEditorScene.h"
|
//#include "Scenes/SBEditorScene.h"
|
||||||
#endif // SHEDITOR
|
#endif // SHEDITOR
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@
|
||||||
#include "FRC/SHFramerateController.h"
|
#include "FRC/SHFramerateController.h"
|
||||||
#include "AudioSystem/SHAudioSystem.h"
|
#include "AudioSystem/SHAudioSystem.h"
|
||||||
#include "Camera/SHCameraSystem.h"
|
#include "Camera/SHCameraSystem.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h"
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||||
|
@ -42,6 +43,7 @@
|
||||||
#include "Assets/SHAssetManager.h"
|
#include "Assets/SHAssetManager.h"
|
||||||
|
|
||||||
#include "Tools/SHLogger.h"
|
#include "Tools/SHLogger.h"
|
||||||
|
#include "Tools/SHDebugDraw.h"
|
||||||
|
|
||||||
using namespace SHADE;
|
using namespace SHADE;
|
||||||
|
|
||||||
|
@ -69,6 +71,7 @@ namespace Sandbox
|
||||||
SHGraphicsSystem* graphicsSystem = static_cast<SHGraphicsSystem*>(SHSystemManager::GetSystem<SHGraphicsSystem>());
|
SHGraphicsSystem* graphicsSystem = static_cast<SHGraphicsSystem*>(SHSystemManager::GetSystem<SHGraphicsSystem>());
|
||||||
SHSystemManager::CreateSystem<SHAudioSystem>();
|
SHSystemManager::CreateSystem<SHAudioSystem>();
|
||||||
SHSystemManager::CreateSystem<SHCameraSystem>();
|
SHSystemManager::CreateSystem<SHCameraSystem>();
|
||||||
|
SHSystemManager::CreateSystem<SHDebugDrawSystem>();
|
||||||
|
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
SDL_Init(SDL_INIT_VIDEO);
|
SDL_Init(SDL_INIT_VIDEO);
|
||||||
|
@ -90,11 +93,12 @@ namespace Sandbox
|
||||||
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPostUpdate>();
|
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPostUpdate>();
|
||||||
|
|
||||||
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformPostPhysicsUpdate>();
|
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformPostPhysicsUpdate>();
|
||||||
|
SHSystemManager::RegisterRoutine<SHDebugDrawSystem, SHDebugDrawSystem::ProcessPointsRoutine>();
|
||||||
|
|
||||||
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BatcherDispatcherRoutine>();
|
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BatcherDispatcherRoutine>();
|
||||||
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BeginRoutine>();
|
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BeginRoutine>();
|
||||||
|
|
||||||
SHSystemManager::RegisterRoutine<SHCameraSystem, SHCameraSystem::EditorCameraUpdate>();
|
//SHSystemManager::RegisterRoutine<SHCameraSystem, SHCameraSystem::EditorCameraUpdate>();
|
||||||
SHSystemManager::RegisterRoutine<SHCameraSystem, SHCameraSystem::CameraSystemUpdate>();
|
SHSystemManager::RegisterRoutine<SHCameraSystem, SHCameraSystem::CameraSystemUpdate>();
|
||||||
|
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
|
@ -108,13 +112,10 @@ namespace Sandbox
|
||||||
SHComponentManager::CreateComponentSparseSet<SHColliderComponent>();
|
SHComponentManager::CreateComponentSparseSet<SHColliderComponent>();
|
||||||
SHComponentManager::CreateComponentSparseSet<SHTransformComponent>();
|
SHComponentManager::CreateComponentSparseSet<SHTransformComponent>();
|
||||||
SHComponentManager::CreateComponentSparseSet<SHRenderable>();
|
SHComponentManager::CreateComponentSparseSet<SHRenderable>();
|
||||||
SHComponentManager::CreateComponentSparseSet<SHCameraComponent>();
|
//SHComponentManager::CreateComponentSparseSet<SHCameraComponent>();
|
||||||
|
|
||||||
SHAssetManager::Load();
|
SHAssetManager::Load();
|
||||||
|
|
||||||
auto id = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>();
|
|
||||||
auto id2 = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>();
|
|
||||||
auto id3 = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>();
|
|
||||||
|
|
||||||
SHSystemManager::RegisterRoutine<SHAudioSystem, SHAudioSystem::AudioRoutine>();
|
SHSystemManager::RegisterRoutine<SHAudioSystem, SHAudioSystem::AudioRoutine>();
|
||||||
|
|
||||||
|
@ -126,6 +127,9 @@ namespace Sandbox
|
||||||
SHSceneManager::InitSceneManager<SBTestScene>("TestScene");
|
SHSceneManager::InitSceneManager<SBTestScene>("TestScene");
|
||||||
|
|
||||||
SHFrameRateController::UpdateFRC();
|
SHFrameRateController::UpdateFRC();
|
||||||
|
|
||||||
|
// Link up SHDebugDraw
|
||||||
|
SHDebugDraw::Init(SHSystemManager::GetSystem<SHDebugDrawSystem>());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SBApplication::Update(void)
|
void SBApplication::Update(void)
|
||||||
|
|
|
@ -16,7 +16,10 @@
|
||||||
|
|
||||||
#include "Assets/SHAssetManager.h"
|
#include "Assets/SHAssetManager.h"
|
||||||
#include "Camera/SHCameraComponent.h"
|
#include "Camera/SHCameraComponent.h"
|
||||||
|
#include "Math/SHColour.h"
|
||||||
#include "Resource/SHResourceManager.h"
|
#include "Resource/SHResourceManager.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h"
|
||||||
|
#include "Tools/SHDebugDraw.h"
|
||||||
|
|
||||||
using namespace SHADE;
|
using namespace SHADE;
|
||||||
|
|
||||||
|
@ -128,7 +131,6 @@ namespace Sandbox
|
||||||
floorRigidBody.SetType(SHRigidBodyComponent::Type::STATIC);
|
floorRigidBody.SetType(SHRigidBodyComponent::Type::STATIC);
|
||||||
|
|
||||||
auto* floorBox = floorCollider.AddBoundingBox();
|
auto* floorBox = floorCollider.AddBoundingBox();
|
||||||
floorBox->SetHalfExtents(floorTransform.GetWorldScale() * 0.5f);
|
|
||||||
|
|
||||||
// Create blank entity with a script
|
// Create blank entity with a script
|
||||||
//testObj = SHADE::SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
//testObj = SHADE::SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
||||||
|
@ -160,7 +162,7 @@ namespace Sandbox
|
||||||
SHComponentManager::RemoveComponent <SHColliderComponent>(0);
|
SHComponentManager::RemoveComponent <SHColliderComponent>(0);
|
||||||
|
|
||||||
auto ambientLight = SHEntityManager::CreateEntity<SHLightComponent>();
|
auto ambientLight = SHEntityManager::CreateEntity<SHLightComponent>();
|
||||||
SHComponentManager::GetComponent<SHLightComponent>(ambientLight)->SetColor(SHVec4(1.0f, 1.0f, 1.0f, 1.0f));
|
SHComponentManager::GetComponent<SHLightComponent>(ambientLight)->SetColor(SHColour::WHITE);
|
||||||
SHComponentManager::GetComponent<SHLightComponent>(ambientLight)->SetStrength(0.25f);
|
SHComponentManager::GetComponent<SHLightComponent>(ambientLight)->SetStrength(0.25f);
|
||||||
SHComponentManager::GetComponent<SHLightComponent>(ambientLight)->SetType(SH_LIGHT_TYPE::AMBIENT);
|
SHComponentManager::GetComponent<SHLightComponent>(ambientLight)->SetType(SH_LIGHT_TYPE::AMBIENT);
|
||||||
}
|
}
|
||||||
|
@ -187,6 +189,8 @@ namespace Sandbox
|
||||||
SHADE::SHScriptEngine* scriptEngine = static_cast<SHADE::SHScriptEngine*>(SHADE::SHSystemManager::GetSystem<SHADE::SHScriptEngine>());
|
SHADE::SHScriptEngine* scriptEngine = static_cast<SHADE::SHScriptEngine*>(SHADE::SHSystemManager::GetSystem<SHADE::SHScriptEngine>());
|
||||||
scriptEngine->RemoveAllScripts(testObj);
|
scriptEngine->RemoveAllScripts(testObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHDebugDraw::Cube(SHColour::CRIMSON, SHVec3(1.0f, 0.0f, 0.0f), SHVec3(1.0f, 1.0f, 1.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SBTestScene::Render()
|
void SBTestScene::Render()
|
||||||
|
|
|
@ -8,7 +8,7 @@ project "SHADE_Engine"
|
||||||
pchheader "SHpch.h"
|
pchheader "SHpch.h"
|
||||||
pchsource "%{prj.location}/src/SHpch.cpp"
|
pchsource "%{prj.location}/src/SHpch.cpp"
|
||||||
staticruntime "off"
|
staticruntime "off"
|
||||||
|
buildoptions{"/bigobj"}
|
||||||
files
|
files
|
||||||
{
|
{
|
||||||
"%{prj.location}/src/**.h",
|
"%{prj.location}/src/**.h",
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <vulkan/vulkan.hpp>
|
||||||
#include "SHAssetData.h"
|
#include "SHAssetData.h"
|
||||||
#include "SH_API.h"
|
#include "SH_API.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -17,12 +18,14 @@
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
//! Tighter control over types of shaders. Maps directly to their
|
||||||
|
//! equivalent vk::ShaderStageFlagBits.
|
||||||
enum class SH_SHADER_TYPE : uint8_t
|
enum class SH_SHADER_TYPE : uint8_t
|
||||||
{
|
{
|
||||||
VERTEX,
|
VERTEX = static_cast<uint8_t>(vk::ShaderStageFlagBits::eVertex),
|
||||||
FRAGMENT,
|
FRAGMENT = static_cast<uint8_t>(vk::ShaderStageFlagBits::eFragment),
|
||||||
COMPUTE,
|
COMPUTE = static_cast<uint8_t>(vk::ShaderStageFlagBits::eCompute),
|
||||||
INAVLID_TYPE
|
INAVLID_TYPE = std::numeric_limits<uint8_t>::max()
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SH_API SHShaderAsset : SHAssetData
|
struct SH_API SHShaderAsset : SHAssetData
|
||||||
|
|
|
@ -101,9 +101,10 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
for (auto i { 0 }; i < SHADER_TYPE_MAX_COUNT; ++i)
|
for (auto i { 0 }; i < SHADER_TYPE_MAX_COUNT; ++i)
|
||||||
{
|
{
|
||||||
if (name.find(SHADER_IDENTIFIERS[i].data()) != std::string::npos)
|
const auto& [SHADER_SUFFIX, SHADER_TYPE] = SHADER_IDENTIFIERS[i];
|
||||||
|
if (name.find(SHADER_SUFFIX.data()) != std::string::npos)
|
||||||
{
|
{
|
||||||
return static_cast<SH_SHADER_TYPE>(i);
|
return SHADER_TYPE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "SHAssetLoader.h"
|
#include "SHAssetLoader.h"
|
||||||
|
|
||||||
|
#include "Assets/Asset Types/SHPrefabAsset.h"
|
||||||
|
#include "Assets/Asset Types/SHSceneAsset.h"
|
||||||
|
#include "Assets/Asset Types/SHMaterialAsset.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
struct SHTextBasedLoader : SHAssetLoader
|
struct SHTextBasedLoader : SHAssetLoader
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include "Asset Types/SHShaderAsset.h"
|
||||||
|
|
||||||
// FMOD Fwd Declare
|
// FMOD Fwd Declare
|
||||||
namespace FMOD
|
namespace FMOD
|
||||||
|
@ -113,10 +114,10 @@ constexpr std::string_view VERTEX_SHADER{ "_VS" };
|
||||||
constexpr std::string_view FRAGMENT_SHADER{ "_FS" };
|
constexpr std::string_view FRAGMENT_SHADER{ "_FS" };
|
||||||
constexpr std::string_view COMPUTER_SHADER{ "_CS" };
|
constexpr std::string_view COMPUTER_SHADER{ "_CS" };
|
||||||
|
|
||||||
constexpr std::string_view SHADER_IDENTIFIERS[] = {
|
constexpr std::pair<std::string_view, SHADE::SH_SHADER_TYPE> SHADER_IDENTIFIERS[] = {
|
||||||
VERTEX_SHADER,
|
std::make_pair(VERTEX_SHADER, SHADE::SH_SHADER_TYPE::VERTEX),
|
||||||
FRAGMENT_SHADER,
|
std::make_pair(FRAGMENT_SHADER, SHADE::SH_SHADER_TYPE::FRAGMENT),
|
||||||
COMPUTER_SHADER
|
std::make_pair(COMPUTER_SHADER, SHADE::SH_SHADER_TYPE::COMPUTE)
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr size_t SHADER_TYPE_MAX_COUNT{ 3 };
|
constexpr size_t SHADER_TYPE_MAX_COUNT{ 3 };
|
||||||
|
|
|
@ -151,19 +151,23 @@ namespace SHADE
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
AssetID SHAssetManager::CreateNewAsset(AssetType type, AssetName name) noexcept
|
AssetID SHAssetManager::CreateNewAsset(AssetType type, AssetName name) noexcept
|
||||||
{
|
{
|
||||||
|
SHAssetData* data = nullptr;
|
||||||
std::string newPath{ ASSET_ROOT };
|
std::string newPath{ ASSET_ROOT };
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case AssetType::PREFAB:
|
case AssetType::PREFAB:
|
||||||
newPath += PREFAB_FOLDER;
|
newPath += PREFAB_FOLDER;
|
||||||
|
data = new SHPrefabAsset();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AssetType::SCENE:
|
case AssetType::SCENE:
|
||||||
newPath += SCENE_FOLDER;
|
newPath += SCENE_FOLDER;
|
||||||
|
data = new SHSceneAsset();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AssetType::MATERIAL:
|
case AssetType::MATERIAL:
|
||||||
newPath += MATERIAL_FOLDER;
|
newPath += MATERIAL_FOLDER;
|
||||||
|
data = new SHMaterialAsset();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -189,6 +193,8 @@ namespace SHADE
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
assetData.emplace(id, data);
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHCameraArmComponent.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
|
||||||
|
SHCameraArmComponent::SHCameraArmComponent()
|
||||||
|
:pitch(0.0f), yaw(0.0f), armLength(1.0f),offset(), dirty(true), lookAtCameraOrigin(true)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SHVec3 const& SHCameraArmComponent::GetOffset() const noexcept
|
||||||
|
{
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
float SHCameraArmComponent::GetPitch() const noexcept
|
||||||
|
{
|
||||||
|
return pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
float SHCameraArmComponent::GetYaw() const noexcept
|
||||||
|
{
|
||||||
|
return yaw;
|
||||||
|
}
|
||||||
|
|
||||||
|
float SHCameraArmComponent::GetArmLength() const noexcept
|
||||||
|
{
|
||||||
|
return armLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHCameraArmComponent::SetPitch(float pitch) noexcept
|
||||||
|
{
|
||||||
|
this->pitch = pitch;
|
||||||
|
dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHCameraArmComponent::SetYaw(float yaw) noexcept
|
||||||
|
{
|
||||||
|
this->yaw = yaw;
|
||||||
|
dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHCameraArmComponent::SetArmLength(float length) noexcept
|
||||||
|
{
|
||||||
|
this->armLength = length;
|
||||||
|
dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}//namespace SHADE
|
||||||
|
|
||||||
|
|
||||||
|
RTTR_REGISTRATION
|
||||||
|
{
|
||||||
|
using namespace SHADE;
|
||||||
|
using namespace rttr;
|
||||||
|
|
||||||
|
registration::class_<SHCameraArmComponent>("Camera Arm Component")
|
||||||
|
.property("Arm Pitch", &SHCameraArmComponent::GetPitch, &SHCameraArmComponent::SetPitch)
|
||||||
|
.property("Arm Yaw", &SHCameraArmComponent::GetYaw, &SHCameraArmComponent::SetYaw)
|
||||||
|
.property("Arm Length", &SHCameraArmComponent::GetArmLength, &SHCameraArmComponent::SetArmLength)
|
||||||
|
.property("Look At Camera Origin", &SHCameraArmComponent::lookAtCameraOrigin);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
#include <rttr/registration>
|
||||||
|
#include "ECS_Base/Components/SHComponent.h"
|
||||||
|
#include "Math/SHMatrix.h"
|
||||||
|
#include "SH_API.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SH_API SHCameraArmComponent final: public SHComponent
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
float pitch;
|
||||||
|
float yaw;
|
||||||
|
float armLength;
|
||||||
|
|
||||||
|
bool dirty;
|
||||||
|
SHVec3 offset;
|
||||||
|
|
||||||
|
public:
|
||||||
|
friend class SHCameraSystem;
|
||||||
|
SHCameraArmComponent();
|
||||||
|
virtual ~SHCameraArmComponent() = default;
|
||||||
|
|
||||||
|
bool lookAtCameraOrigin;
|
||||||
|
//Getters
|
||||||
|
//SHMatrix const& GetMatrix() const noexcept;
|
||||||
|
SHVec3 const& GetOffset() const noexcept;
|
||||||
|
float GetPitch() const noexcept;
|
||||||
|
float GetYaw() const noexcept;
|
||||||
|
float GetArmLength() const noexcept;
|
||||||
|
|
||||||
|
//Setters
|
||||||
|
void SetPitch(float pitch) noexcept;
|
||||||
|
void SetYaw(float yaw) noexcept;
|
||||||
|
void SetArmLength(float length) noexcept;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}//namespace SHADE
|
|
@ -13,7 +13,7 @@ namespace SHADE
|
||||||
, width(1920.0f), height(1080.0f), zNear(0.01f), zFar(10000.0f), fov(90.0f), movementSpeed(1.0f), turnSpeed(0.5f)
|
, width(1920.0f), height(1080.0f), zNear(0.01f), zFar(10000.0f), fov(90.0f), movementSpeed(1.0f), turnSpeed(0.5f)
|
||||||
, perspProj(true), dirtyView(true), dirtyProj(true)
|
, perspProj(true), dirtyView(true), dirtyProj(true)
|
||||||
, viewMatrix(), projMatrix()
|
, viewMatrix(), projMatrix()
|
||||||
, position()
|
, position(), offset()
|
||||||
{
|
{
|
||||||
ComponentFamily::GetID<SHCameraComponent>();
|
ComponentFamily::GetID<SHCameraComponent>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace SHADE
|
||||||
SHVec3 position;
|
SHVec3 position;
|
||||||
|
|
||||||
bool perspProj;
|
bool perspProj;
|
||||||
|
SHVec3 offset;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ namespace SHADE
|
||||||
friend class SHCameraSystem;
|
friend class SHCameraSystem;
|
||||||
|
|
||||||
SHCameraComponent();
|
SHCameraComponent();
|
||||||
~SHCameraComponent();
|
virtual ~SHCameraComponent();
|
||||||
|
|
||||||
|
|
||||||
//Getters and setters.
|
//Getters and setters.
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "SHpch.h"
|
#include "SHpch.h"
|
||||||
#include "SHCameraDirector.h"
|
#include "SHCameraDirector.h"
|
||||||
#include "SHCameraComponent.h"
|
#include "SHCameraComponent.h"
|
||||||
|
#include "SHCameraArmComponent.h"
|
||||||
#include "ECS_Base/Managers/SHComponentManager.h"
|
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||||
#include "ECS_Base/SHECSMacros.h"
|
#include "ECS_Base/SHECSMacros.h"
|
||||||
#include "ECS_Base/Managers/SHEntityManager.h"
|
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||||
|
@ -48,6 +49,7 @@ namespace SHADE
|
||||||
viewMatrix = camComponent->GetViewMatrix();
|
viewMatrix = camComponent->GetViewMatrix();
|
||||||
projMatrix = camComponent->GetProjMatrix();
|
projMatrix = camComponent->GetProjMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCameraDirector::SetMainCamera(SHCameraComponent& camera) noexcept
|
void SHCameraDirector::SetMainCamera(SHCameraComponent& camera) noexcept
|
||||||
|
|
|
@ -22,6 +22,7 @@ namespace SHADE
|
||||||
EntityID mainCameraEID;
|
EntityID mainCameraEID;
|
||||||
EntityID transitionCameraEID;
|
EntityID transitionCameraEID;
|
||||||
|
|
||||||
|
|
||||||
SHMatrix GetViewMatrix() const noexcept;
|
SHMatrix GetViewMatrix() const noexcept;
|
||||||
SHMatrix GetProjMatrix() const noexcept;
|
SHMatrix GetProjMatrix() const noexcept;
|
||||||
SHMatrix GetVPMatrix() const noexcept;
|
SHMatrix GetVPMatrix() const noexcept;
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
#include "SHpch.h"
|
#include "SHpch.h"
|
||||||
#include "SHCameraSystem.h"
|
#include "SHCameraSystem.h"
|
||||||
|
#include "SHCameraArmComponent.h"
|
||||||
#include "Math/SHMathHelpers.h"
|
#include "Math/SHMathHelpers.h"
|
||||||
#include "Input/SHInputManager.h"
|
#include "Input/SHInputManager.h"
|
||||||
#include "Math/Vector/SHVec2.h"
|
#include "Math/Vector/SHVec2.h"
|
||||||
#include "ECS_Base/Managers/SHComponentManager.h"
|
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||||
#include "Math/Transform/SHTransformComponent.h"
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
|
@ -59,6 +61,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateCameraComponent(editorCamera);
|
UpdateCameraComponent(editorCamera);
|
||||||
|
|
||||||
}
|
}
|
||||||
void SHCameraSystem::EditorCameraUpdate::Execute(double dt) noexcept
|
void SHCameraSystem::EditorCameraUpdate::Execute(double dt) noexcept
|
||||||
{
|
{
|
||||||
|
@ -112,6 +115,8 @@ namespace SHADE
|
||||||
|
|
||||||
//std::cout << "Camera position: " << camera.position.x << " " << camera.position.y << std::endl;
|
//std::cout << "Camera position: " << camera.position.x << " " << camera.position.y << std::endl;
|
||||||
system->UpdateCameraComponent(system->editorCamera);
|
system->UpdateCameraComponent(system->editorCamera);
|
||||||
|
|
||||||
|
system->DecomposeViewMatrix(camera.viewMatrix, camera.pitch, camera.yaw, camera.roll, camera.position);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCameraSystem::Init(void)
|
void SHCameraSystem::Init(void)
|
||||||
|
@ -122,6 +127,9 @@ namespace SHADE
|
||||||
editorCamera.SetRoll(0.0f);
|
editorCamera.SetRoll(0.0f);
|
||||||
editorCamera.movementSpeed = 2.0f;
|
editorCamera.movementSpeed = 2.0f;
|
||||||
|
|
||||||
|
SHComponentManager::CreateComponentSparseSet<SHCameraComponent>();
|
||||||
|
SHComponentManager::CreateComponentSparseSet<SHCameraArmComponent>();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCameraSystem::Exit(void)
|
void SHCameraSystem::Exit(void)
|
||||||
|
@ -134,6 +142,26 @@ namespace SHADE
|
||||||
return &editorCamera;
|
return &editorCamera;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHCameraSystem::UpdatePivotArmComponent(SHCameraArmComponent& pivot) noexcept
|
||||||
|
{
|
||||||
|
if (pivot.dirty)
|
||||||
|
{
|
||||||
|
|
||||||
|
SHVec3 offset{ 0.0f,0.0f, pivot.GetArmLength() };
|
||||||
|
offset = SHVec3::RotateX(offset, -(SHMath::DegreesToRadians(pivot.GetPitch())));
|
||||||
|
offset = SHVec3::RotateY(offset, (SHMath::DegreesToRadians(pivot.GetYaw())));
|
||||||
|
|
||||||
|
|
||||||
|
//pivot.rtMatrix = SHMatrix::RotateX(SHMath::DegreesToRadians(pivot.GetPitch()))
|
||||||
|
// * SHMatrix::RotateY(SHMath::DegreesToRadians(pivot.GetYaw()))
|
||||||
|
// * SHMatrix::Translate(SHVec3(0.0f , 0.0f, pivot.GetArmLength()));
|
||||||
|
|
||||||
|
pivot.offset = offset;
|
||||||
|
// pivot.rtMatrix = SHMatrix::Inverse(pivot.rtMatrix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SHCameraSystem::UpdateCameraComponent(SHCameraComponent& camera) noexcept
|
void SHCameraSystem::UpdateCameraComponent(SHCameraComponent& camera) noexcept
|
||||||
{
|
{
|
||||||
if (SHComponentManager::HasComponent<SHTransformComponent>(camera.GetEID()) == true && &camera != &editorCamera)
|
if (SHComponentManager::HasComponent<SHTransformComponent>(camera.GetEID()) == true && &camera != &editorCamera)
|
||||||
|
@ -151,6 +179,15 @@ namespace SHADE
|
||||||
if (camera.dirtyView)
|
if (camera.dirtyView)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
camera.offset = SHVec3{ 0.0f };
|
||||||
|
if (SHComponentManager::HasComponent<SHCameraArmComponent>(camera.GetEID()))
|
||||||
|
{
|
||||||
|
auto arm = SHComponentManager::GetComponent<SHCameraArmComponent>(camera.GetEID());
|
||||||
|
camera.offset = arm->GetOffset();
|
||||||
|
if(arm->lookAtCameraOrigin)
|
||||||
|
CameraLookAt(camera, camera.position);
|
||||||
|
}
|
||||||
|
|
||||||
SHVec3 view, right, UP;
|
SHVec3 view, right, UP;
|
||||||
|
|
||||||
|
|
||||||
|
@ -171,9 +208,12 @@ namespace SHADE
|
||||||
camera.viewMatrix(2, 1) = view[1];
|
camera.viewMatrix(2, 1) = view[1];
|
||||||
camera.viewMatrix(2, 2) = view[2];
|
camera.viewMatrix(2, 2) = view[2];
|
||||||
|
|
||||||
camera.viewMatrix(0, 3) = -right.Dot(camera.position);
|
camera.viewMatrix(0, 3) = -right.Dot(camera.position + camera.offset);
|
||||||
camera.viewMatrix(1, 3) = -UP.Dot(camera.position);
|
camera.viewMatrix(1, 3) = -UP.Dot(camera.position + camera.offset);
|
||||||
camera.viewMatrix(2, 3) = -view.Dot(camera.position);
|
camera.viewMatrix(2, 3) = -view.Dot(camera.position + camera.offset);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
camera.dirtyView = false;
|
camera.dirtyView = false;
|
||||||
}
|
}
|
||||||
|
@ -221,6 +261,8 @@ namespace SHADE
|
||||||
SHVec3 up = { 0.0f,1.0f,0.0f };
|
SHVec3 up = { 0.0f,1.0f,0.0f };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
target = SHVec3::RotateX(target, SHMath::DegreesToRadians(camera.pitch));
|
target = SHVec3::RotateX(target, SHMath::DegreesToRadians(camera.pitch));
|
||||||
target = SHVec3::RotateY(target, SHMath::DegreesToRadians(camera.yaw));
|
target = SHVec3::RotateY(target, SHMath::DegreesToRadians(camera.yaw));
|
||||||
target += camera.position;
|
target += camera.position;
|
||||||
|
@ -241,6 +283,13 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
SHCameraSystem* system = static_cast<SHCameraSystem*>(GetSystem());
|
SHCameraSystem* system = static_cast<SHCameraSystem*>(GetSystem());
|
||||||
auto& dense = SHComponentManager::GetDense<SHCameraComponent>();
|
auto& dense = SHComponentManager::GetDense<SHCameraComponent>();
|
||||||
|
auto& pivotDense = SHComponentManager::GetDense<SHCameraArmComponent>();
|
||||||
|
|
||||||
|
for (auto& pivot : pivotDense)
|
||||||
|
{
|
||||||
|
system->UpdatePivotArmComponent(pivot);
|
||||||
|
}
|
||||||
|
|
||||||
for (auto& cam : dense)
|
for (auto& cam : dense)
|
||||||
{
|
{
|
||||||
system->UpdateCameraComponent(cam);
|
system->UpdateCameraComponent(cam);
|
||||||
|
@ -274,18 +323,115 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
void SHCameraSystem::ClampCameraRotation(SHCameraComponent& camera) noexcept
|
void SHCameraSystem::ClampCameraRotation(SHCameraComponent& camera) noexcept
|
||||||
{
|
{
|
||||||
|
constexpr float clampVal = 85.0f;
|
||||||
|
|
||||||
|
|
||||||
|
if (camera.pitch > clampVal)
|
||||||
|
camera.SetPitch(clampVal);
|
||||||
|
if (camera.pitch < -clampVal)
|
||||||
|
camera.SetPitch(-clampVal);
|
||||||
|
if (camera.roll > clampVal)
|
||||||
|
camera.SetRoll(clampVal);
|
||||||
|
if (camera.roll < -clampVal)
|
||||||
|
camera.SetRoll(-clampVal);
|
||||||
|
|
||||||
if (camera.pitch > 85)
|
while (camera.yaw > 360)
|
||||||
camera.SetPitch(85);
|
camera.yaw -= 360;
|
||||||
if (camera.pitch < -85)
|
while (camera.yaw < -360)
|
||||||
camera.SetPitch(-85);
|
camera.yaw += 360;
|
||||||
if (camera.roll > 85)
|
|
||||||
camera.SetRoll(85);
|
|
||||||
if (camera.roll < -85)
|
|
||||||
camera.SetRoll(-85);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHCameraSystem::SetMainCamera(EntityID eid, size_t directorIndex) noexcept
|
||||||
|
{
|
||||||
|
if (SHComponentManager::HasComponent<SHCameraComponent>(eid) && directorIndex < directorHandleList.size())
|
||||||
|
directorHandleList[directorIndex]->SetMainCamera(*SHComponentManager::GetComponent<SHCameraComponent>(eid));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("Set Main Camera warning: Entity does not have camera component or director does not exist.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHCameraSystem::DecomposeViewMatrix(SHMatrix const& viewMatrix, float& pitch, float& yaw, float& roll, SHVec3& pos) noexcept
|
||||||
|
{
|
||||||
|
|
||||||
|
float initPitch = pitch;
|
||||||
|
SHVec3 initPos = pos;
|
||||||
|
SHVec3 translate3, scale;
|
||||||
|
SHQuaternion quat;
|
||||||
|
|
||||||
|
//SHMatrix viewInverse = viewMatrix;
|
||||||
|
|
||||||
|
viewMatrix.Decompose(translate3, quat, scale);
|
||||||
|
yaw = 180+ SHMath::RadiansToDegrees(quat.ToEuler().y);
|
||||||
|
pitch = -SHMath::RadiansToDegrees(quat.ToEuler().x);
|
||||||
|
|
||||||
|
SHVec4 dotPos{ -viewMatrix(0,3),-viewMatrix(1,3), -viewMatrix(2,3), 1.0f };
|
||||||
|
SHMatrix mtx = viewMatrix;
|
||||||
|
mtx(0, 3) = 0.0f;
|
||||||
|
mtx(1, 3) = 0.0f;
|
||||||
|
mtx(2, 3) = 0.0f;
|
||||||
|
mtx.Transpose();
|
||||||
|
mtx = SHMatrix::Inverse(mtx);
|
||||||
|
SHVec4 translate = mtx* dotPos;
|
||||||
|
|
||||||
|
pos.x = translate.x;
|
||||||
|
pos.y = translate.y;
|
||||||
|
pos.z = translate.z;
|
||||||
|
|
||||||
|
}
|
||||||
|
void SHCameraSystem::SetCameraViewMatrix(SHCameraComponent& camera, SHMatrix const& viewMatrix) noexcept
|
||||||
|
{
|
||||||
|
DecomposeViewMatrix(viewMatrix, camera.pitch, camera.yaw, camera.roll, camera.position);
|
||||||
|
camera.dirtyView = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHCameraSystem::CameraLookAt(SHCameraComponent& camera, SHVec3 target) noexcept
|
||||||
|
{
|
||||||
|
|
||||||
|
if (camera.position == target)
|
||||||
|
{
|
||||||
|
//lets off set it abit so the view is nt fked
|
||||||
|
target.z -= 0.0001f;
|
||||||
|
}
|
||||||
|
SHVec3 forward, right, upVec;
|
||||||
|
|
||||||
|
SHVec3 up = { 0.0f,1.0f,0.0f };
|
||||||
|
|
||||||
|
|
||||||
|
////SHVec3::RotateZ(target, SHMath::DegreesToRadians(camera.roll));
|
||||||
|
|
||||||
|
//target = SHVec3::Normalise(target);
|
||||||
|
|
||||||
|
SHVec3::RotateZ(up, camera.roll);
|
||||||
|
up = SHVec3::Normalise(up);
|
||||||
|
|
||||||
|
|
||||||
|
forward = target - (camera.position + camera.offset); forward = SHVec3::Normalise(forward);
|
||||||
|
right = SHVec3::Cross(forward, up); right = SHVec3::Normalise(right);
|
||||||
|
upVec = SHVec3::Cross(forward, right);
|
||||||
|
|
||||||
|
|
||||||
|
SHMatrix viewMtx;
|
||||||
|
viewMtx = SHMatrix::Identity;
|
||||||
|
viewMtx(0, 0) = right[0];
|
||||||
|
viewMtx(0, 1) = right[1];
|
||||||
|
viewMtx(0, 2) = right[2];
|
||||||
|
|
||||||
|
viewMtx(1, 0) = upVec[0];
|
||||||
|
viewMtx(1, 1) = upVec[1];
|
||||||
|
viewMtx(1, 2) = upVec[2];
|
||||||
|
|
||||||
|
viewMtx(2, 0) = forward[0];
|
||||||
|
viewMtx(2, 1) = forward[1];
|
||||||
|
viewMtx(2, 2) = forward[2];
|
||||||
|
|
||||||
|
viewMtx(0, 3) = -right.Dot(camera.position + camera.offset);
|
||||||
|
viewMtx(1, 3) = -upVec.Dot(camera.position + camera.offset);
|
||||||
|
viewMtx(2, 3) = -forward.Dot(camera.position + camera.offset);
|
||||||
|
|
||||||
|
|
||||||
|
SetCameraViewMatrix(camera, viewMtx);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,9 @@
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class SHCameraArmComponent;
|
||||||
|
|
||||||
class SH_API SHCameraSystem final : public SHSystem
|
class SH_API SHCameraSystem final : public SHSystem
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
@ -19,6 +22,11 @@ namespace SHADE
|
||||||
SHResourceLibrary<SHCameraDirector> directorLibrary;
|
SHResourceLibrary<SHCameraDirector> directorLibrary;
|
||||||
std::vector<DirectorHandle> directorHandleList;
|
std::vector<DirectorHandle> directorHandleList;
|
||||||
|
|
||||||
|
|
||||||
|
void UpdateCameraComponent(SHCameraComponent& camera) noexcept;
|
||||||
|
void UpdatePivotArmComponent(SHCameraArmComponent& pivot) noexcept;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SHCameraSystem(void) = default;
|
SHCameraSystem(void) = default;
|
||||||
virtual ~SHCameraSystem(void) = default;
|
virtual ~SHCameraSystem(void) = default;
|
||||||
|
@ -39,7 +47,7 @@ namespace SHADE
|
||||||
class SH_API CameraSystemUpdate final: public SHSystemRoutine
|
class SH_API CameraSystemUpdate final: public SHSystemRoutine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CameraSystemUpdate() : SHSystemRoutine("Camera System Update", false) {};
|
CameraSystemUpdate() : SHSystemRoutine("Camera System Update", true) {};
|
||||||
virtual void Execute(double dt)noexcept override final;
|
virtual void Execute(double dt)noexcept override final;
|
||||||
};
|
};
|
||||||
friend class CameraSystemUpdate;
|
friend class CameraSystemUpdate;
|
||||||
|
@ -51,12 +59,10 @@ namespace SHADE
|
||||||
DirectorHandle GetDirector(size_t index) noexcept;
|
DirectorHandle GetDirector(size_t index) noexcept;
|
||||||
void ClampCameraRotation(SHCameraComponent& camera) noexcept;
|
void ClampCameraRotation(SHCameraComponent& camera) noexcept;
|
||||||
void UpdateEditorCamera(double dt) noexcept;
|
void UpdateEditorCamera(double dt) noexcept;
|
||||||
protected:
|
void SetMainCamera(EntityID eid, size_t directorIndex) noexcept;
|
||||||
|
void DecomposeViewMatrix(SHMatrix const& matrix, float& pitch, float& yaw, float& roll, SHVec3& pos) noexcept;
|
||||||
void UpdateCameraComponent(SHCameraComponent& camera) noexcept;
|
void SetCameraViewMatrix(SHCameraComponent& camera, SHMatrix const& viewMatrix) noexcept;
|
||||||
|
void CameraLookAt(SHCameraComponent& camera, SHVec3 target) noexcept;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -33,12 +33,18 @@ namespace SHADE
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<SHComponentRemovedEvent> eventVec;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < componentSet.Size(); ++i)
|
for (uint32_t i = 0; i < componentSet.Size(); ++i)
|
||||||
{
|
{
|
||||||
SHComponent* comp = (SHComponent*) componentSet.GetElement(i, EntityHandleGenerator::GetIndex(entityID));
|
SHComponent* comp = (SHComponent*) componentSet.GetElement(i, EntityHandleGenerator::GetIndex(entityID));
|
||||||
if (comp)
|
if (comp)
|
||||||
{
|
{
|
||||||
comp->OnDestroy();
|
comp->OnDestroy();
|
||||||
|
SHComponentRemovedEvent eventData;
|
||||||
|
eventData.eid = entityID;
|
||||||
|
eventData.removedComponentType = i;
|
||||||
|
eventVec.push_back(eventData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,8 +57,15 @@ namespace SHADE
|
||||||
|
|
||||||
componentSet.RemoveElements(EntityHandleGenerator::GetIndex(entityID));
|
componentSet.RemoveElements(EntityHandleGenerator::GetIndex(entityID));
|
||||||
|
|
||||||
|
for (auto& eventData : eventVec)
|
||||||
|
{
|
||||||
|
SHEventManager::BroadcastEvent<SHComponentRemovedEvent>(eventData, SH_COMPONENT_REMOVED_EVENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//entityHandle.RemoveHandle(entityID);
|
//entityHandle.RemoveHandle(entityID);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -213,5 +213,14 @@ namespace SHADE
|
||||||
return SHSerialization::DeserializeEntityToSceneFromString(data);
|
return SHSerialization::DeserializeEntityToSceneFromString(data);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
EntityID SHEntityManager::GetEntityByName(std::string const& name) noexcept
|
||||||
|
{
|
||||||
|
EntityID result = MAX_EID;
|
||||||
|
for (auto& entity : entityVec)
|
||||||
|
{
|
||||||
|
if (entity->name == name)
|
||||||
|
result = entity->GetEID();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -209,6 +209,8 @@ namespace SHADE
|
||||||
|
|
||||||
//static EntityID DuplicateEntity(EntityID eid) noexcept;
|
//static EntityID DuplicateEntity(EntityID eid) noexcept;
|
||||||
|
|
||||||
|
static EntityID GetEntityByName(std::string const& name) noexcept;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
system.second->Init();
|
system.second->Init();
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
std::cout << system.first << " Init" << std::endl;
|
SHLOG_INFO("Initialising System {}...", system.first)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,12 @@
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
//TODO: Convert to RTTR?
|
//TODO: Convert to RTTR?
|
||||||
constexpr auto DRAG_EID = "DragEID";
|
|
||||||
constexpr auto DRAG_RESOURCE = "DragResource";
|
|
||||||
|
|
||||||
|
|
||||||
struct SHDragDrop
|
struct SHDragDrop
|
||||||
{
|
{
|
||||||
|
using DragDropTag = std::string_view;
|
||||||
|
static constexpr DragDropTag DRAG_EID = "DragEID";
|
||||||
|
static constexpr DragDropTag DRAG_RESOURCE = "DragResource";
|
||||||
static bool BeginSource(ImGuiDragDropFlags const flags = 0);
|
static bool BeginSource(ImGuiDragDropFlags const flags = 0);
|
||||||
/**
|
/**
|
||||||
* \brief Ends the DragDrop Source. ONLY CALL IF BeginSource returns true
|
* \brief Ends the DragDrop Source. ONLY CALL IF BeginSource returns true
|
||||||
|
|
|
@ -4,14 +4,16 @@
|
||||||
#include "Editor/IconsMaterialDesign.h"
|
#include "Editor/IconsMaterialDesign.h"
|
||||||
#include "Editor/SHImGuiHelpers.hpp"
|
#include "Editor/SHImGuiHelpers.hpp"
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
|
#include <imgui_internal.h>
|
||||||
|
|
||||||
#include "Assets/SHAssetManager.h"
|
#include "Assets/SHAssetManager.h"
|
||||||
|
#include "Editor/IconsFontAwesome6.h"
|
||||||
#include "Editor/DragDrop/SHDragDrop.hpp"
|
#include "Editor/DragDrop/SHDragDrop.hpp"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
SHAssetBrowser::SHAssetBrowser()
|
SHAssetBrowser::SHAssetBrowser()
|
||||||
:SHEditorWindow("\xee\x8b\x87 Asset Browser", ImGuiWindowFlags_MenuBar)
|
:SHEditorWindow("\xee\x8b\x87 Asset Browser", ImGuiWindowFlags_MenuBar), rootFolder(SHAssetManager::GetRootFolder()), prevFolder(rootFolder), currentFolder(rootFolder)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,22 +27,9 @@ namespace SHADE
|
||||||
SHEditorWindow::Update();
|
SHEditorWindow::Update();
|
||||||
if (Begin())
|
if (Begin())
|
||||||
{
|
{
|
||||||
|
RecursivelyDrawTree(rootFolder);
|
||||||
DrawMenuBar();
|
DrawMenuBar();
|
||||||
auto const& assets = SHAssetManager::GetAllAssets();
|
DrawCurrentFolder();
|
||||||
if(ImGui::BeginTable("AssetBrowserTable", 3))
|
|
||||||
{
|
|
||||||
ImGui::TableNextColumn();
|
|
||||||
ImGui::TableHeader("Asset ID");
|
|
||||||
ImGui::TableNextColumn();
|
|
||||||
ImGui::TableHeader("Name");
|
|
||||||
ImGui::TableNextColumn();
|
|
||||||
ImGui::TableHeader("Type");
|
|
||||||
for(SHAsset const& asset : assets)
|
|
||||||
{
|
|
||||||
DrawAsset(asset);
|
|
||||||
}
|
|
||||||
ImGui::EndTable();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
@ -54,31 +43,122 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHAssetBrowser::DrawAsset(SHAsset const& asset)
|
ImRect SHAssetBrowser::RecursivelyDrawTree(FolderPointer folder)
|
||||||
{
|
{
|
||||||
ImGui::PushID(asset.id);
|
auto const& subFolders = folder->subFolders;
|
||||||
ImGui::BeginGroup();
|
auto const& files = folder->files;
|
||||||
|
const bool isSelected = std::ranges::find(selectedFolders, folder) != selectedFolders.end();
|
||||||
|
ImGuiTreeNodeFlags flags = (subFolders.empty() && files.empty()) ? ImGuiTreeNodeFlags_Leaf : ImGuiTreeNodeFlags_OpenOnArrow;
|
||||||
|
if (isSelected)
|
||||||
|
flags |= ImGuiTreeNodeFlags_Selected;
|
||||||
|
if (folder == rootFolder)
|
||||||
|
flags |= ImGuiTreeNodeFlags_DefaultOpen;
|
||||||
|
|
||||||
ImGui::TableNextColumn();
|
bool isOpen = ImGui::TreeNodeEx(folder, flags, "%s %s", ICON_MD_FOLDER, folder->name.data());
|
||||||
ImGui::Selectable(std::format("{}", asset.id).data(), false, ImGuiSelectableFlags_SpanAllColumns);
|
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
||||||
|
if(ImGui::IsItemClicked())
|
||||||
|
{
|
||||||
|
selectedFolders.clear();
|
||||||
|
selectedFolders.push_back(folder);
|
||||||
|
}
|
||||||
|
if (isOpen)
|
||||||
|
{
|
||||||
|
const ImColor treeLineColor = ImGui::GetColorU32(ImGuiCol_CheckMark);
|
||||||
|
const float horizontalOffset = 0.0f;
|
||||||
|
ImDrawList* drawList = ImGui::GetWindowDrawList();
|
||||||
|
ImVec2 vertLineStart = ImGui::GetCursorScreenPos();
|
||||||
|
vertLineStart.x += horizontalOffset;
|
||||||
|
ImVec2 vertLineEnd = vertLineStart;
|
||||||
|
for (auto const& subFolder : subFolders)
|
||||||
|
{
|
||||||
|
const float horizontalLineSize = 8.0f;
|
||||||
|
const ImRect childRect = RecursivelyDrawTree(subFolder);
|
||||||
|
const float midPoint = (childRect.Min.y + childRect.Max.y) * 0.5f;
|
||||||
|
drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1);
|
||||||
|
vertLineEnd.y = midPoint;
|
||||||
|
}
|
||||||
|
for (auto const& file : files)
|
||||||
|
{
|
||||||
|
const float horizontalLineSize = 25.0f;
|
||||||
|
const ImRect childRect = DrawFile(file);
|
||||||
|
const float midPoint = (childRect.Min.y + childRect.Max.y) * 0.5f;
|
||||||
|
drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1);
|
||||||
|
vertLineEnd.y = midPoint;
|
||||||
|
}
|
||||||
|
drawList->AddLine(vertLineStart, vertLineEnd, treeLineColor, 1);
|
||||||
|
ImGui::TreePop();
|
||||||
|
}
|
||||||
|
return nodeRect;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAssetBrowser::DrawCurrentFolder()
|
||||||
|
{
|
||||||
|
//auto const& subFolders = currentFolder->subFolders;
|
||||||
|
//ImVec2 initialCursorPos = ImGui::GetCursorPos();
|
||||||
|
//ImVec2 initialRegionAvail = ImGui::GetContentRegionAvail();
|
||||||
|
//int maxTiles = initialRegionAvail.x / tileWidth;
|
||||||
|
//float maxX = (maxTiles - 1)*tileWidth;
|
||||||
|
//ImVec2 tilePos = initialCursorPos;
|
||||||
|
//for (auto const& subFolder : subFolders)
|
||||||
|
//{
|
||||||
|
// ImGui::SetCursorPos(tilePos);
|
||||||
|
// ImGui::BeginGroup();
|
||||||
|
// ImGui::PushStyleVar(ImGuiStyleVar_ItemInnerSpacing, {0.0f, 0.0f});
|
||||||
|
// ImGui::Button(ICON_MD_FOLDER, {tileWidth});
|
||||||
|
// ImGui::Text(subFolder->name.data());
|
||||||
|
// ImGui::PopStyleVar();
|
||||||
|
// ImGui::EndGroup();
|
||||||
|
// if(tilePos.x >= maxX)
|
||||||
|
// {
|
||||||
|
// tilePos.x = initialCursorPos.x;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// ImGui::SameLine();
|
||||||
|
// tilePos.x += tileWidth;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImRect SHAssetBrowser::DrawFile(SHFile const& file) noexcept
|
||||||
|
{
|
||||||
|
if (file.assetMeta == nullptr)
|
||||||
|
return ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
||||||
|
const bool isSelected = std::ranges::find(selectedAssets, file.assetMeta->id) != selectedAssets.end();
|
||||||
|
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_Leaf;
|
||||||
|
if (isSelected)
|
||||||
|
flags |= ImGuiTreeNodeFlags_Selected;
|
||||||
|
std::string icon{};
|
||||||
|
|
||||||
|
switch(file.assetMeta->type)
|
||||||
|
{
|
||||||
|
case AssetType::INVALID: break;
|
||||||
|
case AssetType::SHADER: icon = ICON_FA_FILE_CODE; break;
|
||||||
|
case AssetType::SHADER_BUILT_IN: icon = ICON_FA_FILE_CODE; break;
|
||||||
|
case AssetType::TEXTURE: icon = ICON_FA_IMAGES; break;
|
||||||
|
case AssetType::MESH: icon = ICON_FA_CUBES; break;
|
||||||
|
case AssetType::SCENE: icon = ICON_MD_IMAGE; break;
|
||||||
|
case AssetType::PREFAB: icon = ICON_FA_BOX_OPEN; break;
|
||||||
|
case AssetType::MATERIAL: break;
|
||||||
|
case AssetType::MAX_COUNT: break;
|
||||||
|
default: ;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::TreeNodeEx(file.assetMeta, flags, "%s %s", icon.data(), file.assetMeta->name.data());
|
||||||
|
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
||||||
if(SHDragDrop::BeginSource())
|
if(SHDragDrop::BeginSource())
|
||||||
{
|
{
|
||||||
auto id = asset.id;
|
auto id = file.assetMeta->id;
|
||||||
ImGui::Text("Moving Asset: %zu", id);
|
ImGui::Text("Moving Asset: %s [%zu]", file.name.data(), file.assetMeta->id);
|
||||||
SHDragDrop::SetPayload<AssetID>(DRAG_RESOURCE, &id);
|
SHDragDrop::SetPayload<AssetID>(SHDragDrop::DRAG_RESOURCE, &id);
|
||||||
SHDragDrop::EndSource();
|
SHDragDrop::EndSource();
|
||||||
}
|
}
|
||||||
|
if(ImGui::IsItemClicked())
|
||||||
ImGui::TableNextColumn();
|
{
|
||||||
ImGui::Text("%s", asset.name.c_str());
|
selectedAssets.clear();
|
||||||
|
selectedAssets.push_back(file.assetMeta->id);
|
||||||
ImGui::TableNextColumn();
|
}
|
||||||
ImGui::Text("%s", "Type");
|
ImGui::TreePop();
|
||||||
|
return nodeRect;
|
||||||
ImGui::EndGroup();
|
|
||||||
ImGui::PopID();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "imgui_internal.h"
|
||||||
#include "Assets/SHAsset.h"
|
#include "Assets/SHAsset.h"
|
||||||
#include "Editor/EditorWindow/SHEditorWindow.h"
|
#include "Editor/EditorWindow/SHEditorWindow.h"
|
||||||
|
#include "Filesystem/SHFolder.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -16,9 +18,14 @@ namespace SHADE
|
||||||
void Refresh();
|
void Refresh();
|
||||||
private:
|
private:
|
||||||
void DrawMenuBar();
|
void DrawMenuBar();
|
||||||
void DrawAsset(SHAsset const& asset);
|
ImRect RecursivelyDrawTree(FolderPointer folder);
|
||||||
|
void DrawCurrentFolder();
|
||||||
|
ImRect DrawFile(SHFile const& file) noexcept;
|
||||||
|
|
||||||
float idColumnWidth, nameColumnWidth, typeColumnWidth;
|
FolderPointer rootFolder, prevFolder, currentFolder;
|
||||||
|
std::vector<FolderPointer> selectedFolders;
|
||||||
|
std::vector<AssetID> selectedAssets;
|
||||||
|
static constexpr float tileWidth = 50.0f;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -6,7 +6,7 @@
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| SHADE Includes ||
|
//|| SHADE Includes ||
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
#include "Editor/SHEditor.hpp"
|
#include "Editor/SHEditor.h"
|
||||||
#include "Editor/SHImGuiHelpers.hpp"
|
#include "Editor/SHImGuiHelpers.hpp"
|
||||||
#include "Editor/SHEditorWidgets.hpp"
|
#include "Editor/SHEditorWidgets.hpp"
|
||||||
#include "SHHierarchyPanel.h"
|
#include "SHHierarchyPanel.h"
|
||||||
|
@ -48,15 +48,28 @@ namespace SHADE
|
||||||
|
|
||||||
if (Begin())
|
if (Begin())
|
||||||
{
|
{
|
||||||
|
if (skipFrame)
|
||||||
|
{
|
||||||
|
ImGui::End();
|
||||||
|
skipFrame = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
DrawMenuBar();
|
DrawMenuBar();
|
||||||
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
|
|
||||||
if (const auto root = sceneGraph.GetRoot())
|
if (const auto root = sceneGraph.GetRoot())
|
||||||
{
|
{
|
||||||
auto const& children = root->GetChildren();
|
auto const& children = root->GetChildren();
|
||||||
|
|
||||||
for (const auto child : children)
|
for (const auto child : children)
|
||||||
{
|
{
|
||||||
|
if (child)
|
||||||
RecursivelyDrawEntityNode(child);
|
RecursivelyDrawEntityNode(child);
|
||||||
|
if (skipFrame)
|
||||||
|
{
|
||||||
|
ImGui::End();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -70,6 +83,30 @@ namespace SHADE
|
||||||
editor->selectedEntities.clear();
|
editor->selectedEntities.clear();
|
||||||
}
|
}
|
||||||
ImGui::SeparatorEx(ImGuiSeparatorFlags_Horizontal);
|
ImGui::SeparatorEx(ImGuiSeparatorFlags_Horizontal);
|
||||||
|
if (ImGui::IsWindowFocused())
|
||||||
|
{
|
||||||
|
if (ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_A))
|
||||||
|
{
|
||||||
|
SelectAllEntities();
|
||||||
|
}
|
||||||
|
if (ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_C))
|
||||||
|
{
|
||||||
|
CopySelectedEntities();
|
||||||
|
}
|
||||||
|
if (ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && !ImGui::IsKeyDown(ImGuiKey_LeftShift) && ImGui::IsKeyReleased(ImGuiKey_V))
|
||||||
|
{
|
||||||
|
PasteEntities();
|
||||||
|
}
|
||||||
|
if (ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyDown(ImGuiKey_LeftShift) && ImGui::IsKeyReleased(ImGuiKey_V))
|
||||||
|
{
|
||||||
|
const auto editor = SHSystemManager::GetSystem<SHEditor>();
|
||||||
|
if (editor->selectedEntities.size() == 1)
|
||||||
|
{
|
||||||
|
PasteEntities(editor->selectedEntities.back());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
@ -93,8 +130,10 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if (ImGui::BeginMenuBar())
|
if (ImGui::BeginMenuBar())
|
||||||
{
|
{
|
||||||
ImGui::SetCursorPosX(ImGui::GetContentRegionAvail().x * 0.75f);
|
auto size = ImGui::GetWindowSize();
|
||||||
if(ImGui::SmallButton(ICON_MD_DESELECT))
|
auto g = ImGui::GetCurrentContext();
|
||||||
|
ImGui::SetCursorPosX(size.x - g->Style.FramePadding.x * 15.0f);
|
||||||
|
if (ImGui::SmallButton(ICON_MD_CLEAR_ALL))
|
||||||
{
|
{
|
||||||
auto editor = SHSystemManager::GetSystem<SHEditor>();
|
auto editor = SHSystemManager::GetSystem<SHEditor>();
|
||||||
editor->selectedEntities.clear();
|
editor->selectedEntities.clear();
|
||||||
|
@ -119,8 +158,10 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImRect SHHierarchyPanel::RecursivelyDrawEntityNode(SHSceneNode* currentNode)
|
ImRect SHHierarchyPanel::RecursivelyDrawEntityNode(SHSceneNode* const currentNode)
|
||||||
{
|
{
|
||||||
|
if (currentNode == nullptr)
|
||||||
|
return {};
|
||||||
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
|
|
||||||
//Get node data (Children, eid, selected)
|
//Get node data (Children, eid, selected)
|
||||||
|
@ -154,23 +195,27 @@ namespace SHADE
|
||||||
if (SHDragDrop::BeginSource())
|
if (SHDragDrop::BeginSource())
|
||||||
{
|
{
|
||||||
std::string moveLabel = "Moving EID: ";
|
std::string moveLabel = "Moving EID: ";
|
||||||
|
static std::vector<EntityID> draggingEntities = editor->selectedEntities;
|
||||||
if (!isSelected)
|
if (!isSelected)
|
||||||
editor->selectedEntities.push_back(eid);
|
|
||||||
for(int i = 0; i < static_cast<int>(editor->selectedEntities.size()); ++i)
|
|
||||||
{
|
{
|
||||||
moveLabel.append(std::to_string(editor->selectedEntities[i]));
|
draggingEntities.clear();
|
||||||
if(i + 1 < static_cast<int>(editor->selectedEntities.size()))
|
draggingEntities.push_back(eid);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < static_cast<int>(draggingEntities.size()); ++i)
|
||||||
|
{
|
||||||
|
moveLabel.append(std::to_string(draggingEntities[i]));
|
||||||
|
if (i + 1 < static_cast<int>(draggingEntities.size()))
|
||||||
{
|
{
|
||||||
moveLabel.append(", ");
|
moveLabel.append(", ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::Text(moveLabel.c_str());
|
ImGui::Text(moveLabel.c_str());
|
||||||
SHDragDrop::SetPayload<std::vector<EntityID>>(DRAG_EID, &editor->selectedEntities);
|
SHDragDrop::SetPayload<std::vector<EntityID>>(SHDragDrop::DRAG_EID, &draggingEntities);
|
||||||
SHDragDrop::EndSource();
|
SHDragDrop::EndSource();
|
||||||
}
|
}
|
||||||
else if (SHDragDrop::BeginTarget()) //If Received DragDrop
|
else if (SHDragDrop::BeginTarget()) //If Received DragDrop
|
||||||
{
|
{
|
||||||
if (const std::vector<EntityID>* eidPayload = SHDragDrop::AcceptPayload<std::vector<EntityID>>(DRAG_EID)) //If payload is valid
|
if (const std::vector<EntityID>* eidPayload = SHDragDrop::AcceptPayload<std::vector<EntityID>>(SHDragDrop::DRAG_EID)) //If payload is valid
|
||||||
{
|
{
|
||||||
ParentSelectedEntities(eid);
|
ParentSelectedEntities(eid);
|
||||||
SHDragDrop::EndTarget();
|
SHDragDrop::EndTarget();
|
||||||
|
@ -187,15 +232,21 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
if (ImGui::Selectable("Copy"))
|
if (ImGui::Selectable("Copy"))
|
||||||
{
|
{
|
||||||
SHClipboardUtilities::WriteToClipboard(SHSerialization::SerializeEntitiesToString(editor->selectedEntities));
|
CopySelectedEntities();
|
||||||
}
|
}
|
||||||
if (ImGui::Selectable("Paste"))
|
if (ImGui::Selectable("Paste"))
|
||||||
{
|
{
|
||||||
SetScrollTo(SHSerialization::DeserializeEntitiesFromString(SHClipboardUtilities::GetDataFromClipboard()));
|
PasteEntities();
|
||||||
|
skipFrame = true;
|
||||||
|
ImGui::EndPopup();
|
||||||
|
if (isNodeOpen)
|
||||||
|
ImGui::TreePop();
|
||||||
|
return nodeRect;
|
||||||
}
|
}
|
||||||
if (ImGui::Selectable("Paste as Child"))
|
if (ImGui::Selectable("Paste as Child"))
|
||||||
{
|
{
|
||||||
SetScrollTo(SHSerialization::DeserializeEntitiesFromString(SHClipboardUtilities::GetDataFromClipboard(), eid));
|
PasteEntities(eid);
|
||||||
|
skipFrame = true;
|
||||||
}
|
}
|
||||||
if (ImGui::Selectable(std::format("{} Delete", ICON_MD_DELETE).data()))
|
if (ImGui::Selectable(std::format("{} Delete", ICON_MD_DELETE).data()))
|
||||||
{
|
{
|
||||||
|
@ -322,6 +373,29 @@ namespace SHADE
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHHierarchyPanel::SelectAllEntities()
|
||||||
|
{
|
||||||
|
const auto editor = SHSystemManager::GetSystem<SHEditor>();
|
||||||
|
editor->selectedEntities.clear();
|
||||||
|
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
|
sceneGraph.Traverse([&](SHSceneNode* nodePtr)
|
||||||
|
{
|
||||||
|
auto eid = nodePtr->GetEntityID();
|
||||||
|
editor->selectedEntities.push_back(eid);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHHierarchyPanel::CopySelectedEntities()
|
||||||
|
{
|
||||||
|
const auto editor = SHSystemManager::GetSystem<SHEditor>();
|
||||||
|
SHClipboardUtilities::WriteToClipboard(SHSerialization::SerializeEntitiesToString(editor->selectedEntities));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHHierarchyPanel::PasteEntities(EntityID parentEID)
|
||||||
|
{
|
||||||
|
SetScrollTo(SHSerialization::DeserializeEntitiesFromString(SHClipboardUtilities::GetDataFromClipboard(), parentEID));
|
||||||
|
}
|
||||||
|
|
||||||
void SHCreateEntityCommand::Execute()
|
void SHCreateEntityCommand::Execute()
|
||||||
{
|
{
|
||||||
EntityID newEID = SHEntityManager::CreateEntity(eid);
|
EntityID newEID = SHEntityManager::CreateEntity(eid);
|
||||||
|
|
|
@ -26,10 +26,14 @@ namespace SHADE
|
||||||
void SetScrollTo(EntityID eid);
|
void SetScrollTo(EntityID eid);
|
||||||
private:
|
private:
|
||||||
void DrawMenuBar() const noexcept;
|
void DrawMenuBar() const noexcept;
|
||||||
ImRect RecursivelyDrawEntityNode(SHSceneNode*);
|
ImRect RecursivelyDrawEntityNode(SHSceneNode* const);
|
||||||
void CreateChildEntity(EntityID parentEID) const noexcept;
|
void CreateChildEntity(EntityID parentEID) const noexcept;
|
||||||
void ParentSelectedEntities(EntityID parentEID) const noexcept;
|
void ParentSelectedEntities(EntityID parentEID) const noexcept;
|
||||||
void SelectRangeOfEntities(EntityID beginEID, EntityID EndEID);
|
void SelectRangeOfEntities(EntityID beginEID, EntityID EndEID);
|
||||||
|
void SelectAllEntities();
|
||||||
|
void CopySelectedEntities();
|
||||||
|
void PasteEntities(EntityID parentEID = MAX_EID);
|
||||||
|
bool skipFrame = false;
|
||||||
std::string filter;
|
std::string filter;
|
||||||
bool isAnyNodeSelected = false;
|
bool isAnyNodeSelected = false;
|
||||||
EntityID scrollTo = MAX_EID;
|
EntityID scrollTo = MAX_EID;
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
#pragma once
|
||||||
|
#include "ECS_Base/Components/SHComponent.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
template<typename T, std::enable_if_t<std::is_base_of<SHComponent, T>::value, bool> = true>
|
||||||
|
static void DrawContextMenu(T* component);
|
||||||
|
template<typename T, std::enable_if_t<std::is_base_of_v<SHComponent, T>, bool> = true>
|
||||||
|
static void DrawComponent(T* component);
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "SHEditorComponentView.hpp"
|
|
@ -13,9 +13,12 @@
|
||||||
#include "Editor/IconsFontAwesome6.h"
|
#include "Editor/IconsFontAwesome6.h"
|
||||||
#include "ECS_Base/Components/SHComponent.h"
|
#include "ECS_Base/Components/SHComponent.h"
|
||||||
#include "Editor/SHEditorWidgets.hpp"
|
#include "Editor/SHEditorWidgets.hpp"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||||
#include "Graphics/MiddleEnd/Lights/SHLightComponent.h"
|
#include "Graphics/MiddleEnd/Lights/SHLightComponent.h"
|
||||||
#include "Physics/Components/SHColliderComponent.h"
|
#include "Physics/Components/SHColliderComponent.h"
|
||||||
#include "Reflection/SHReflectionMetadata.h"
|
#include "Reflection/SHReflectionMetadata.h"
|
||||||
|
#include "Resource/SHResourceManager.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -31,7 +34,7 @@ namespace SHADE
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, std::enable_if_t<std::is_base_of<SHComponent, T>::value, bool> = true>
|
template<typename T, std::enable_if_t<std::is_base_of<SHComponent, T>::value, bool>>
|
||||||
static void DrawContextMenu(T* component)
|
static void DrawContextMenu(T* component)
|
||||||
{
|
{
|
||||||
if (!component)
|
if (!component)
|
||||||
|
@ -60,13 +63,15 @@ namespace SHADE
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
template<typename T, std::enable_if_t<std::is_base_of_v<SHComponent, T>, bool> = true>
|
template<typename T, std::enable_if_t<std::is_base_of_v<SHComponent, T>, bool>>
|
||||||
static void DrawComponent(T* component)
|
static void DrawComponent(T* component)
|
||||||
{
|
{
|
||||||
if (!component)
|
if (!component)
|
||||||
return;
|
return;
|
||||||
const auto componentType = rttr::type::get(*component);
|
const auto componentType = rttr::type::get<T>();
|
||||||
|
ImGui::PushID(SHFamilyID<SHComponent>::GetID<T>());
|
||||||
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
|
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
|
||||||
|
ImGui::PopID();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
||||||
{
|
{
|
||||||
|
@ -75,7 +80,8 @@ namespace SHADE
|
||||||
for (auto const& property : properties)
|
for (auto const& property : properties)
|
||||||
{
|
{
|
||||||
auto const& type = property.get_type();
|
auto const& type = property.get_type();
|
||||||
|
auto tooltip = property.get_metadata(META::tooltip);
|
||||||
|
bool const& isAngleInRad = property.get_metadata(META::angleInRad).is_valid() ? property.get_metadata(META::angleInRad).template get_value<bool>() : false;
|
||||||
if (type.is_enumeration())
|
if (type.is_enumeration())
|
||||||
{
|
{
|
||||||
auto enumAlign = type.get_enumeration();
|
auto enumAlign = type.get_enumeration();
|
||||||
|
@ -89,29 +95,25 @@ namespace SHADE
|
||||||
auto values = enumAlign.get_values();
|
auto values = enumAlign.get_values();
|
||||||
auto it = std::next(values.begin(), idx);
|
auto it = std::next(values.begin(), idx);
|
||||||
property.set_value(component, *it);
|
property.set_value(component, *it);
|
||||||
});
|
}, tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string());
|
||||||
}
|
}
|
||||||
else if (type.is_arithmetic())
|
else if (type.is_arithmetic())
|
||||||
{
|
{
|
||||||
if (type == rttr::type::get<bool>())
|
if (type == rttr::type::get<bool>())
|
||||||
{
|
{
|
||||||
SHEditorWidgets::CheckBox(property.get_name().data(), [component, property] {return property.get_value(component).to_bool(); }, [component, property](bool const& result) {property.set_value(component, result); });
|
SHEditorWidgets::CheckBox(property.get_name().data(), [component, property] {return property.get_value(component).to_bool(); }, [component, property](bool const& result) {property.set_value(component, result); }, tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string());
|
||||||
}
|
}
|
||||||
//else if (type == rttr::type::get<char>())
|
|
||||||
//{
|
|
||||||
//
|
|
||||||
//}
|
|
||||||
else if (type == rttr::type::get<int8_t>() || type == rttr::type::get<int16_t>() || type == rttr::type::get<int32_t>() || type == rttr::type::get<int64_t>())
|
else if (type == rttr::type::get<int8_t>() || type == rttr::type::get<int16_t>() || type == rttr::type::get<int32_t>() || type == rttr::type::get<int64_t>())
|
||||||
{
|
{
|
||||||
auto metaMin = property.get_metadata(META::min);
|
auto metaMin = property.get_metadata(META::min);
|
||||||
auto metaMax = property.get_metadata(META::max);
|
auto metaMax = property.get_metadata(META::max);
|
||||||
if (metaMin && metaMax)
|
if (metaMin && metaMax)
|
||||||
{
|
{
|
||||||
SHEditorWidgets::SliderInt(property.get_name().data(), metaMin.template get_value<int>(), metaMax.template get_value<int>(), [component, property] {return property.get_value(component).to_int(); }, [component, property](int const& result) {property.set_value(component, result); });
|
SHEditorWidgets::SliderInt(property.get_name().data(), metaMin.template get_value<int>(), metaMax.template get_value<int>(), [component, property] {return property.get_value(component).to_int(); }, [component, property](int const& result) {property.set_value(component, result); }, tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SHEditorWidgets::DragInt(property.get_name().data(), [component, property] {return property.get_value(component).to_int(); }, [component, property](int const& result) {property.set_value(component, result); });
|
SHEditorWidgets::DragInt(property.get_name().data(), [component, property] {return property.get_value(component).to_int(); }, [component, property](int const& result) {property.set_value(component, result); }, tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == rttr::type::get<uint8_t>())
|
else if (type == rttr::type::get<uint8_t>())
|
||||||
|
@ -120,11 +122,11 @@ namespace SHADE
|
||||||
auto metaMax = property.get_metadata(META::max);
|
auto metaMax = property.get_metadata(META::max);
|
||||||
if (metaMin.is_valid() && metaMax.is_valid())
|
if (metaMin.is_valid() && metaMax.is_valid())
|
||||||
{
|
{
|
||||||
SHEditorWidgets::SliderScalar<uint8_t>(property.get_name().data(), ImGuiDataType_U8, metaMin.template get_value<uint8_t>(), metaMax.template get_value<uint8_t>(), [component, property] {return property.get_value(component).to_uint8(); }, [component, property](uint8_t const& result) {property.set_value(component, result); }, "%zu");
|
SHEditorWidgets::SliderScalar<uint8_t>(property.get_name().data(), ImGuiDataType_U8, metaMin.template get_value<uint8_t>(), metaMax.template get_value<uint8_t>(), [component, property] {return property.get_value(component).to_uint8(); }, [component, property](uint8_t const& result) {property.set_value(component, result); }, tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string(), "%zu");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SHEditorWidgets::DragScalar<uint8_t>(property.get_name().data(), ImGuiDataType_U8, [component, property] {return property.get_value(component).to_uint8(); }, [component, property](uint8_t const& result) {property.set_value(component, result); }, 0.1f, 0, 0, "%zu");
|
SHEditorWidgets::DragScalar<uint8_t>(property.get_name().data(), ImGuiDataType_U8, [component, property] {return property.get_value(component).to_uint8(); }, [component, property](uint8_t const& result) {property.set_value(component, result); }, 0.1f, 0, 0, "%zu", tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == rttr::type::get<uint16_t>())
|
else if (type == rttr::type::get<uint16_t>())
|
||||||
|
@ -133,11 +135,11 @@ namespace SHADE
|
||||||
auto metaMax = property.get_metadata(META::max);
|
auto metaMax = property.get_metadata(META::max);
|
||||||
if (metaMin.is_valid() && metaMax.is_valid())
|
if (metaMin.is_valid() && metaMax.is_valid())
|
||||||
{
|
{
|
||||||
SHEditorWidgets::SliderScalar<uint16_t>(property.get_name().data(), ImGuiDataType_U16, metaMin.template get_value<uint16_t>(), metaMax.template get_value<uint16_t>(), [component, property] {return property.get_value(component).to_uint16(); }, [component, property](uint16_t const& result) {property.set_value(component, result); }, "%zu");
|
SHEditorWidgets::SliderScalar<uint16_t>(property.get_name().data(), ImGuiDataType_U16, metaMin.template get_value<uint16_t>(), metaMax.template get_value<uint16_t>(), [component, property] {return property.get_value(component).to_uint16(); }, [component, property](uint16_t const& result) {property.set_value(component, result); }, tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string(), "%zu");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SHEditorWidgets::DragScalar<uint16_t>(property.get_name().data(), ImGuiDataType_U16, [component, property] {return property.get_value(component).to_uint16(); }, [component, property](uint16_t const& result) {property.set_value(component, result); }, 0.1f, 0, 0, "%zu");
|
SHEditorWidgets::DragScalar<uint16_t>(property.get_name().data(), ImGuiDataType_U16, [component, property] {return property.get_value(component).to_uint16(); }, [component, property](uint16_t const& result) {property.set_value(component, result); }, 0.1f, 0, 0, "%zu", tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == rttr::type::get<uint32_t>())
|
else if (type == rttr::type::get<uint32_t>())
|
||||||
|
@ -146,11 +148,11 @@ namespace SHADE
|
||||||
auto metaMax = property.get_metadata(META::max);
|
auto metaMax = property.get_metadata(META::max);
|
||||||
if (metaMin.is_valid() && metaMax.is_valid())
|
if (metaMin.is_valid() && metaMax.is_valid())
|
||||||
{
|
{
|
||||||
SHEditorWidgets::SliderScalar<uint32_t>(property.get_name().data(), ImGuiDataType_U32, metaMin.template get_value<uint32_t>(), metaMax.template get_value<uint32_t>(), [component, property] { return property.get_value(component).to_uint32(); }, [component, property](uint32_t const& result) {property.set_value(component, result); }, "%zu");
|
SHEditorWidgets::SliderScalar<uint32_t>(property.get_name().data(), ImGuiDataType_U32, metaMin.template get_value<uint32_t>(), metaMax.template get_value<uint32_t>(), [component, property] { return property.get_value(component).to_uint32(); }, [component, property](uint32_t const& result) {property.set_value(component, result); }, tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string(), "%zu");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SHEditorWidgets::DragScalar<uint32_t>(property.get_name().data(), ImGuiDataType_U32, [component, property] { return property.get_value(component).to_uint32(); }, [component, property](uint32_t const& result) {property.set_value(component, result); }, 0.1f, 0, 0, "%zu");
|
SHEditorWidgets::DragScalar<uint32_t>(property.get_name().data(), ImGuiDataType_U32, [component, property] { return property.get_value(component).to_uint32(); }, [component, property](uint32_t const& result) {property.set_value(component, result); }, 0.1f, 0, 0, "%zu", tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == rttr::type::get<uint64_t>())
|
else if (type == rttr::type::get<uint64_t>())
|
||||||
|
@ -159,11 +161,11 @@ namespace SHADE
|
||||||
auto metaMax = property.get_metadata(META::max);
|
auto metaMax = property.get_metadata(META::max);
|
||||||
if (metaMin.is_valid() && metaMax.is_valid())
|
if (metaMin.is_valid() && metaMax.is_valid())
|
||||||
{
|
{
|
||||||
SHEditorWidgets::SliderScalar<uint64_t>(property.get_name().data(), ImGuiDataType_U64, metaMin.template get_value<uint64_t>(), metaMax.template get_value<uint64_t>(), [component, property] {return property.get_value(component).to_uint64(); }, [component, property](uint64_t const& result) {property.set_value(component, result); }, "%zu");
|
SHEditorWidgets::SliderScalar<uint64_t>(property.get_name().data(), ImGuiDataType_U64, metaMin.template get_value<uint64_t>(), metaMax.template get_value<uint64_t>(), [component, property] {return property.get_value(component).to_uint64(); }, [component, property](uint64_t const& result) {property.set_value(component, result); }, tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string(), "%zu");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SHEditorWidgets::DragScalar<uint64_t>(property.get_name().data(), ImGuiDataType_U64, [component, property] {return property.get_value(component).to_uint64(); }, [component, property](uint64_t const& result) {property.set_value(component, result); }, 0.1f, 0, 0, "%zu");
|
SHEditorWidgets::DragScalar<uint64_t>(property.get_name().data(), ImGuiDataType_U64, [component, property] {return property.get_value(component).to_uint64(); }, [component, property](uint64_t const& result) {property.set_value(component, result); }, 0.1f, 0, 0, "%zu", tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == rttr::type::get<float>())
|
else if (type == rttr::type::get<float>())
|
||||||
|
@ -177,11 +179,11 @@ namespace SHADE
|
||||||
max = std::min(metaMax.template get_value<float>(), FLT_MAX * 0.5f);
|
max = std::min(metaMax.template get_value<float>(), FLT_MAX * 0.5f);
|
||||||
if (metaMin.is_valid() && metaMax.is_valid())
|
if (metaMin.is_valid() && metaMax.is_valid())
|
||||||
{
|
{
|
||||||
SHEditorWidgets::SliderFloat(property.get_name().data(), min, max, [component, property] {return property.get_value(component).to_float(); }, [component, property](float const& result) {property.set_value(component, result); });
|
SHEditorWidgets::SliderFloat(property.get_name().data(), min, max, [component, property] {return property.get_value(component).to_float(); }, [component, property](float const& result) {property.set_value(component, result); }, tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SHEditorWidgets::DragFloat(property.get_name().data(), [component, property] {return property.get_value(component).to_float(); }, [component, property](float const& result) {property.set_value(component, result); }, "Test");
|
SHEditorWidgets::DragFloat(property.get_name().data(), [component, property] {return property.get_value(component).to_float(); }, [component, property](float const& result) {property.set_value(component, result); }, tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == rttr::type::get<double>())
|
else if (type == rttr::type::get<double>())
|
||||||
|
@ -190,25 +192,25 @@ namespace SHADE
|
||||||
auto metaMax = property.get_metadata(META::max);
|
auto metaMax = property.get_metadata(META::max);
|
||||||
if (metaMin.is_valid() && metaMax.is_valid())
|
if (metaMin.is_valid() && metaMax.is_valid())
|
||||||
{
|
{
|
||||||
SHEditorWidgets::SliderScalar<double>(property.get_name().data(), ImGuiDataType_Double, metaMin.template get_value<double>(), metaMax.template get_value<double>(), [component, property] {return property.get_value(component).to_double(); }, [component, property](double const& result) {property.set_value(component, result); });
|
SHEditorWidgets::SliderScalar<double>(property.get_name().data(), ImGuiDataType_Double, metaMin.template get_value<double>(), metaMax.template get_value<double>(), [component, property] {return property.get_value(component).to_double(); }, [component, property](double const& result) {property.set_value(component, result); }, tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SHEditorWidgets::DragScalar<double>(property.get_name().data(), ImGuiDataType_Double, [component, property] {return property.get_value(component).to_double(); }, [component, property](double const& result) {property.set_value(component, result); }, 0.1f);
|
SHEditorWidgets::DragScalar<double>(property.get_name().data(), ImGuiDataType_Double, [component, property] {return property.get_value(component).to_double(); }, [component, property](double const& result) {property.set_value(component, result); }, 0.1f, {}, {}, "%.3f", tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == rttr::type::get<SHVec4>())
|
else if (type == rttr::type::get<SHVec4>())
|
||||||
{
|
{
|
||||||
SHEditorWidgets::DragVec4(property.get_name().data(), { "X", "Y", "Z", "W" }, [component, property]() {return property.get_value(component).template convert<SHVec4>(); }, [component, property](SHVec4 vec) {return property.set_value(component, vec); });
|
SHEditorWidgets::DragVec4(property.get_name().data(), { "X", "Y", "Z", "W" }, [component, property]() {return property.get_value(component).template convert<SHVec4>(); }, [component, property](SHVec4 vec) {return property.set_value(component, vec); }, isAngleInRad, tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string());
|
||||||
}
|
}
|
||||||
else if (type == rttr::type::get<SHVec3>())
|
else if (type == rttr::type::get<SHVec3>())
|
||||||
{
|
{
|
||||||
SHEditorWidgets::DragVec3(property.get_name().data(), { "X", "Y", "Z" }, [component, property]() {return property.get_value(component).template convert<SHVec3>(); }, [component, property](SHVec3 vec) {return property.set_value(component, vec); });
|
SHEditorWidgets::DragVec3(property.get_name().data(), { "X", "Y", "Z" }, [component, property]() {return property.get_value(component).template convert<SHVec3>(); }, [component, property](SHVec3 vec) {return property.set_value(component, vec); }, isAngleInRad, tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string());
|
||||||
}
|
}
|
||||||
else if (type == rttr::type::get<SHVec2>())
|
else if (type == rttr::type::get<SHVec2>())
|
||||||
{
|
{
|
||||||
SHEditorWidgets::DragVec2(property.get_name().data(), { "X", "Y" }, [component, property]() {return property.get_value(component).template convert<SHVec2>(); }, [component, property](SHVec2 vec) {return property.set_value(component, vec); });
|
SHEditorWidgets::DragVec2(property.get_name().data(), { "X", "Y" }, [component, property]() {return property.get_value(component).template convert<SHVec2>(); }, [component, property](SHVec2 vec) {return property.set_value(component, vec); }, isAngleInRad, tooltip.is_valid() ? tooltip.template get_value<std::string>() : std::string());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -223,10 +225,10 @@ namespace SHADE
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Get transform component for extrapolating relative sizes
|
// Get transform component for extrapolating relative sizes
|
||||||
auto* transformComponent = SHComponentManager::GetComponent<SHTransformComponent>(component->GetEID());
|
auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(component->GetEID());
|
||||||
|
|
||||||
const auto componentType = rttr::type::get(*component);
|
const auto componentType = rttr::type::get(*component);
|
||||||
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; });
|
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
||||||
{
|
{
|
||||||
|
@ -249,7 +251,7 @@ namespace SHADE
|
||||||
SHEditorWidgets::DragVec3
|
SHEditorWidgets::DragVec3
|
||||||
(
|
(
|
||||||
"Half Extents", { "X", "Y", "Z" },
|
"Half Extents", { "X", "Y", "Z" },
|
||||||
[box, transformComponent] { return (transformComponent->GetWorldScale() * 2.0f) * box->GetHalfExtents(); },
|
[box, transformComponent] { return (box->GetHalfExtents() * 2.0f) / transformComponent->GetWorldScale(); },
|
||||||
[collider](SHVec3 const& vec) { collider->SetBoundingBox(vec); });
|
[collider](SHVec3 const& vec) { collider->SetBoundingBox(vec); });
|
||||||
}
|
}
|
||||||
else if (collider->GetType() == SHCollider::Type::SPHERE)
|
else if (collider->GetType() == SHCollider::Type::SPHERE)
|
||||||
|
@ -272,8 +274,27 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
SHEditorWidgets::BeginPanel("Offset", { ImGui::GetContentRegionAvail().x, 30.0f });
|
SHEditorWidgets::BeginPanel("Offsets",{ ImGui::GetContentRegionAvail().x, 30.0f });
|
||||||
SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [&collider] {return collider->GetPositionOffset(); }, [&collider](SHVec3 const& vec) {collider->SetPositionOffset(vec); });
|
SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [&collider] {return collider->GetPositionOffset(); }, [&collider](SHVec3 const& vec) {collider->SetPositionOffset(vec); });
|
||||||
|
SHEditorWidgets::DragVec3("Rotation", { "X", "Y", "Z" },
|
||||||
|
[&collider]
|
||||||
|
{
|
||||||
|
auto offset = collider->GetRotationOffset();
|
||||||
|
offset.x = SHMath::RadiansToDegrees(offset.x);
|
||||||
|
offset.y = SHMath::RadiansToDegrees(offset.y);
|
||||||
|
offset.z = SHMath::RadiansToDegrees(offset.z);
|
||||||
|
return offset;
|
||||||
|
},
|
||||||
|
[&collider](SHVec3 const& vec)
|
||||||
|
{
|
||||||
|
const SHVec3 vecInRad
|
||||||
|
{
|
||||||
|
SHMath::DegreesToRadians(vec.x)
|
||||||
|
, SHMath::DegreesToRadians(vec.y)
|
||||||
|
, SHMath::DegreesToRadians(vec.z)
|
||||||
|
};
|
||||||
|
collider->SetRotationOffset(vecInRad);
|
||||||
|
});
|
||||||
SHEditorWidgets::EndPanel();
|
SHEditorWidgets::EndPanel();
|
||||||
}
|
}
|
||||||
if (ImGui::Button(std::format("{} Remove Collider #{}", ICON_MD_REMOVE, i).data()))
|
if (ImGui::Button(std::format("{} Remove Collider #{}", ICON_MD_REMOVE, i).data()))
|
||||||
|
@ -311,7 +332,7 @@ namespace SHADE
|
||||||
if (!component)
|
if (!component)
|
||||||
return;
|
return;
|
||||||
const auto componentType = rttr::type::get(*component);
|
const auto componentType = rttr::type::get(*component);
|
||||||
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; });
|
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
||||||
{
|
{
|
||||||
|
@ -334,4 +355,34 @@ namespace SHADE
|
||||||
DrawContextMenu(component);
|
DrawContextMenu(component);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
static void DrawComponent(SHRenderable* component)
|
||||||
|
{
|
||||||
|
if (!component)
|
||||||
|
return;
|
||||||
|
const auto componentType = rttr::type::get(*component);
|
||||||
|
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
||||||
|
{
|
||||||
|
DrawContextMenu(component);
|
||||||
|
Handle<SHMesh> const& mesh = component->GetMesh();
|
||||||
|
|
||||||
|
SHEditorWidgets::DragDropReadOnlyField<AssetID>("Mesh", std::to_string(SHResourceManager::GetAssetID<SHMesh>(mesh).value_or(0)).data(), [component]()
|
||||||
|
{
|
||||||
|
Handle<SHMesh> const& mesh = component->GetMesh();
|
||||||
|
return SHResourceManager::GetAssetID<SHMesh>(mesh).value_or(0);
|
||||||
|
},
|
||||||
|
[component](AssetID const& id)
|
||||||
|
{
|
||||||
|
component->SetMesh(SHResourceManager::LoadOrGet<SHMesh>(id));
|
||||||
|
SHResourceManager::FinaliseChanges();
|
||||||
|
}, SHDragDrop::DRAG_RESOURCE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DrawContextMenu(component);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
#include "SHpch.h"
|
#include "SHpch.h"
|
||||||
|
|
||||||
#include "Editor/SHEditor.hpp"
|
#include "Editor/SHEditor.h"
|
||||||
#include "SHEditorInspector.h"
|
#include "SHEditorInspector.h"
|
||||||
|
|
||||||
#include "ECS_Base/SHECSMacros.h"
|
#include "ECS_Base/SHECSMacros.h"
|
||||||
|
@ -10,17 +10,15 @@
|
||||||
|
|
||||||
#include "Editor/SHImGuiHelpers.hpp"
|
#include "Editor/SHImGuiHelpers.hpp"
|
||||||
#include "Editor/SHEditorWidgets.hpp"
|
#include "Editor/SHEditorWidgets.hpp"
|
||||||
#include "SHEditorComponentView.hpp"
|
|
||||||
#include "ECS_Base/UnitTesting/SHTestComponents.h"
|
|
||||||
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||||
#include "Scripting/SHScriptEngine.h"
|
#include "Scripting/SHScriptEngine.h"
|
||||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
|
||||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
|
||||||
#include "AudioSystem/SHAudioSystem.h"
|
|
||||||
#include "Physics/Components/SHRigidBodyComponent.h"
|
#include "Physics/Components/SHRigidBodyComponent.h"
|
||||||
#include "Physics/Components/SHColliderComponent.h"
|
#include "Physics/Components/SHColliderComponent.h"
|
||||||
#include "Camera/SHCameraComponent.h"
|
#include "Camera/SHCameraComponent.h"
|
||||||
|
#include "Camera/SHCameraArmComponent.h"
|
||||||
|
#include "SHEditorComponentView.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -30,8 +28,17 @@ namespace SHADE
|
||||||
bool selected = false;
|
bool selected = false;
|
||||||
if(!SHComponentManager::HasComponent<ComponentType>(eid))
|
if(!SHComponentManager::HasComponent<ComponentType>(eid))
|
||||||
{
|
{
|
||||||
if(selected = ImGui::Selectable(std::format("Add {}", rttr::type::get<ComponentType>().get_name().data()).data()); selected)
|
const char* componentName = rttr::type::get<ComponentType>().get_name().data();
|
||||||
|
if(selected = ImGui::Selectable(std::format("Add {}", componentName).data()); selected)
|
||||||
SHComponentManager::AddComponent<ComponentType>(eid);
|
SHComponentManager::AddComponent<ComponentType>(eid);
|
||||||
|
if(ImGui::IsItemHovered())
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text("Adds", componentName); ImGui::SameLine();
|
||||||
|
ImGui::TextColored(ImGuiColors::green, "%s", componentName); ImGui::SameLine();
|
||||||
|
ImGui::Text("to this entity", componentName);
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return selected;
|
return selected;
|
||||||
}
|
}
|
||||||
|
@ -42,13 +49,26 @@ namespace SHADE
|
||||||
bool selected = false;
|
bool selected = false;
|
||||||
if (!SHComponentManager::HasComponent<ComponentType>(eid))
|
if (!SHComponentManager::HasComponent<ComponentType>(eid))
|
||||||
{
|
{
|
||||||
if(selected = ImGui::Selectable(std::format("Add {}", rttr::type::get<ComponentType>().get_name().data()).data()); selected)
|
const char* componentName = rttr::type::get<ComponentType>().get_name().data();
|
||||||
|
|
||||||
|
if(selected = ImGui::Selectable(std::format("Add {}", componentName).data()); selected)
|
||||||
{
|
{
|
||||||
if(SHComponentManager::GetComponent_s<EnforcedComponent>(eid) == nullptr)
|
if(SHComponentManager::GetComponent_s<EnforcedComponent>(eid) == nullptr)
|
||||||
SHComponentManager::AddComponent<EnforcedComponent>(eid);
|
SHComponentManager::AddComponent<EnforcedComponent>(eid);
|
||||||
|
|
||||||
SHComponentManager::AddComponent<ComponentType>(eid);
|
SHComponentManager::AddComponent<ComponentType>(eid);
|
||||||
}
|
}
|
||||||
|
if(ImGui::IsItemHovered())
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text("Adds", componentName); ImGui::SameLine();
|
||||||
|
ImGui::TextColored(ImGuiColors::green, "%s", componentName); ImGui::SameLine();
|
||||||
|
ImGui::Text("to this entity", componentName);
|
||||||
|
ImGui::Text("Adds"); ImGui::SameLine();
|
||||||
|
ImGui::TextColored(ImGuiColors::red, "%s", rttr::type::get<EnforcedComponent>().get_name().data()); ImGui::SameLine();
|
||||||
|
ImGui::Text("if the entity does not already have it");
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return selected;
|
return selected;
|
||||||
}
|
}
|
||||||
|
@ -107,6 +127,9 @@ namespace SHADE
|
||||||
if (auto cameraComponent = SHComponentManager::GetComponent_s<SHCameraComponent>(eid))
|
if (auto cameraComponent = SHComponentManager::GetComponent_s<SHCameraComponent>(eid))
|
||||||
{
|
{
|
||||||
DrawComponent(cameraComponent);
|
DrawComponent(cameraComponent);
|
||||||
|
}if (auto cameraArmComponent = SHComponentManager::GetComponent_s<SHCameraArmComponent>(eid))
|
||||||
|
{
|
||||||
|
DrawComponent(cameraArmComponent);
|
||||||
}
|
}
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
// Render Scripts
|
// Render Scripts
|
||||||
|
@ -117,6 +140,8 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
DrawAddComponentButton<SHTransformComponent>(eid);
|
DrawAddComponentButton<SHTransformComponent>(eid);
|
||||||
DrawAddComponentButton<SHCameraComponent>(eid);
|
DrawAddComponentButton<SHCameraComponent>(eid);
|
||||||
|
DrawAddComponentButton<SHCameraArmComponent>(eid);
|
||||||
|
DrawAddComponentButton<SHLightComponent>(eid);
|
||||||
|
|
||||||
// Components that require Transforms
|
// Components that require Transforms
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| SHADE Includes ||
|
//|| SHADE Includes ||
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
#include "Editor/SHEditor.hpp"
|
#include "Editor/SHEditor.h"
|
||||||
#include "SHEditorMenuBar.h"
|
#include "SHEditorMenuBar.h"
|
||||||
#include "Editor/IconsMaterialDesign.h"
|
#include "Editor/IconsMaterialDesign.h"
|
||||||
#include "Editor/Command/SHCommandManager.h"
|
#include "Editor/Command/SHCommandManager.h"
|
||||||
|
@ -175,19 +175,37 @@ namespace SHADE
|
||||||
ImGui::BeginDisabled(editor->editorState == SHEditor::State::PLAY);
|
ImGui::BeginDisabled(editor->editorState == SHEditor::State::PLAY);
|
||||||
if(ImGui::SmallButton(ICON_MD_PLAY_ARROW))
|
if(ImGui::SmallButton(ICON_MD_PLAY_ARROW))
|
||||||
{
|
{
|
||||||
|
const SHEditorStateChangeEvent STATE_CHANGE_EVENT
|
||||||
|
{
|
||||||
|
.previousState = editor->editorState
|
||||||
|
};
|
||||||
editor->editorState = SHEditor::State::PLAY;
|
editor->editorState = SHEditor::State::PLAY;
|
||||||
|
|
||||||
|
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_PLAY_EVENT);
|
||||||
}
|
}
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
ImGui::BeginDisabled(editor->editorState == SHEditor::State::PAUSE);
|
ImGui::BeginDisabled(editor->editorState == SHEditor::State::PAUSE);
|
||||||
if(ImGui::SmallButton(ICON_MD_PAUSE))
|
if(ImGui::SmallButton(ICON_MD_PAUSE))
|
||||||
{
|
{
|
||||||
|
const SHEditorStateChangeEvent STATE_CHANGE_EVENT
|
||||||
|
{
|
||||||
|
.previousState = editor->editorState
|
||||||
|
};
|
||||||
editor->editorState = SHEditor::State::PAUSE;
|
editor->editorState = SHEditor::State::PAUSE;
|
||||||
|
|
||||||
|
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_PAUSE_EVENT);
|
||||||
}
|
}
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
ImGui::BeginDisabled(editor->editorState == SHEditor::State::STOP);
|
ImGui::BeginDisabled(editor->editorState == SHEditor::State::STOP);
|
||||||
if(ImGui::SmallButton(ICON_MD_STOP))
|
if(ImGui::SmallButton(ICON_MD_STOP))
|
||||||
{
|
{
|
||||||
|
const SHEditorStateChangeEvent STATE_CHANGE_EVENT
|
||||||
|
{
|
||||||
|
.previousState = editor->editorState
|
||||||
|
};
|
||||||
editor->editorState = SHEditor::State::STOP;
|
editor->editorState = SHEditor::State::STOP;
|
||||||
|
|
||||||
|
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_STOP_EVENT);
|
||||||
}
|
}
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
ImGui::EndMenuBar();
|
ImGui::EndMenuBar();
|
||||||
|
|
|
@ -20,4 +20,10 @@ namespace SHADE
|
||||||
float menuBarHeight = 20.0f;
|
float menuBarHeight = 20.0f;
|
||||||
std::vector<std::filesystem::path> layoutPaths;
|
std::vector<std::filesystem::path> layoutPaths;
|
||||||
};//class SHEditorMenuBar
|
};//class SHEditorMenuBar
|
||||||
|
|
||||||
|
struct SHEditorStateChangeEvent
|
||||||
|
{
|
||||||
|
SHEditor::State previousState;
|
||||||
|
};
|
||||||
|
|
||||||
}//namespace SHADE
|
}//namespace SHADE
|
|
@ -5,13 +5,16 @@
|
||||||
#include "ImGuizmo.h"
|
#include "ImGuizmo.h"
|
||||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
#include "Editor/IconsMaterialDesign.h"
|
#include "Editor/IconsMaterialDesign.h"
|
||||||
#include "Editor/SHEditor.hpp"
|
#include "Editor/SHEditor.h"
|
||||||
#include "Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h"
|
#include "Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
||||||
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h"
|
#include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h"
|
||||||
#include <Editor/IconsFontAwesome6.h>
|
#include <Editor/IconsFontAwesome6.h>
|
||||||
|
|
||||||
|
#include "Camera/SHCameraSystem.h"
|
||||||
|
#include "FRC/SHFramerateController.h"
|
||||||
|
|
||||||
constexpr std::string_view windowName = "\xef\x80\x95 Viewport";
|
constexpr std::string_view windowName = "\xef\x80\x95 Viewport";
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
|
@ -30,7 +33,14 @@ namespace SHADE
|
||||||
void SHEditorViewport::Update()
|
void SHEditorViewport::Update()
|
||||||
{
|
{
|
||||||
SHEditorWindow::Update();
|
SHEditorWindow::Update();
|
||||||
|
if (shouldUpdateCamera)
|
||||||
|
{
|
||||||
|
auto camSystem = SHSystemManager::GetSystem<SHCameraSystem>();
|
||||||
|
camSystem->UpdateEditorCamera(SHFrameRateController::GetRawDeltaTime());
|
||||||
|
shouldUpdateCamera = false;
|
||||||
|
}
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
||||||
|
|
||||||
if (Begin())
|
if (Begin())
|
||||||
{
|
{
|
||||||
ImGuizmo::SetDrawlist();
|
ImGuizmo::SetDrawlist();
|
||||||
|
@ -51,6 +61,23 @@ namespace SHADE
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text, ImGuiColors::green);
|
ImGui::PushStyleColor(ImGuiCol_Text, ImGuiColors::green);
|
||||||
ImGui::Text(ICON_FA_EYE);
|
ImGui::Text(ICON_FA_EYE);
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
|
|
||||||
|
shouldUpdateCamera = true;
|
||||||
|
}
|
||||||
|
if (ImGui::IsWindowFocused() && !ImGui::IsMouseDown(ImGuiMouseButton_Right))
|
||||||
|
{
|
||||||
|
if (ImGui::IsKeyReleased(ImGuiKey_Q))
|
||||||
|
{
|
||||||
|
transformGizmo.operation = SHTransformGizmo::Operation::TRANSLATE;
|
||||||
|
}
|
||||||
|
if (ImGui::IsKeyReleased(ImGuiKey_W))
|
||||||
|
{
|
||||||
|
transformGizmo.operation = SHTransformGizmo::Operation::ROTATE;
|
||||||
|
}
|
||||||
|
if (ImGui::IsKeyReleased(ImGuiKey_E))
|
||||||
|
{
|
||||||
|
transformGizmo.operation = SHTransformGizmo::Operation::SCALE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGuizmo::SetRect(beginCursorPos.x, beginCursorPos.y, beginContentRegionAvailable.x, beginContentRegionAvailable.y);
|
ImGuizmo::SetRect(beginCursorPos.x, beginCursorPos.y, beginContentRegionAvailable.x, beginContentRegionAvailable.y);
|
||||||
|
@ -77,6 +104,7 @@ namespace SHADE
|
||||||
beginContentRegionAvailable = windowSize;
|
beginContentRegionAvailable = windowSize;
|
||||||
}
|
}
|
||||||
gfxSystem->PrepareResize(static_cast<uint32_t>(beginContentRegionAvailable.x), static_cast<uint32_t>(beginContentRegionAvailable.y));
|
gfxSystem->PrepareResize(static_cast<uint32_t>(beginContentRegionAvailable.x), static_cast<uint32_t>(beginContentRegionAvailable.y));
|
||||||
|
shouldUpdateCamera = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHEditorViewport::OnPosChange()
|
void SHEditorViewport::OnPosChange()
|
||||||
|
@ -88,6 +116,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if (ImGui::BeginMenuBar())
|
if (ImGui::BeginMenuBar())
|
||||||
{
|
{
|
||||||
|
ImGui::BeginDisabled(ImGui::IsWindowFocused() && ImGui::IsMouseDown(ImGuiMouseButton_Right));
|
||||||
bool const isTranslate = transformGizmo.operation == SHTransformGizmo::Operation::TRANSLATE;
|
bool const isTranslate = transformGizmo.operation == SHTransformGizmo::Operation::TRANSLATE;
|
||||||
ImGui::BeginDisabled(isTranslate);
|
ImGui::BeginDisabled(isTranslate);
|
||||||
if (isTranslate)
|
if (isTranslate)
|
||||||
|
@ -97,6 +126,12 @@ namespace SHADE
|
||||||
transformGizmo.operation = SHTransformGizmo::Operation::TRANSLATE;
|
transformGizmo.operation = SHTransformGizmo::Operation::TRANSLATE;
|
||||||
}
|
}
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
|
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text("Translate [Q]");
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
if (isTranslate)
|
if (isTranslate)
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
|
|
||||||
|
@ -109,6 +144,12 @@ namespace SHADE
|
||||||
transformGizmo.operation = SHTransformGizmo::Operation::ROTATE;
|
transformGizmo.operation = SHTransformGizmo::Operation::ROTATE;
|
||||||
}
|
}
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
|
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text("Rotate [W]");
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
if (isRotate)
|
if (isRotate)
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
|
|
||||||
|
@ -121,9 +162,15 @@ namespace SHADE
|
||||||
transformGizmo.operation = SHTransformGizmo::Operation::SCALE;
|
transformGizmo.operation = SHTransformGizmo::Operation::SCALE;
|
||||||
}
|
}
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
|
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text("Scale [E]");
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
if (isScale)
|
if (isScale)
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
|
ImGui::EndDisabled();
|
||||||
ImGui::EndMenuBar();
|
ImGui::EndMenuBar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,5 +28,6 @@ namespace SHADE
|
||||||
private:
|
private:
|
||||||
void DrawMenuBar() noexcept;
|
void DrawMenuBar() noexcept;
|
||||||
SHVec2 beginCursorPos;
|
SHVec2 beginCursorPos;
|
||||||
|
bool shouldUpdateCamera = false;
|
||||||
};//class SHEditorViewport
|
};//class SHEditorViewport
|
||||||
}//namespace SHADE
|
}//namespace SHADE
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include "ECS_Base/Managers/SHComponentManager.h"
|
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
#include "Editor/SHEditor.hpp"
|
#include "Editor/SHEditor.h"
|
||||||
#include "Editor/SHImGuiHelpers.hpp"
|
#include "Editor/SHImGuiHelpers.hpp"
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
#include <ImGuizmo.h>
|
#include <ImGuizmo.h>
|
||||||
|
@ -63,6 +63,9 @@ namespace SHADE
|
||||||
if (selectedEntityTransformComponent == nullptr)
|
if (selectedEntityTransformComponent == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if(!selectedEntityTransformComponent->isActive)
|
||||||
|
return;
|
||||||
|
|
||||||
SHMatrix mat = selectedEntityTransformComponent->GetTRS();
|
SHMatrix mat = selectedEntityTransformComponent->GetTRS();
|
||||||
useSnap = ImGui::IsKeyDown(ImGuiKey_LeftCtrl);
|
useSnap = ImGui::IsKeyDown(ImGuiKey_LeftCtrl);
|
||||||
if(useSnap)
|
if(useSnap)
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#include "Graphics/MiddleEnd/Interface/SHViewport.h"
|
#include "Graphics/MiddleEnd/Interface/SHViewport.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHRenderer.h"
|
#include "Graphics/MiddleEnd/Interface/SHRenderer.h"
|
||||||
|
|
||||||
#include "SHEditor.hpp"
|
#include "SHEditor.h"
|
||||||
#include "SHEditorWidgets.hpp"
|
#include "SHEditorWidgets.hpp"
|
||||||
|
|
||||||
#include "Math/Transform/SHTransformSystem.h"
|
#include "Math/Transform/SHTransformSystem.h"
|
||||||
|
@ -175,7 +175,7 @@ namespace SHADE
|
||||||
ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.GlyphOffset.y = 5.f;
|
ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.GlyphOffset.y = 5.f;
|
||||||
constexpr ImWchar icon_ranges_fa[] = { ICON_MIN_FA, ICON_MAX_FA, 0 };
|
constexpr ImWchar icon_ranges_fa[] = { ICON_MIN_FA, ICON_MAX_FA, 0 };
|
||||||
ImFont* UIFontFA = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/fa-solid-900.ttf", 20.f, &icons_config, icon_ranges_fa); //TODO: Change to config based assets path
|
ImFont* UIFontFA = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/fa-solid-900.ttf", 20.f, &icons_config, icon_ranges_fa); //TODO: Change to config based assets path
|
||||||
constexpr ImWchar icon_ranges_md[] = { ICON_MIN_MD, ICON_MAX_MD, 0 };
|
constexpr ImWchar icon_ranges_md[] = { ICON_MIN_MD, ICON_MAX_16_MD, 0 };
|
||||||
ImFont* UIFontMD = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/MaterialIcons-Regular.ttf", 20.f, &icons_config, icon_ranges_md); //TODO: Change to config based assets path
|
ImFont* UIFontMD = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/MaterialIcons-Regular.ttf", 20.f, &icons_config, icon_ranges_md); //TODO: Change to config based assets path
|
||||||
io->Fonts->Build();
|
io->Fonts->Build();
|
||||||
}
|
}
|
||||||
|
@ -293,6 +293,7 @@ namespace SHADE
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
void SHEditor::InitBackend()
|
void SHEditor::InitBackend()
|
||||||
{
|
{
|
||||||
|
#ifdef SHEDITOR
|
||||||
if(ImGui_ImplSDL2_InitForVulkan(sdlWindow) == false)
|
if(ImGui_ImplSDL2_InitForVulkan(sdlWindow) == false)
|
||||||
{
|
{
|
||||||
SHLOG_CRITICAL("Editor backend initialisation; Failed to perform SDL initialisation for Vulkan")
|
SHLOG_CRITICAL("Editor backend initialisation; Failed to perform SDL initialisation for Vulkan")
|
||||||
|
@ -339,6 +340,7 @@ namespace SHADE
|
||||||
renderGraph->GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle<SHVkCommandBuffer>& cmd) {
|
renderGraph->GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle<SHVkCommandBuffer>& cmd) {
|
||||||
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->GetVkCommandBuffer());
|
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->GetVkCommandBuffer());
|
||||||
});
|
});
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHEditor::PollPicking()
|
void SHEditor::PollPicking()
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#include "ECS_Base/System/SHSystemRoutine.h"
|
#include "ECS_Base/System/SHSystemRoutine.h"
|
||||||
#include "Resource/SHHandle.h"
|
#include "Resource/SHHandle.h"
|
||||||
#include "EditorWindow/SHEditorWindow.h"
|
#include "EditorWindow/SHEditorWindow.h"
|
||||||
#include "Tools/SHLogger.h"
|
#include "Tools/SHLog.h"
|
||||||
#include "Gizmos/SHTransformGizmo.h"
|
#include "Gizmos/SHTransformGizmo.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SHLOG_WARNING("Attempt to create duplicate of Editor window type")
|
SHLog::Warning("Attempt to create duplicate of Editor window type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
// External Dependencies
|
// External Dependencies
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
#include "SHEditorWidgets.hpp"
|
#include "SHEditorWidgets.hpp"
|
||||||
|
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -156,7 +157,7 @@ namespace SHADE
|
||||||
if (isHovered)
|
if (isHovered)
|
||||||
*isHovered = ImGui::IsItemHovered();
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
return ImGui::Checkbox("#", &value);
|
return ImGui::Checkbox("##", &value);
|
||||||
}
|
}
|
||||||
bool SHEditorUI::InputInt(const std::string& label, int& value, bool* isHovered)
|
bool SHEditorUI::InputInt(const std::string& label, int& value, bool* isHovered)
|
||||||
{
|
{
|
||||||
|
@ -164,7 +165,7 @@ namespace SHADE
|
||||||
if (isHovered)
|
if (isHovered)
|
||||||
*isHovered = ImGui::IsItemHovered();
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
return ImGui::InputInt("#", &value,
|
return ImGui::InputInt("##", &value,
|
||||||
1, 10,
|
1, 10,
|
||||||
ImGuiInputTextFlags_EnterReturnsTrue);
|
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||||
}
|
}
|
||||||
|
@ -175,7 +176,7 @@ namespace SHADE
|
||||||
if (isHovered)
|
if (isHovered)
|
||||||
*isHovered = ImGui::IsItemHovered();
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
const bool CHANGED = InputInt("#", signedVal);
|
const bool CHANGED = InputInt("##", signedVal);
|
||||||
if (CHANGED)
|
if (CHANGED)
|
||||||
{
|
{
|
||||||
signedVal = std::clamp(signedVal, 0, std::numeric_limits<int>::max());
|
signedVal = std::clamp(signedVal, 0, std::numeric_limits<int>::max());
|
||||||
|
@ -189,7 +190,7 @@ namespace SHADE
|
||||||
if (isHovered)
|
if (isHovered)
|
||||||
*isHovered = ImGui::IsItemHovered();
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
return ImGui::InputFloat("#", &value,
|
return ImGui::InputFloat("##", &value,
|
||||||
0.1f, 1.0f, "%.3f",
|
0.1f, 1.0f, "%.3f",
|
||||||
ImGuiInputTextFlags_EnterReturnsTrue);
|
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||||
}
|
}
|
||||||
|
@ -199,7 +200,7 @@ namespace SHADE
|
||||||
if (isHovered)
|
if (isHovered)
|
||||||
*isHovered = ImGui::IsItemHovered();
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
return ImGui::InputDouble("#", &value,
|
return ImGui::InputDouble("##", &value,
|
||||||
0.1, 1.0, "%.3f",
|
0.1, 1.0, "%.3f",
|
||||||
ImGuiInputTextFlags_EnterReturnsTrue);
|
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||||
}
|
}
|
||||||
|
@ -209,7 +210,7 @@ namespace SHADE
|
||||||
if (isHovered)
|
if (isHovered)
|
||||||
*isHovered = ImGui::IsItemHovered();
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
return ImGui::InputDouble("#", &value,
|
return ImGui::InputDouble("##", &value,
|
||||||
1.0, 45.0, "%.3f",
|
1.0, 45.0, "%.3f",
|
||||||
ImGuiInputTextFlags_EnterReturnsTrue);
|
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||||
}
|
}
|
||||||
|
@ -279,7 +280,7 @@ namespace SHADE
|
||||||
if (isHovered)
|
if (isHovered)
|
||||||
*isHovered = ImGui::IsItemHovered();
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
const bool CHANGED = ImGui::InputText("#", &buffer[0], TEXT_FIELD_MAX_LENGTH);
|
const bool CHANGED = ImGui::InputText("##", &buffer[0], TEXT_FIELD_MAX_LENGTH);
|
||||||
if (CHANGED)
|
if (CHANGED)
|
||||||
{
|
{
|
||||||
value = std::string(buffer.data(), buffer.data() + TEXT_FIELD_MAX_LENGTH);
|
value = std::string(buffer.data(), buffer.data() + TEXT_FIELD_MAX_LENGTH);
|
||||||
|
@ -287,6 +288,35 @@ namespace SHADE
|
||||||
return CHANGED;
|
return CHANGED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SHEditorUI::InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered)
|
||||||
|
{
|
||||||
|
ImGui::Text(label.c_str());
|
||||||
|
if (isHovered)
|
||||||
|
*isHovered = ImGui::IsItemHovered();
|
||||||
|
ImGui::SameLine();
|
||||||
|
SHEntity* entity = SHEntityManager::GetEntityByID(value);
|
||||||
|
std::ostringstream oss;
|
||||||
|
if (entity)
|
||||||
|
{
|
||||||
|
oss << value << ": " << entity->name;
|
||||||
|
}
|
||||||
|
std::string entityName = oss.str();
|
||||||
|
bool changed = ImGui::InputText("##", &entityName, ImGuiInputTextFlags_ReadOnly);
|
||||||
|
if (SHDragDrop::BeginTarget())
|
||||||
|
{
|
||||||
|
if (const std::vector<EntityID>* payload = SHDragDrop::AcceptPayload<std::vector<EntityID>>(SHDragDrop::DRAG_EID))
|
||||||
|
{
|
||||||
|
if (!payload->empty())
|
||||||
|
{
|
||||||
|
value = payload->at(0);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
SHDragDrop::EndTarget();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
bool SHEditorUI::InputEnumCombo(const std::string& label, int& v, const std::vector<std::string>& enumNames, bool* isHovered)
|
bool SHEditorUI::InputEnumCombo(const std::string& label, int& v, const std::vector<std::string>& enumNames, bool* isHovered)
|
||||||
{
|
{
|
||||||
// Clamp input value
|
// Clamp input value
|
||||||
|
@ -297,7 +327,7 @@ namespace SHADE
|
||||||
if (isHovered)
|
if (isHovered)
|
||||||
*isHovered = ImGui::IsItemHovered();
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::BeginCombo("#", INITIAL_NAME.c_str(), ImGuiComboFlags_None))
|
if (ImGui::BeginCombo("##", INITIAL_NAME.c_str(), ImGuiComboFlags_None))
|
||||||
{
|
{
|
||||||
for (int i = 0; i < enumNames.size(); ++i)
|
for (int i = 0; i < enumNames.size(); ++i)
|
||||||
{
|
{
|
||||||
|
|
|
@ -308,6 +308,14 @@ namespace SHADE
|
||||||
/// <returns>True if the value was changed.</returns>
|
/// <returns>True if the value was changed.</returns>
|
||||||
static bool InputTextField(const std::string& label, std::string& value, bool* isHovered = nullptr);
|
static bool InputTextField(const std::string& label, std::string& value, bool* isHovered = nullptr);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// Creates a drag field widget for int input.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="label">Label used to identify this widget.</param>
|
||||||
|
/// <param name="value">Reference to the variable to store the result.</param>
|
||||||
|
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||||
|
/// <returns>True if the value was changed.</returns>
|
||||||
|
static bool InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered = nullptr);
|
||||||
|
/// <summary>
|
||||||
/// Creates a combo box for enumeration input.
|
/// Creates a combo box for enumeration input.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="Enum">The type of enum to input.</typeparam>
|
/// <typeparam name="Enum">The type of enum to input.</typeparam>
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
#include <misc/cpp/imgui_stdlib.h>
|
#include <misc/cpp/imgui_stdlib.h>
|
||||||
#include <rttr/type.h>
|
#include <rttr/type.h>
|
||||||
|
|
||||||
|
#include "DragDrop/SHDragDrop.hpp"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
class SH_API SHEditorWidgets
|
class SH_API SHEditorWidgets
|
||||||
|
@ -41,7 +43,7 @@ namespace SHADE
|
||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
|
|
||||||
auto itemSpacing = ImGui::GetStyle().ItemSpacing;
|
auto itemSpacing = ImGui::GetStyle().ItemSpacing;
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f));
|
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.2f));
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
|
||||||
|
|
||||||
auto frameHeight = ImGui::GetFrameHeight();
|
auto frameHeight = ImGui::GetFrameHeight();
|
||||||
|
@ -86,7 +88,7 @@ namespace SHADE
|
||||||
|
|
||||||
auto itemSpacing = ImGui::GetStyle().ItemSpacing;
|
auto itemSpacing = ImGui::GetStyle().ItemSpacing;
|
||||||
|
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f));
|
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.2f));
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
|
||||||
|
|
||||||
auto frameHeight = ImGui::GetFrameHeight();
|
auto frameHeight = ImGui::GetFrameHeight();
|
||||||
|
@ -127,7 +129,7 @@ namespace SHADE
|
||||||
|
|
||||||
ImGui::GetWindowDrawList()->AddRect(
|
ImGui::GetWindowDrawList()->AddRect(
|
||||||
frameRect.Min, frameRect.Max,
|
frameRect.Min, frameRect.Max,
|
||||||
ImColor(ImGui::GetStyleColorVec4(ImGuiCol_Button)),
|
ImColor(ImGui::GetStyleColorVec4(ImGuiCol_TextDisabled)),
|
||||||
halfFrame.x);
|
halfFrame.x);
|
||||||
|
|
||||||
ImGui::PopClipRect();
|
ImGui::PopClipRect();
|
||||||
|
@ -174,15 +176,19 @@ namespace SHADE
|
||||||
ImGui::SetColumnWidth(-1, 80.0f);
|
ImGui::SetColumnWidth(-1, 80.0f);
|
||||||
ImGui::Text(label.c_str());
|
ImGui::Text(label.c_str());
|
||||||
if (isHovered)
|
if (isHovered)
|
||||||
*isHovered = ImGui::IsItemHovered();
|
*isHovered |= ImGui::IsItemHovered();
|
||||||
ImGui::NextColumn();
|
ImGui::NextColumn();
|
||||||
for (std::size_t i = 0; i < N; ++i)
|
for (std::size_t i = 0; i < N; ++i)
|
||||||
{
|
{
|
||||||
ImGui::PushID(static_cast<int>(i));
|
ImGui::PushID(static_cast<int>(i));
|
||||||
ImGui::TextUnformatted(componentLabels[i].c_str(), ImGui::FindRenderedTextEnd(componentLabels[i].c_str())); ImGui::SameLine();
|
ImGui::TextUnformatted(componentLabels[i].c_str(), ImGui::FindRenderedTextEnd(componentLabels[i].c_str()));
|
||||||
|
if (isHovered)
|
||||||
|
*isHovered |= ImGui::IsItemHovered();
|
||||||
|
ImGui::SameLine();
|
||||||
ImGui::SetNextItemWidth(80.0f);
|
ImGui::SetNextItemWidth(80.0f);
|
||||||
valueChanged |= ImGui::DragFloat("##v", values[i], speed, valueMin, valueMax, displayFormat, flags);
|
valueChanged |= ImGui::DragFloat("##v", values[i], speed, valueMin, valueMax, displayFormat, flags);
|
||||||
|
if (isHovered)
|
||||||
|
*isHovered |= ImGui::IsItemHovered();
|
||||||
const ImVec2 min = ImGui::GetItemRectMin();
|
const ImVec2 min = ImGui::GetItemRectMin();
|
||||||
const ImVec2 max = ImGui::GetItemRectMax();
|
const ImVec2 max = ImGui::GetItemRectMax();
|
||||||
const float spacing = g.Style.FrameRounding;
|
const float spacing = g.Style.FrameRounding;
|
||||||
|
@ -203,14 +209,22 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool DragVec2(const std::string& label, std::vector<std::string>const& componentLabels, std::function<SHVec2(void)> get,
|
static bool DragVec2(const std::string& label, std::vector<std::string>const& componentLabels, std::function<SHVec2(void)> get,
|
||||||
std::function<void(SHVec2)> set, float speed = 0.1f, const char* displayFormat = "%.3f", std::string_view const& tooltip = {}, float valueMin = 0.0f, float valueMax = 0.0f,
|
std::function<void(SHVec2)> set, bool const& isAnAngleInRad = false, std::string_view const& tooltip = {}, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f,
|
||||||
ImGuiSliderFlags flags = 0)
|
ImGuiSliderFlags flags = 0)
|
||||||
{
|
{
|
||||||
SHVec2 values = get();
|
SHVec2 values = get();
|
||||||
|
if(isAnAngleInRad)
|
||||||
|
{
|
||||||
|
values = {SHMath::RadiansToDegrees(values.x), SHMath::RadiansToDegrees(values.y)};
|
||||||
|
}
|
||||||
bool const changed = DragN<float, 2>(label, componentLabels, { &values.x, &values.y }, speed, displayFormat, valueMin, valueMax, flags);
|
bool const changed = DragN<float, 2>(label, componentLabels, { &values.x, &values.y }, speed, displayFormat, valueMin, valueMax, flags);
|
||||||
static bool startRecording = false;
|
static bool startRecording = false;
|
||||||
if (changed)
|
if (changed)
|
||||||
{
|
{
|
||||||
|
if(isAnAngleInRad)
|
||||||
|
{
|
||||||
|
values = {SHMath::DegreesToRadians(values.x), SHMath::DegreesToRadians(values.y)};
|
||||||
|
}
|
||||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec2>>(get(), values, set)), startRecording);
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec2>>(get(), values, set)), startRecording);
|
||||||
if (!startRecording)
|
if (!startRecording)
|
||||||
startRecording = true;
|
startRecording = true;
|
||||||
|
@ -230,17 +244,24 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool DragVec3(const std::string& label, std::vector<std::string>const& componentLabels, std::function<SHVec3(void)> get,
|
static bool DragVec3(const std::string& label, std::vector<std::string>const& componentLabels, std::function<SHVec3(void)> get,
|
||||||
std::function<void(SHVec3)> set, float speed = 0.1f, const char* displayFormat = "%.3f", std::string_view const& tooltip = {}, float valueMin = 0.0f, float valueMax = 0.0f,
|
std::function<void(SHVec3)> set, bool const& isAnAngleInRad = false, std::string_view const& tooltip = {}, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f,
|
||||||
ImGuiSliderFlags flags = 0)
|
ImGuiSliderFlags flags = 0)
|
||||||
{
|
{
|
||||||
SHVec3 values = get();
|
SHVec3 values = get();
|
||||||
bool const changed = DragN<float, 3>(label, componentLabels, { &values.x, &values.y, &values.z }, speed, displayFormat, valueMin, valueMax, flags);
|
if(isAnAngleInRad)
|
||||||
|
{
|
||||||
|
values = {SHMath::RadiansToDegrees(values.x), SHMath::RadiansToDegrees(values.y), SHMath::RadiansToDegrees(values.z)};
|
||||||
|
}
|
||||||
|
bool isHovered = false;
|
||||||
|
bool const changed = DragN<float, 3>(label, componentLabels, { &values.x, &values.y, &values.z }, speed, displayFormat, valueMin, valueMax, flags, &isHovered);
|
||||||
static bool startRecording = false;
|
static bool startRecording = false;
|
||||||
if (changed)
|
if (changed)
|
||||||
{
|
{
|
||||||
SHVec3 old = get();
|
SHVec3 old = get();
|
||||||
|
if(isAnAngleInRad)
|
||||||
|
{
|
||||||
|
values = {SHMath::DegreesToRadians(values.x), SHMath::DegreesToRadians(values.y), SHMath::DegreesToRadians(values.z)};
|
||||||
|
}
|
||||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec3>>(old, values, set)), startRecording);
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec3>>(old, values, set)), startRecording);
|
||||||
if (!startRecording)
|
if (!startRecording)
|
||||||
startRecording = true;
|
startRecording = true;
|
||||||
|
@ -251,7 +272,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
if (!tooltip.empty())
|
if (!tooltip.empty())
|
||||||
{
|
{
|
||||||
if(ImGui::IsItemHovered())
|
if (isHovered)
|
||||||
{
|
{
|
||||||
ImGui::BeginTooltip();
|
ImGui::BeginTooltip();
|
||||||
ImGui::Text(tooltip.data());
|
ImGui::Text(tooltip.data());
|
||||||
|
@ -262,14 +283,22 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool DragVec4(const std::string& label, std::vector<std::string>const& componentLabels, std::function<SHVec4(void)> get,
|
static bool DragVec4(const std::string& label, std::vector<std::string>const& componentLabels, std::function<SHVec4(void)> get,
|
||||||
std::function<void(SHVec4)> set, float speed = 0.1f, const char* displayFormat = "%.3f", std::string_view const& tooltip = {}, float valueMin = 0.0f, float valueMax = 0.0f,
|
std::function<void(SHVec4)> set, bool const& isAnAngleInRad = false, std::string_view const& tooltip = {}, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f,
|
||||||
ImGuiSliderFlags flags = 0)
|
ImGuiSliderFlags flags = 0)
|
||||||
{
|
{
|
||||||
SHVec4 values = get();
|
SHVec4 values = get();
|
||||||
|
if(isAnAngleInRad)
|
||||||
|
{
|
||||||
|
values = {SHMath::RadiansToDegrees(values.x), SHMath::RadiansToDegrees(values.y), SHMath::RadiansToDegrees(values.z), SHMath::RadiansToDegrees(values.w)};
|
||||||
|
}
|
||||||
bool const changed = DragN<float, 4>(label, componentLabels, { &values.x, &values.y, &values.z, &values.w }, speed, displayFormat, valueMin, valueMax, flags);
|
bool const changed = DragN<float, 4>(label, componentLabels, { &values.x, &values.y, &values.z, &values.w }, speed, displayFormat, valueMin, valueMax, flags);
|
||||||
static bool startRecording = false;
|
static bool startRecording = false;
|
||||||
if (changed)
|
if (changed)
|
||||||
{
|
{
|
||||||
|
if(isAnAngleInRad)
|
||||||
|
{
|
||||||
|
values = {SHMath::DegreesToRadians(values.x), SHMath::DegreesToRadians(values.y), SHMath::DegreesToRadians(values.z), SHMath::DegreesToRadians(values.w)};
|
||||||
|
}
|
||||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec4>>(get(), values, set)), startRecording);
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec4>>(get(), values, set)), startRecording);
|
||||||
if (!startRecording)
|
if (!startRecording)
|
||||||
startRecording = true;
|
startRecording = true;
|
||||||
|
@ -310,10 +339,10 @@ namespace SHADE
|
||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
ImGui::PushID(label.data());
|
ImGui::PushID(label.data());
|
||||||
TextLabel(label);
|
TextLabel(label);
|
||||||
if (ImGui::Checkbox("##", &value))
|
bool const changed = ImGui::Checkbox("##", &value);
|
||||||
|
if (changed)
|
||||||
{
|
{
|
||||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<bool>>(get(), value, set)), false);
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<bool>>(get(), value, set)), false);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
ImGui::EndGroup();
|
ImGui::EndGroup();
|
||||||
|
@ -326,7 +355,7 @@ namespace SHADE
|
||||||
ImGui::EndTooltip();
|
ImGui::EndTooltip();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -335,7 +364,7 @@ namespace SHADE
|
||||||
T type = get();
|
T type = get();
|
||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
ImGui::PushID(label.data());
|
ImGui::PushID(label.data());
|
||||||
TextLabel(label);
|
//TextLabel(label);
|
||||||
for (size_t i = 0; i < listTypes.size(); i++)
|
for (size_t i = 0; i < listTypes.size(); i++)
|
||||||
{
|
{
|
||||||
if (ImGui::RadioButton(label[i].c_str(), type == listTypes[i]))
|
if (ImGui::RadioButton(label[i].c_str(), type == listTypes[i]))
|
||||||
|
@ -366,12 +395,11 @@ namespace SHADE
|
||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
ImGui::PushID(label.data());
|
ImGui::PushID(label.data());
|
||||||
TextLabel(label);
|
TextLabel(label);
|
||||||
if (ImGui::InputText("##", &text, flag, callback, userData))
|
bool const changed = ImGui::InputText("##", &text, flag, callback, userData);
|
||||||
|
if (changed)
|
||||||
{
|
{
|
||||||
if (ImGui::IsItemDeactivatedAfterEdit())
|
if (ImGui::IsItemDeactivatedAfterEdit())
|
||||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<std::string>>(get(), text, set)), false);
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<std::string>>(get(), text, set)), false);
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
ImGui::EndGroup();
|
ImGui::EndGroup();
|
||||||
|
@ -384,7 +412,37 @@ namespace SHADE
|
||||||
ImGui::EndTooltip();
|
ImGui::EndTooltip();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static bool DragDropReadOnlyField(std::string const& label, std::string_view const& fieldVTextValue, std::function<T (void)> const& get, std::function<void(T const&)> const& set, SHDragDrop::DragDropTag const& dragDropTag, std::string_view const& tooltip = {})
|
||||||
|
{
|
||||||
|
std::string text = fieldVTextValue.data();
|
||||||
|
ImGui::BeginGroup();
|
||||||
|
ImGui::PushID(label.data());
|
||||||
|
TextLabel(label);
|
||||||
|
bool const changed = ImGui::InputText("##", &text, ImGuiInputTextFlags_ReadOnly, nullptr, nullptr);
|
||||||
|
if(SHDragDrop::BeginTarget())
|
||||||
|
{
|
||||||
|
if(T* payload = SHDragDrop::AcceptPayload<T>(dragDropTag))
|
||||||
|
{
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), *payload, set)), false);
|
||||||
|
SHDragDrop::EndTarget();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::PopID();
|
||||||
|
ImGui::EndGroup();
|
||||||
|
if (!tooltip.empty())
|
||||||
|
{
|
||||||
|
if (ImGui::IsItemHovered())
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text(tooltip.data());
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
|
@ -13,4 +13,7 @@ constexpr SHEventIdentifier SH_COMPONENT_REMOVED_EVENT { 4 };
|
||||||
constexpr SHEventIdentifier SH_SCENEGRAPH_CHANGE_PARENT_EVENT { 5 };
|
constexpr SHEventIdentifier SH_SCENEGRAPH_CHANGE_PARENT_EVENT { 5 };
|
||||||
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_ADDED_EVENT { 6 };
|
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_ADDED_EVENT { 6 };
|
||||||
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_REMOVED_EVENT { 7 };
|
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_REMOVED_EVENT { 7 };
|
||||||
|
constexpr SHEventIdentifier SH_EDITOR_ON_PLAY_EVENT { 8 };
|
||||||
|
constexpr SHEventIdentifier SH_EDITOR_ON_PAUSE_EVENT { 9 };
|
||||||
|
constexpr SHEventIdentifier SH_EDITOR_ON_STOP_EVENT { 10 };
|
||||||
|
|
||||||
|
|
|
@ -282,6 +282,11 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHVkCommandBuffer::SetLineWidth(float lineWidth) noexcept
|
||||||
|
{
|
||||||
|
vkCommandBuffer.setLineWidth(lineWidth);
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
|
|
@ -115,6 +115,7 @@ namespace SHADE
|
||||||
|
|
||||||
// Dynamic State
|
// Dynamic State
|
||||||
void SetViewportScissor (float vpWidth, float vpHeight, uint32_t sWidth, uint32_t sHeight, float vpX = 0.0f, float vpY = 0.0f, int32_t sX = 0.0f, int32_t sY = 0.0f, float vpMinDepth = 0.0f, float vpMaxDepth = 1.0f) noexcept;
|
void SetViewportScissor (float vpWidth, float vpHeight, uint32_t sWidth, uint32_t sHeight, float vpX = 0.0f, float vpY = 0.0f, int32_t sX = 0.0f, int32_t sY = 0.0f, float vpMinDepth = 0.0f, float vpMaxDepth = 1.0f) noexcept;
|
||||||
|
void SetLineWidth (float lineWidth) noexcept;
|
||||||
|
|
||||||
// Binding Commands
|
// Binding Commands
|
||||||
void BindPipeline (Handle<SHVkPipeline> const& pipelineHdl) noexcept;
|
void BindPipeline (Handle<SHVkPipeline> const& pipelineHdl) noexcept;
|
||||||
|
|
|
@ -74,10 +74,11 @@ namespace SHADE
|
||||||
|
|
||||||
void SHBatch::Remove(const SHRenderable* renderable)
|
void SHBatch::Remove(const SHRenderable* renderable)
|
||||||
{
|
{
|
||||||
// Check if we have a SubBatch with the same mesh yet
|
// Check if we have a SubBatch with the existing mesh yet (if changed, we use the old mesh)
|
||||||
|
Handle<SHMesh> prevSubBatchMesh = renderable->HasMeshChanged() ? renderable->GetPrevMesh() : renderable->GetMesh();
|
||||||
auto subBatch = std::find_if(subBatches.begin(), subBatches.end(), [&](const SHSubBatch& batch)
|
auto subBatch = std::find_if(subBatches.begin(), subBatches.end(), [&](const SHSubBatch& batch)
|
||||||
{
|
{
|
||||||
return batch.Mesh == renderable->GetMesh();
|
return batch.Mesh == prevSubBatchMesh;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Attempt to remove if it exists
|
// Attempt to remove if it exists
|
||||||
|
@ -88,9 +89,7 @@ namespace SHADE
|
||||||
|
|
||||||
// Check if other renderables in subBatches contain the same material instance
|
// Check if other renderables in subBatches contain the same material instance
|
||||||
bool matUnused = true;
|
bool matUnused = true;
|
||||||
|
|
||||||
Handle<SHMaterialInstance> matToCheck = renderable->HasMaterialChanged() ? renderable->GetPrevMaterial() : renderable->GetMaterial();
|
Handle<SHMaterialInstance> matToCheck = renderable->HasMaterialChanged() ? renderable->GetPrevMaterial() : renderable->GetMaterial();
|
||||||
|
|
||||||
for (const auto& sb : subBatches)
|
for (const auto& sb : subBatches)
|
||||||
{
|
{
|
||||||
// Check material usage
|
// Check material usage
|
||||||
|
|
|
@ -0,0 +1,202 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SHDebugDrawSystem.cpp
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Oct 16, 2022
|
||||||
|
\brief Contains the definition of functions of the SHDebugDrawSystem class.
|
||||||
|
|
||||||
|
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"
|
||||||
|
#include "SHDebugDrawSystem.h"
|
||||||
|
// STL Includes
|
||||||
|
#include <algorithm>
|
||||||
|
// Project Includes
|
||||||
|
#include "../Meshes/SHMeshData.h"
|
||||||
|
#include "../Meshes/SHPrimitiveGenerator.h"
|
||||||
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
#include "SHGraphicsSystem.h"
|
||||||
|
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||||
|
#include "../../SHVkUtil.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHViewport.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHRenderer.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* DrawRoutine */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
SHDebugDrawSystem::ProcessPointsRoutine::ProcessPointsRoutine()
|
||||||
|
: SHSystemRoutine("Debug Draw", true)
|
||||||
|
{
|
||||||
|
SystemFamily::GetID<SHDebugDrawSystem>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHDebugDrawSystem::ProcessPointsRoutine::Execute(double dt) noexcept
|
||||||
|
{
|
||||||
|
auto gfxSys = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||||
|
if (!gfxSys)
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("[DebugDraw] Attempted to do debug draw without a graphics system.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get current frame index
|
||||||
|
const uint32_t FRAME_IDX = gfxSys->GetCurrentFrameIndex();
|
||||||
|
|
||||||
|
// Create the buffer if it doesn't exist or just update it
|
||||||
|
SHDebugDrawSystem* system = static_cast<SHDebugDrawSystem*>(GetSystem());
|
||||||
|
system->numPoints[FRAME_IDX] = system->points.size();
|
||||||
|
const uint32_t DATA_SIZE = sizeof(PointVertex) * system->points.size();
|
||||||
|
if (DATA_SIZE > 0)
|
||||||
|
{
|
||||||
|
system->vertexBuffers[FRAME_IDX]->WriteToMemory(system->points.data(), DATA_SIZE, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset for next frame
|
||||||
|
system->points.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* SHSystem overrides */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
void SHDebugDrawSystem::Init()
|
||||||
|
{
|
||||||
|
// Register function for subpass
|
||||||
|
const auto* GFX_SYSTEM = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||||
|
auto const& RENDERERS = GFX_SYSTEM->GetDefaultViewport()->GetRenderers();
|
||||||
|
auto renderGraph = RENDERERS[SHGraphicsConstants::RenderGraphIndices::WORLD]->GetRenderGraph();
|
||||||
|
auto subPass = renderGraph->GetNode("Debug Draw")->GetSubpass("Debug Draw");
|
||||||
|
subPass->AddExteriorDrawCalls([this, GFX_SYSTEM](Handle<SHVkCommandBuffer>& cmdBuffer)
|
||||||
|
{
|
||||||
|
// Get Current frame index
|
||||||
|
const uint32_t FRAME_IDX = GFX_SYSTEM->GetCurrentFrameIndex();
|
||||||
|
|
||||||
|
// Don't draw if no points
|
||||||
|
if (numPoints[FRAME_IDX] <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cmdBuffer->BindPipeline(GFX_SYSTEM->GetDebugDrawPipeline());
|
||||||
|
cmdBuffer->SetLineWidth(LineWidth);
|
||||||
|
cmdBuffer->BindVertexBuffer(0, vertexBuffers[FRAME_IDX], 0);
|
||||||
|
cmdBuffer->DrawArrays(numPoints[FRAME_IDX], 1, 0, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Reset trackers
|
||||||
|
std::fill_n(numPoints.begin(), numPoints.size(), 0);
|
||||||
|
|
||||||
|
// Allocate buffers
|
||||||
|
static constexpr uint32_t BUFFER_SIZE = MAX_POINTS * sizeof(PointVertex);
|
||||||
|
for (Handle<SHVkBuffer>& bufHandle : vertexBuffers)
|
||||||
|
{
|
||||||
|
bufHandle = GFX_SYSTEM->GetDevice()->CreateBuffer
|
||||||
|
(
|
||||||
|
BUFFER_SIZE,
|
||||||
|
nullptr,
|
||||||
|
0,
|
||||||
|
vk::BufferUsageFlagBits::eVertexBuffer,
|
||||||
|
VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO,
|
||||||
|
VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHDebugDrawSystem::Exit()
|
||||||
|
{
|
||||||
|
for (auto vertexBuffer : vertexBuffers)
|
||||||
|
{
|
||||||
|
if (vertexBuffer)
|
||||||
|
vertexBuffer.Free();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Draw Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
void SHDebugDrawSystem::DrawLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt)
|
||||||
|
{
|
||||||
|
if (points.size() > MAX_POINTS)
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("[DebugDraw] Exceeded maximum size of drawable debug elements.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
points.emplace_back(PointVertex{ startPt, color });
|
||||||
|
points.emplace_back(PointVertex{ endPt, color });
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHDebugDrawSystem::DrawTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3)
|
||||||
|
{
|
||||||
|
DrawPoly(color, { pt1, pt2, pt3 });
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHDebugDrawSystem::DrawQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4)
|
||||||
|
{
|
||||||
|
DrawPoly(color, { pt1, pt2, pt3, pt4 });
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHDebugDrawSystem::DrawPoly(const SHVec4& color, std::initializer_list<SHVec3> pointList)
|
||||||
|
{
|
||||||
|
DrawPoly(color, pointList.begin(), pointList.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHDebugDrawSystem::DrawCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size)
|
||||||
|
{
|
||||||
|
static const SHVec3 EXTENTS = SHVec3 { 0.5f, 0.5f, 0.5f };
|
||||||
|
static const SHVec3 UNIT_BOT_LEFT_FRONT = SHVec3 { pos - EXTENTS };
|
||||||
|
static const SHVec3 UNIT_BOT_RIGHT_FRONT = SHVec3 { pos + SHVec3 { EXTENTS.x, -EXTENTS.y, -EXTENTS.z } };
|
||||||
|
static const SHVec3 UNIT_BOT_RIGHT_BACK = SHVec3 { pos + SHVec3 { EXTENTS.x, -EXTENTS.y, EXTENTS.z } };
|
||||||
|
static const SHVec3 UNIT_BOT_LEFT_BACK = SHVec3 { pos + SHVec3 { -EXTENTS.x, -EXTENTS.y, EXTENTS.z } };
|
||||||
|
static const SHVec3 UNIT_TOP_LEFT_BACK = SHVec3 { pos + SHVec3 { -EXTENTS.x, EXTENTS.y, EXTENTS.z } };
|
||||||
|
static const SHVec3 UNIT_TOP_RIGHT_FRONT = SHVec3 { pos + SHVec3 { EXTENTS.x, EXTENTS.y, -EXTENTS.z } };
|
||||||
|
static const SHVec3 UNIT_TOP_LEFT_FRONT = SHVec3 { pos + SHVec3 { -EXTENTS.x, EXTENTS.y, -EXTENTS.z } };
|
||||||
|
static const SHVec3 UNIT_TOP_RIGHT_BACK = SHVec3 { pos + EXTENTS };
|
||||||
|
|
||||||
|
const SHVec3 BOT_LEFT_BACK = UNIT_BOT_LEFT_BACK * size;
|
||||||
|
const SHVec3 BOT_RIGHT_BACK = UNIT_BOT_RIGHT_BACK * size;
|
||||||
|
const SHVec3 BOT_LEFT_FRONT = UNIT_BOT_LEFT_FRONT * size;
|
||||||
|
const SHVec3 BOT_RIGHT_FRONT = UNIT_BOT_RIGHT_FRONT * size;
|
||||||
|
const SHVec3 TOP_LEFT_BACK = UNIT_TOP_LEFT_BACK * size;
|
||||||
|
const SHVec3 TOP_RIGHT_BACK = UNIT_TOP_RIGHT_BACK * size;
|
||||||
|
const SHVec3 TOP_LEFT_FRONT = UNIT_TOP_LEFT_FRONT * size;
|
||||||
|
const SHVec3 TOP_RIGHT_FRONT = UNIT_TOP_RIGHT_FRONT * size;
|
||||||
|
|
||||||
|
DrawPoly
|
||||||
|
(
|
||||||
|
color,
|
||||||
|
{
|
||||||
|
// Bottom Square
|
||||||
|
BOT_LEFT_BACK , BOT_RIGHT_BACK,
|
||||||
|
BOT_RIGHT_BACK , BOT_RIGHT_FRONT,
|
||||||
|
BOT_RIGHT_FRONT, BOT_LEFT_FRONT,
|
||||||
|
BOT_LEFT_FRONT , BOT_LEFT_BACK,
|
||||||
|
// Top Square
|
||||||
|
TOP_LEFT_BACK , TOP_RIGHT_BACK,
|
||||||
|
TOP_RIGHT_BACK , TOP_RIGHT_FRONT,
|
||||||
|
TOP_RIGHT_FRONT, TOP_LEFT_FRONT,
|
||||||
|
TOP_LEFT_FRONT , TOP_LEFT_BACK,
|
||||||
|
// Middle Lines
|
||||||
|
TOP_LEFT_BACK , BOT_LEFT_BACK,
|
||||||
|
TOP_RIGHT_BACK , BOT_RIGHT_BACK,
|
||||||
|
TOP_RIGHT_FRONT, BOT_RIGHT_FRONT,
|
||||||
|
TOP_LEFT_FRONT , BOT_LEFT_FRONT
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHDebugDrawSystem::DrawSphere(const SHVec4& color, const SHVec3& pos, double radius)
|
||||||
|
{
|
||||||
|
if (spherePoints.empty())
|
||||||
|
{
|
||||||
|
// Generate
|
||||||
|
static const SHMeshData SPHERE = SHPrimitiveGenerator::Sphere();
|
||||||
|
for (const auto& idx : SPHERE.Indices)
|
||||||
|
{
|
||||||
|
spherePoints.emplace_back(SPHERE.VertexPositions[idx]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DrawPoly(color, spherePoints.begin(), spherePoints.end());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,159 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SHDebugDrawSystem.h
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Oct 16, 2022
|
||||||
|
\brief Contains the definition of the SHDebugDrawSystem class.
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
// STL Includes
|
||||||
|
#include <vector>
|
||||||
|
// Project Includes
|
||||||
|
#include "SH_API.h"
|
||||||
|
#include "Math/Vector/SHVec2.h"
|
||||||
|
#include "Math/Vector/SHVec3.h"
|
||||||
|
#include "Math/Vector/SHVec4.h"
|
||||||
|
#include "ECS_Base/System/SHSystem.h"
|
||||||
|
#include "ECS_Base/System/SHSystemRoutine.h"
|
||||||
|
#include "Resource/SHHandle.h"
|
||||||
|
#include "Graphics/Buffers/SHVkBuffer.h"
|
||||||
|
#include "SHGraphicsConstants.h"
|
||||||
|
#include "Math/SHColour.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Forward Declarations */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
class SHVkBuffer;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Type Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Manages the Debug Draw system.
|
||||||
|
/// </summary>
|
||||||
|
class SH_API SHDebugDrawSystem final : public SHSystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* System Routines */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
class SH_API ProcessPointsRoutine final : public SHSystemRoutine
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ProcessPointsRoutine();
|
||||||
|
virtual void Execute(double dt) noexcept override final;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* SHSystem overrides */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
virtual void Init() override final;
|
||||||
|
virtual void Exit() override final;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Configuration Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Configures the line width used to draw all lines in the Debug Draw system.
|
||||||
|
/// </summary>
|
||||||
|
float LineWidth = 1.0f;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Draw Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Renders a line between two points in world space.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="color">Colour of the line.</param>
|
||||||
|
/// <param name="startPt">First point of the line.</param>
|
||||||
|
/// <param name="endPt">Second point of the line.</param>
|
||||||
|
void DrawLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt);
|
||||||
|
/// <summary>
|
||||||
|
/// Renders a triangle indicated by three points in world space.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="color">Colour of the triangle.</param>
|
||||||
|
/// <param name="pt1">First point of the triangle.</param>
|
||||||
|
/// <param name="pt2">Second point of the triangle.</param>
|
||||||
|
/// <param name="pt3">Third point of the triangle.</param>
|
||||||
|
void DrawTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3);
|
||||||
|
/// <summary>
|
||||||
|
/// Renders a quadrilateral indicated by four points in world space.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="color">Colour of the quadrilateral.</param>
|
||||||
|
/// <param name="pt1">First point of the triangle.</param>
|
||||||
|
/// <param name="pt2">Second point of the quadrilateral.</param>
|
||||||
|
/// <param name="pt3">Third point of the quadrilateral.</param>
|
||||||
|
/// <param name="pt4">Third point of the quadrilateral.</param>
|
||||||
|
void DrawQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4);
|
||||||
|
/// <summary>
|
||||||
|
/// Renders a polygon indicated by the specified set of points in world space.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="color">Colour of the polygon.</param>
|
||||||
|
/// <param name="pointList">List of points for the polygon.</param>
|
||||||
|
void DrawPoly(const SHVec4& color, std::initializer_list<SHVec3> pointList);
|
||||||
|
/// <summary>
|
||||||
|
/// Renders a polygon indicated by the specified set of points in world space.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="IterType">Iterator for a STL-like container.</typeparam>
|
||||||
|
/// <param name="color">Colour of the polygon.</param>
|
||||||
|
/// <param name="pointListBegin">
|
||||||
|
/// Iterator to the first point of the point container.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="pointListEnd">
|
||||||
|
/// One past last iterator of the point container.
|
||||||
|
/// </param>
|
||||||
|
template<typename IterType>
|
||||||
|
void DrawPoly(const SHVec4& color, IterType pointListBegin, IterType pointListEnd);
|
||||||
|
/// <summary>
|
||||||
|
/// Renders a wireframe cube centered around the position specified in world space.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="color">Colour of the cube.</param>
|
||||||
|
/// <param name="pos">Position where the cube wil be centered at.</param>
|
||||||
|
/// <param name="size">Size of the rendered cube.</param>
|
||||||
|
void DrawCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size);
|
||||||
|
/// <summary>
|
||||||
|
/// Renders a wireframe sphere centered around the position specified in world space.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="color">Colour of the sphere.</param>
|
||||||
|
/// <param name="pos">Position where the sphere wil be centered at.</param>
|
||||||
|
/// <param name="size">Size of the rendered sphere.</param>
|
||||||
|
void DrawSphere(const SHVec4& color, const SHVec3& pos, double radius);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Type Definitions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
struct SH_API PointVertex
|
||||||
|
{
|
||||||
|
SHVec4 Position;
|
||||||
|
SHVec4 Color;
|
||||||
|
};
|
||||||
|
using TripleBuffer = std::array<Handle<SHVkBuffer>, SHGraphicsConstants::NUM_FRAME_BUFFERS>;
|
||||||
|
using TripleUInt = std::array<uint32_t, SHGraphicsConstants::NUM_FRAME_BUFFERS>;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Constants */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
static constexpr uint32_t MAX_POINTS = 100'000;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Data Members */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
// CPU Buffers
|
||||||
|
std::vector<PointVertex> points;
|
||||||
|
// GPU Buffers
|
||||||
|
TripleBuffer vertexBuffers;
|
||||||
|
TripleUInt numPoints;
|
||||||
|
// Cached Points for polygon drawing
|
||||||
|
std::vector<SHVec3> spherePoints;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "SHDebugDrawSystem.hpp"
|
|
@ -0,0 +1,48 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SHDebugDrawSystem.hpp
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Oct 16, 2022
|
||||||
|
\brief Contains the definition of template functions the SHDebugDrawSystem
|
||||||
|
class.
|
||||||
|
|
||||||
|
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 "SHDebugDrawSystem.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Draw Functions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
template<typename IterType>
|
||||||
|
void SHDebugDrawSystem::DrawPoly(const SHVec4& color, IterType pointListBegin, IterType pointListEnd)
|
||||||
|
{
|
||||||
|
// Ensure dereferenced type is SHVec3
|
||||||
|
static_assert(std::is_same_v<SHVec3, std::remove_cvref_t<decltype(*pointListBegin)>>, "Parameters to DrawPoly must be SHVec3.");
|
||||||
|
|
||||||
|
// Check if points exceeded max
|
||||||
|
if (points.size() > MAX_POINTS)
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("[DebugDraw] Exceeded maximum size of drawable debug elements.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t POINTS_COUNT = pointListEnd - pointListBegin;
|
||||||
|
// Invalid polygon
|
||||||
|
if (POINTS_COUNT < 2)
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("[SHDebugDraw] Invalid polygon provided to DrawPoly().");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t POINTS_ROUNDED_COUNT = POINTS_COUNT / 2 * 2;
|
||||||
|
for (auto pointIter = pointListBegin; pointIter != (pointListBegin + POINTS_ROUNDED_COUNT); ++pointIter)
|
||||||
|
{
|
||||||
|
points.emplace_back(PointVertex{ *pointIter, color });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,7 +17,7 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Graphics/Windowing/Surface/SHVkSurface.h"
|
#include "Graphics/Windowing/Surface/SHVkSurface.h"
|
||||||
#include "Graphics/Swapchain/SHVkSwapchain.h"
|
#include "Graphics/Swapchain/SHVkSwapchain.h"
|
||||||
#include "Camera/SHCameraSystem.h"
|
#include "Camera/SHCameraSystem.h"
|
||||||
#include "Editor/SHEditor.hpp"
|
#include "Editor/SHEditor.h"
|
||||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
//#include "SHRenderer.h"
|
//#include "SHRenderer.h"
|
||||||
#include "Graphics/Windowing/SHWindow.h"
|
#include "Graphics/Windowing/SHWindow.h"
|
||||||
|
@ -37,8 +37,10 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Assets/Asset Types/SHTextureAsset.h"
|
#include "Assets/Asset Types/SHTextureAsset.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h"
|
#include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h"
|
||||||
#include "Graphics/MiddleEnd/Lights/SHLightingSubSystem.h"
|
#include "Graphics/MiddleEnd/Lights/SHLightingSubSystem.h"
|
||||||
#include "Graphics/RenderGraph/SHRenderGraphNodeCompute.h"
|
|
||||||
#include "Assets/SHAssetManager.h"
|
#include "Assets/SHAssetManager.h"
|
||||||
|
#include "Resource/SHResourceManager.h"
|
||||||
|
#include "Graphics/SHVkUtil.h"
|
||||||
|
#include "Graphics/RenderGraph/SHRenderGraphNodeCompute.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -106,19 +108,16 @@ namespace SHADE
|
||||||
descPool = device->CreateDescriptorPools();
|
descPool = device->CreateDescriptorPools();
|
||||||
|
|
||||||
// Create generic command buffer
|
// Create generic command buffer
|
||||||
//transferCmdPool = device->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true);
|
|
||||||
graphicsCmdPool = device->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true);
|
graphicsCmdPool = device->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true);
|
||||||
transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
|
||||||
graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
|
||||||
|
|
||||||
SHAssetManager::CompileAsset("../../Assets/Shaders/TestCube_VS.glsl");
|
// Load Built In Shaders
|
||||||
SHAssetManager::CompileAsset("../../Assets/Shaders/TestCube_FS.glsl");
|
static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEFAULT);
|
||||||
SHAssetManager::CompileAsset("../../Assets/Shaders/DeferredComposite_CS.glsl");
|
static constexpr AssetID FS_DEFAULT = 46377769; defaultFragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(FS_DEFAULT);
|
||||||
SHAssetManager::CompileAsset("../../Assets/Shaders/SSAO_CS.glsl");
|
static constexpr AssetID VS_DEBUG = 48002439; debugVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEBUG);
|
||||||
SHAssetManager::CompileAsset("../../Assets/Shaders/SSAOBlur_CS.glsl");
|
static constexpr AssetID FS_DEBUG = 36671027; debugFragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(FS_DEBUG);
|
||||||
|
static constexpr AssetID CS_COMPOSITE = 45072428; deferredCompositeShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(CS_COMPOSITE);
|
||||||
shaderModuleLibrary.ImportAllShaderSource(device);
|
static constexpr AssetID SSAO = 38430899; ssaoShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(SSAO);
|
||||||
shaderModuleLibrary.ReflectAllShaderModules();
|
static constexpr AssetID SSAO_BLUR = 39760835; ssaoBlurShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(SSAO_BLUR);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHGraphicsSystem::InitSceneRenderGraph(void) noexcept
|
void SHGraphicsSystem::InitSceneRenderGraph(void) noexcept
|
||||||
|
@ -220,7 +219,6 @@ namespace SHADE
|
||||||
|
|
||||||
ssaoStorage->PrepareRotationVectorsVkData(device);
|
ssaoStorage->PrepareRotationVectorsVkData(device);
|
||||||
|
|
||||||
auto ssaoShader = shaderModuleLibrary.GetBuiltInShaderModule("SSAO_CS");
|
|
||||||
Handle<SHRenderGraphNodeCompute> ssaoPass = gBufferNode->AddNodeCompute(ssaoShader, {"Position", "Normals", "SSAO"});
|
Handle<SHRenderGraphNodeCompute> ssaoPass = gBufferNode->AddNodeCompute(ssaoShader, {"Position", "Normals", "SSAO"});
|
||||||
auto ssaoDataBuffer = ssaoStorage->GetBuffer();
|
auto ssaoDataBuffer = ssaoStorage->GetBuffer();
|
||||||
ssaoPass->ModifyWriteDescBufferComputeResource(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, SHSSAO::DESC_SET_BUFFER_BINDING, { &ssaoDataBuffer, 1 }, 0, ssaoStorage->GetBuffer()->GetSizeStored());
|
ssaoPass->ModifyWriteDescBufferComputeResource(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, SHSSAO::DESC_SET_BUFFER_BINDING, { &ssaoDataBuffer, 1 }, 0, ssaoStorage->GetBuffer()->GetSizeStored());
|
||||||
|
@ -228,21 +226,21 @@ namespace SHADE
|
||||||
auto viewSamplerLayout = ssaoStorage->GetViewSamplerLayout();
|
auto viewSamplerLayout = ssaoStorage->GetViewSamplerLayout();
|
||||||
ssaoPass->ModifyWriteDescImageComputeResource(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, SHSSAO::DESC_SET_IMAGE_BINDING, {&viewSamplerLayout, 1});
|
ssaoPass->ModifyWriteDescImageComputeResource(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, SHSSAO::DESC_SET_IMAGE_BINDING, {&viewSamplerLayout, 1});
|
||||||
|
|
||||||
auto ssaoBlurShader = shaderModuleLibrary.GetBuiltInShaderModule("SSAOBlur_CS");
|
|
||||||
Handle<SHRenderGraphNodeCompute> ssaoBlurPass = gBufferNode->AddNodeCompute(ssaoBlurShader, { "SSAO", "SSAO Blur"});
|
Handle<SHRenderGraphNodeCompute> ssaoBlurPass = gBufferNode->AddNodeCompute(ssaoBlurShader, { "SSAO", "SSAO Blur"});
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* DEFERRED COMPOSITE SUBPASS INIT */
|
/* DEFERRED COMPOSITE SUBPASS INIT */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
auto deferredCompositeShader = shaderModuleLibrary.GetBuiltInShaderModule("DeferredComposite_CS");
|
|
||||||
gBufferNode->AddNodeCompute(deferredCompositeShader, { "Position", "Normals", "Albedo", "Light Layer Indices", "SSAO Blur", "Scene" });
|
gBufferNode->AddNodeCompute(deferredCompositeShader, { "Position", "Normals", "Albedo", "Light Layer Indices", "SSAO Blur", "Scene" });
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
// Set up Debug Draw Pass
|
||||||
/* DUMMY SUBPASS TO TRANSITION SCENE FOR PRESENT USAGE */
|
auto debugDrawNode = worldRenderGraph->AddNode("Debug Draw", { "Scene" }, {"G-Buffer"});
|
||||||
/*-----------------------------------------------------------------------*/
|
auto debugDrawSubpass = debugDrawNode->AddSubpass("Debug Draw");
|
||||||
// Dummy to transition scene to be used for shader read
|
debugDrawSubpass->AddColorOutput("Scene");
|
||||||
auto dummyNode = worldRenderGraph->AddNode("Dummy Pass", { "Scene" }, {"G-Buffer"}); // no predecessors
|
|
||||||
|
// Dummy Node
|
||||||
|
auto dummyNode = worldRenderGraph->AddNode("Dummy Pass", { "Scene" }, { "Debug Draw" }); // no predecessors
|
||||||
auto dummySubpass = dummyNode->AddSubpass("Dummy Subpass");
|
auto dummySubpass = dummyNode->AddSubpass("Dummy Subpass");
|
||||||
dummySubpass->AddInput("Scene");
|
dummySubpass->AddInput("Scene");
|
||||||
|
|
||||||
|
@ -262,10 +260,57 @@ namespace SHADE
|
||||||
|
|
||||||
worldRenderer->SetCameraDirector(cameraSystem->CreateDirector());
|
worldRenderer->SetCameraDirector(cameraSystem->CreateDirector());
|
||||||
|
|
||||||
auto cubeVS = shaderModuleLibrary.GetBuiltInShaderModule("TestCube_VS");
|
// Create default materials
|
||||||
auto cubeFS = shaderModuleLibrary.GetBuiltInShaderModule("TestCube_FS");
|
defaultMaterial = AddMaterial(defaultVertShader, defaultFragShader, gBufferSubpass);
|
||||||
|
|
||||||
defaultMaterial = AddMaterial(cubeVS, cubeFS, gBufferSubpass);
|
// Create debug draw pipeline
|
||||||
|
auto debugDrawPipelineLayout = resourceManager.Create<SHVkPipelineLayout>
|
||||||
|
(
|
||||||
|
device, SHPipelineLayoutParams
|
||||||
|
{
|
||||||
|
.shaderModules = { debugVertShader, debugFragShader },
|
||||||
|
.globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
debugDrawPipeline = resourceManager.Create<SHVkPipeline>(device, debugDrawPipelineLayout, nullptr, debugDrawNode->GetRenderpass(), debugDrawSubpass);
|
||||||
|
debugDrawPipeline->GetPipelineState().SetRasterizationState(SHRasterizationState
|
||||||
|
{
|
||||||
|
.polygonMode = vk::PolygonMode::eLine,
|
||||||
|
.cull_mode = vk::CullModeFlagBits::eNone
|
||||||
|
});
|
||||||
|
debugDrawPipeline->GetPipelineState().SetInputAssemblyState(SHInputAssemblyState
|
||||||
|
{
|
||||||
|
.topology = vk::PrimitiveTopology::eLineList
|
||||||
|
});
|
||||||
|
|
||||||
|
SHVertexInputState debugDrawVertexInputState;
|
||||||
|
debugDrawVertexInputState.AddBinding(false, true, { SHVertexAttribute(SHAttribFormat::FLOAT_4D), SHVertexAttribute(SHAttribFormat::FLOAT_4D) });
|
||||||
|
debugDrawPipeline->GetPipelineState().SetVertexInputState(debugDrawVertexInputState);
|
||||||
|
SHColorBlendState colorBlendState{};
|
||||||
|
colorBlendState.logic_op_enable = VK_FALSE;
|
||||||
|
colorBlendState.logic_op = vk::LogicOp::eCopy;
|
||||||
|
|
||||||
|
auto const& subpassColorReferences = debugDrawSubpass->GetColorAttachmentReferences();
|
||||||
|
colorBlendState.attachments.reserve(subpassColorReferences.size());
|
||||||
|
|
||||||
|
for (auto& att : subpassColorReferences)
|
||||||
|
{
|
||||||
|
colorBlendState.attachments.push_back(vk::PipelineColorBlendAttachmentState
|
||||||
|
{
|
||||||
|
.blendEnable = SHVkUtil::IsBlendCompatible(debugDrawSubpass->GetFormatFromAttachmentReference(att.attachment)),
|
||||||
|
.srcColorBlendFactor = vk::BlendFactor::eSrcAlpha,
|
||||||
|
.dstColorBlendFactor = vk::BlendFactor::eOneMinusSrcAlpha,
|
||||||
|
.colorBlendOp = vk::BlendOp::eAdd,
|
||||||
|
.srcAlphaBlendFactor = vk::BlendFactor::eOne,
|
||||||
|
.dstAlphaBlendFactor = vk::BlendFactor::eZero,
|
||||||
|
.alphaBlendOp = vk::BlendOp::eAdd,
|
||||||
|
.colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
debugDrawPipeline->GetPipelineState().SetColorBlenState(colorBlendState);
|
||||||
|
debugDrawPipeline->ConstructPipeline();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHGraphicsSystem::InitMiddleEnd(void) noexcept
|
void SHGraphicsSystem::InitMiddleEnd(void) noexcept
|
||||||
|
@ -696,10 +741,14 @@ namespace SHADE
|
||||||
|
|
||||||
void SHGraphicsSystem::BuildMeshBuffers()
|
void SHGraphicsSystem::BuildMeshBuffers()
|
||||||
{
|
{
|
||||||
|
transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
||||||
|
device->WaitIdle();
|
||||||
transferCmdBuffer->BeginRecording();
|
transferCmdBuffer->BeginRecording();
|
||||||
meshLibrary.BuildBuffers(device, transferCmdBuffer);
|
meshLibrary.BuildBuffers(device, transferCmdBuffer);
|
||||||
transferCmdBuffer->EndRecording();
|
transferCmdBuffer->EndRecording();
|
||||||
graphicsQueue->SubmitCommandBuffer({ transferCmdBuffer });
|
graphicsQueue->SubmitCommandBuffer({ transferCmdBuffer });
|
||||||
|
device->WaitIdle();
|
||||||
|
transferCmdBuffer.Free(); transferCmdBuffer = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -724,10 +773,14 @@ namespace SHADE
|
||||||
|
|
||||||
void SHGraphicsSystem::BuildTextures()
|
void SHGraphicsSystem::BuildTextures()
|
||||||
{
|
{
|
||||||
|
graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
||||||
|
device->WaitIdle();
|
||||||
texLibrary.BuildTextures
|
texLibrary.BuildTextures
|
||||||
(
|
(
|
||||||
device, graphicsTexCmdBuffer, graphicsQueue, descPool
|
device, graphicsTexCmdBuffer, graphicsQueue, descPool
|
||||||
);
|
);
|
||||||
|
device->WaitIdle();
|
||||||
|
graphicsTexCmdBuffer.Free(); graphicsTexCmdBuffer = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma endregion ADD_REMOVE
|
#pragma endregion ADD_REMOVE
|
||||||
|
@ -767,6 +820,7 @@ namespace SHADE
|
||||||
void SHGraphicsSystem::EndRoutine::Execute(double) noexcept
|
void SHGraphicsSystem::EndRoutine::Execute(double) noexcept
|
||||||
{
|
{
|
||||||
reinterpret_cast<SHGraphicsSystem*>(system)->EndRender();
|
reinterpret_cast<SHGraphicsSystem*>(system)->EndRender();
|
||||||
|
SHResourceManager::FinaliseChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -784,8 +838,13 @@ namespace SHADE
|
||||||
if (!renderable.HasChanged())
|
if (!renderable.HasChanged())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Remove from old material's SuperBatch
|
if (!renderable.GetMesh())
|
||||||
Handle<SHMaterialInstance> prevMaterial = renderable.GetPrevMaterial();
|
{
|
||||||
|
SHLOG_CRITICAL("NULL Mesh provided!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove from the SuperBatch it is previously in (prevMat if mat has changed)
|
||||||
|
Handle<SHMaterialInstance> prevMaterial = renderable.HasMaterialChanged() ? renderable.GetPrevMaterial() : renderable.GetMaterial();
|
||||||
if (prevMaterial)
|
if (prevMaterial)
|
||||||
{
|
{
|
||||||
Handle<SHSuperBatch> oldSuperBatch = prevMaterial->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpass()->GetSuperBatch();
|
Handle<SHSuperBatch> oldSuperBatch = prevMaterial->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpass()->GetSuperBatch();
|
||||||
|
|
|
@ -25,7 +25,6 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "ECS_Base/System/SHSystemRoutine.h"
|
#include "ECS_Base/System/SHSystemRoutine.h"
|
||||||
#include "Graphics/Descriptors/SHVkDescriptorPool.h"
|
#include "Graphics/Descriptors/SHVkDescriptorPool.h"
|
||||||
#include "Graphics/RenderGraph/SHRenderGraph.h"
|
#include "Graphics/RenderGraph/SHRenderGraph.h"
|
||||||
#include "Graphics/MiddleEnd/Shaders/SHShaderModuleLibrary.h"
|
|
||||||
#include "SHMeshLibrary.h"
|
#include "SHMeshLibrary.h"
|
||||||
#include "Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.h"
|
#include "Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.h"
|
||||||
#include "../Textures/SHTextureLibrary.h"
|
#include "../Textures/SHTextureLibrary.h"
|
||||||
|
@ -290,10 +289,13 @@ namespace SHADE
|
||||||
Handle<SHMousePickSystem> GetMousePickSystem(void) const noexcept {return mousePickSystem;};
|
Handle<SHMousePickSystem> GetMousePickSystem(void) const noexcept {return mousePickSystem;};
|
||||||
Handle<SHPostOffscreenRenderSystem> GetPostOffscreenRenderSystem(void) const noexcept {return postOffscreenRender;};
|
Handle<SHPostOffscreenRenderSystem> GetPostOffscreenRenderSystem(void) const noexcept {return postOffscreenRender;};
|
||||||
Handle<SHRenderGraphNode> GetPrimaryRenderpass() const noexcept;
|
Handle<SHRenderGraphNode> GetPrimaryRenderpass() const noexcept;
|
||||||
//SHRenderGraph const& GetRenderGraph(void) const noexcept;
|
Handle<SHVkPipeline> GetDebugDrawPipeline(void) const noexcept { return debugDrawPipeline; }
|
||||||
|
uint32_t GetCurrentFrameIndex(void) const noexcept { return renderContext.GetCurrentFrame(); }
|
||||||
//Handle<SHVkRenderpass> GetRenderPass() const { return renderPass; }
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Getters */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
SHWindow* GetWindow() noexcept { return window; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
@ -327,6 +329,7 @@ namespace SHADE
|
||||||
SHTextureLibrary texLibrary;
|
SHTextureLibrary texLibrary;
|
||||||
SHSamplerCache samplerCache;
|
SHSamplerCache samplerCache;
|
||||||
SHMaterialInstanceCache materialInstanceCache;
|
SHMaterialInstanceCache materialInstanceCache;
|
||||||
|
|
||||||
// Viewports
|
// Viewports
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
Handle<SHViewport> editorViewport;
|
Handle<SHViewport> editorViewport;
|
||||||
|
@ -337,10 +340,6 @@ namespace SHADE
|
||||||
Handle<SHViewport> worldViewport; // Whole screen
|
Handle<SHViewport> worldViewport; // Whole screen
|
||||||
std::vector<Handle<SHViewport>> viewports; // Additional viewports
|
std::vector<Handle<SHViewport>> viewports; // Additional viewports
|
||||||
|
|
||||||
// Debug Renderers
|
|
||||||
Handle<SHRenderer> debugWorldRenderer;
|
|
||||||
Handle<SHRenderer> debugScreenRenderer;
|
|
||||||
|
|
||||||
// Temp renderers
|
// Temp renderers
|
||||||
Handle<SHRenderer> worldRenderer;
|
Handle<SHRenderer> worldRenderer;
|
||||||
|
|
||||||
|
@ -348,10 +347,19 @@ namespace SHADE
|
||||||
Handle<SHCamera> worldCamera;
|
Handle<SHCamera> worldCamera;
|
||||||
Handle<SHCamera> screenCamera;
|
Handle<SHCamera> screenCamera;
|
||||||
|
|
||||||
SHShaderModuleLibrary shaderModuleLibrary;
|
// Built-In Shaders
|
||||||
|
Handle<SHVkShaderModule> defaultVertShader;
|
||||||
|
Handle<SHVkShaderModule> defaultFragShader;
|
||||||
|
Handle<SHVkShaderModule> debugVertShader;
|
||||||
|
Handle<SHVkShaderModule> debugFragShader;
|
||||||
|
Handle<SHVkShaderModule> deferredCompositeShader;
|
||||||
|
Handle<SHVkShaderModule> ssaoShader;
|
||||||
|
Handle<SHVkShaderModule> ssaoBlurShader;
|
||||||
|
|
||||||
// Temp Materials
|
|
||||||
|
// Built-In Materials
|
||||||
Handle<SHMaterial> defaultMaterial;
|
Handle<SHMaterial> defaultMaterial;
|
||||||
|
Handle<SHVkPipeline> debugDrawPipeline;
|
||||||
|
|
||||||
Handle<SHRenderGraph> worldRenderGraph;
|
Handle<SHRenderGraph> worldRenderGraph;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SHGraphicsSystemInterface.cpp
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Oct 31, 2022
|
||||||
|
\brief Contains the definitions of the functions of the static
|
||||||
|
SHGraphicsSystemInterface class.
|
||||||
|
|
||||||
|
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 "SHGraphicsSystemInterface.h"
|
||||||
|
// Project Includes
|
||||||
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
||||||
|
#include "Graphics/Windowing/SHWindow.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Static Usage Functions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
uint32_t SHGraphicsSystemInterface::GetWindowWidth()
|
||||||
|
{
|
||||||
|
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||||
|
if (gfxSystem)
|
||||||
|
{
|
||||||
|
const auto WND = gfxSystem->GetWindow();
|
||||||
|
return WND->GetWindowSize().first;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHLOG_WARNING("[SHGraphicsSystemInterface] Failed to get window width. Value of 0 returned instead.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t SHGraphicsSystemInterface::GetWindowHeight()
|
||||||
|
{
|
||||||
|
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||||
|
if (gfxSystem)
|
||||||
|
{
|
||||||
|
const auto WND = gfxSystem->GetWindow();
|
||||||
|
return WND->GetWindowSize().second;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHLOG_WARNING("[SHGraphicsSystemInterface] Failed to get window height. Value of 0 returned instead.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHGraphicsSystemInterface::IsFullscreen()
|
||||||
|
{
|
||||||
|
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||||
|
if (gfxSystem)
|
||||||
|
{
|
||||||
|
const auto WND = gfxSystem->GetWindow();
|
||||||
|
return WND->GetWindowData().isFullscreen;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHLOG_WARNING("[SHGraphicsSystemInterface] Failed to get window fullscreen status. Value of false returned instead.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHGraphicsSystemInterface::CloseWindow()
|
||||||
|
{
|
||||||
|
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||||
|
if (gfxSystem)
|
||||||
|
{
|
||||||
|
auto WND = gfxSystem->GetWindow();
|
||||||
|
return WND->Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
SHLOG_WARNING("[SHGraphicsSystemInterface] Failed to close window.");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SHGraphicsSystemInterface.h
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Oct 31, 2022
|
||||||
|
\brief Contains the definition of the SHGraphicsSystemInterface static class.
|
||||||
|
|
||||||
|
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>
|
||||||
|
/// Static class that wraps up certain functions in the SHGraphicsSystem so that
|
||||||
|
/// accessing it from SHADE_Managed would not cause issues due to C++20 features.
|
||||||
|
/// </summary>
|
||||||
|
class SH_API SHGraphicsSystemInterface final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Constructor */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
SHGraphicsSystemInterface() = delete;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Static Usage Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves the current window width.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The current window width.</returns>
|
||||||
|
static uint32_t GetWindowWidth();
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves the current window height.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The current window height.</returns>
|
||||||
|
static uint32_t GetWindowHeight();
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves the current window fullscreen status.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The current window fullscreen status..</returns>
|
||||||
|
static bool IsFullscreen();
|
||||||
|
/// <summary>
|
||||||
|
/// Closes the current window, and depending on the implementation, should also
|
||||||
|
/// close the application.
|
||||||
|
/// </summary>
|
||||||
|
static void CloseWindow();
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SHMaterialSpec.h
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Oct 31, 2022
|
||||||
|
\brief Contains the struct definition of SHMaterialSpec.
|
||||||
|
|
||||||
|
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
|
||||||
|
// Standard Library
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <utility>
|
||||||
|
// Project Includes
|
||||||
|
#include "Assets/SHAssetMacros.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*************************************************************************************/
|
||||||
|
/*!
|
||||||
|
\brief
|
||||||
|
Describes a Material's serialized properties. A representation of a material that is
|
||||||
|
independent of GPU resources.
|
||||||
|
*/
|
||||||
|
/*************************************************************************************/
|
||||||
|
struct SHMaterialSpec
|
||||||
|
{
|
||||||
|
AssetID vertexShader;
|
||||||
|
AssetID fragShader;
|
||||||
|
std::string subpassName;
|
||||||
|
YAML::Node properties;
|
||||||
|
};
|
||||||
|
}
|
|
@ -18,6 +18,15 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Static Member Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
SHMeshData SHPrimitiveGenerator::cubeMesh;
|
||||||
|
SHMeshData SHPrimitiveGenerator::sphereMesh;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Primitive Generation Functions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
SHMeshData SHPrimitiveGenerator::Cube() noexcept
|
SHMeshData SHPrimitiveGenerator::Cube() noexcept
|
||||||
{
|
{
|
||||||
SHMeshData mesh;
|
SHMeshData mesh;
|
||||||
|
@ -193,7 +202,90 @@ namespace SHADE
|
||||||
|
|
||||||
Handle<SHMesh> SHPrimitiveGenerator::Cube(SHMeshLibrary& meshLibrary) noexcept
|
Handle<SHMesh> SHPrimitiveGenerator::Cube(SHMeshLibrary& meshLibrary) noexcept
|
||||||
{
|
{
|
||||||
static SHMeshData meshData = Cube();
|
if (cubeMesh.VertexPositions.empty())
|
||||||
|
cubeMesh = Cube();
|
||||||
|
return addMeshDataTo(cubeMesh, meshLibrary);
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle<SHADE::SHMesh> SHPrimitiveGenerator::Cube(SHGraphicsSystem& gfxSystem) noexcept
|
||||||
|
{
|
||||||
|
if (cubeMesh.VertexPositions.empty())
|
||||||
|
cubeMesh = Cube();
|
||||||
|
return addMeshDataTo(cubeMesh, gfxSystem);
|
||||||
|
}
|
||||||
|
|
||||||
|
SHADE::SHMeshData SHPrimitiveGenerator::Sphere() noexcept
|
||||||
|
{
|
||||||
|
SHMeshData meshData;
|
||||||
|
|
||||||
|
const int LAT_SLICES = 12;
|
||||||
|
const int LONG_SLICES = 12;
|
||||||
|
float radius = 1;
|
||||||
|
for (int latNum = 0; latNum <= LAT_SLICES; ++latNum)
|
||||||
|
{
|
||||||
|
float theta = static_cast<float>(latNum * std::numbers::pi / LAT_SLICES);
|
||||||
|
float sinTheta = sin(theta);
|
||||||
|
float cosTheta = cos(theta);
|
||||||
|
|
||||||
|
for (int longNum = 0; longNum <= LONG_SLICES; ++longNum)
|
||||||
|
{
|
||||||
|
float phi = static_cast<float>(longNum * 2 * std::numbers::pi / LONG_SLICES);
|
||||||
|
float sinPhi = sin(phi);
|
||||||
|
float cosPhi = cos(phi);
|
||||||
|
|
||||||
|
const SHVec3 NORMAL = SHVec3(cosPhi * sinTheta, cosTheta, sinPhi * sinTheta);
|
||||||
|
meshData.VertexNormals.emplace_back(NORMAL);
|
||||||
|
meshData.VertexTangents.emplace_back(/* TODO */);
|
||||||
|
meshData.VertexTexCoords.emplace_back
|
||||||
|
(
|
||||||
|
1.0f - (longNum / static_cast<float>(LONG_SLICES)),
|
||||||
|
1.0f - (latNum / static_cast<float>(LAT_SLICES))
|
||||||
|
);
|
||||||
|
meshData.VertexPositions.emplace_back(radius * NORMAL.x, radius * NORMAL.y, radius * NORMAL.z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int latNumber{}; latNumber < LAT_SLICES; latNumber++)
|
||||||
|
{
|
||||||
|
for (int longNumber{}; longNumber < LONG_SLICES; longNumber++)
|
||||||
|
{
|
||||||
|
const auto FIRST = (latNumber * (LONG_SLICES + 1)) + longNumber;
|
||||||
|
const auto SECOND = (FIRST + LONG_SLICES + 1);
|
||||||
|
|
||||||
|
meshData.Indices.emplace_back(FIRST);
|
||||||
|
meshData.Indices.emplace_back(SECOND);
|
||||||
|
meshData.Indices.emplace_back(FIRST + 1);
|
||||||
|
|
||||||
|
meshData.Indices.emplace_back(SECOND);
|
||||||
|
meshData.Indices.emplace_back(SECOND + 1);
|
||||||
|
meshData.Indices.emplace_back(FIRST + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return meshData;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHADE::Handle<SHADE::SHMesh> SHPrimitiveGenerator::Sphere(SHMeshLibrary& meshLibrary) noexcept
|
||||||
|
{
|
||||||
|
if (sphereMesh.VertexPositions.empty())
|
||||||
|
sphereMesh = Sphere();
|
||||||
|
|
||||||
|
return addMeshDataTo(sphereMesh, meshLibrary);
|
||||||
|
}
|
||||||
|
|
||||||
|
SHADE::Handle<SHADE::SHMesh> SHPrimitiveGenerator::Sphere(SHGraphicsSystem& gfxSystem) noexcept
|
||||||
|
{
|
||||||
|
if (sphereMesh.VertexPositions.empty())
|
||||||
|
sphereMesh = Sphere();
|
||||||
|
|
||||||
|
return addMeshDataTo(sphereMesh, gfxSystem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Helper Functions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
SHADE::Handle<SHADE::SHMesh> SHPrimitiveGenerator::addMeshDataTo(const SHMeshData& meshData, SHMeshLibrary& meshLibrary) noexcept
|
||||||
|
{
|
||||||
return meshLibrary.AddMesh
|
return meshLibrary.AddMesh
|
||||||
(
|
(
|
||||||
static_cast<uint32_t>(meshData.VertexPositions.size()),
|
static_cast<uint32_t>(meshData.VertexPositions.size()),
|
||||||
|
@ -206,9 +298,8 @@ namespace SHADE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<SHADE::SHMesh> SHPrimitiveGenerator::Cube(SHGraphicsSystem& gfxSystem) noexcept
|
SHADE::Handle<SHADE::SHMesh> SHPrimitiveGenerator::addMeshDataTo(const SHMeshData& meshData, SHGraphicsSystem& gfxSystem) noexcept
|
||||||
{
|
{
|
||||||
static SHMeshData meshData = Cube();
|
|
||||||
return gfxSystem.AddMesh
|
return gfxSystem.AddMesh
|
||||||
(
|
(
|
||||||
static_cast<uint32_t>(meshData.VertexPositions.size()),
|
static_cast<uint32_t>(meshData.VertexPositions.size()),
|
||||||
|
|
|
@ -59,7 +59,7 @@ namespace SHADE
|
||||||
Produces a cube and constructs a SHMesh using the SHMeshLibrary provided.
|
Produces a cube and constructs a SHMesh using the SHMeshLibrary provided.
|
||||||
|
|
||||||
\param meshLibrary
|
\param meshLibrary
|
||||||
Reference to the SHMeshLibrary to procude and store a cube mesh in.
|
Reference to the SHMeshLibrary to produce and store a cube mesh in.
|
||||||
|
|
||||||
\return
|
\return
|
||||||
SHMesh object that points to the generated cube mesh in the SHMeshLibrary.
|
SHMesh object that points to the generated cube mesh in the SHMeshLibrary.
|
||||||
|
@ -79,11 +79,54 @@ namespace SHADE
|
||||||
*/
|
*/
|
||||||
/***********************************************************************************/
|
/***********************************************************************************/
|
||||||
[[nodiscard]] static Handle<SHMesh> Cube(SHGraphicsSystem& gfxSystem) noexcept;
|
[[nodiscard]] static Handle<SHMesh> Cube(SHGraphicsSystem& gfxSystem) noexcept;
|
||||||
|
/***********************************************************************************/
|
||||||
|
/*!
|
||||||
|
\brief
|
||||||
|
Produces a sphere and stores the data in a SHMeshData object.
|
||||||
|
|
||||||
|
\return
|
||||||
|
SHMeshData object containing vertex data for the sphere.
|
||||||
|
*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
[[nodiscard]] static SHMeshData Sphere() noexcept;
|
||||||
|
/***********************************************************************************/
|
||||||
|
/*!
|
||||||
|
\brief
|
||||||
|
Produces a sphere and constructs a SHMesh using the SHMeshLibrary provided.
|
||||||
|
|
||||||
|
\param meshLibrary
|
||||||
|
Reference to the SHMeshLibrary to produce and store a sphere mesh in.
|
||||||
|
|
||||||
|
\return
|
||||||
|
SHMesh object that points to the generated sphere mesh in the SHMeshLibrary.
|
||||||
|
*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
[[nodiscard]] static Handle<SHMesh> Sphere(SHMeshLibrary& meshLibrary) noexcept;
|
||||||
|
/***********************************************************************************/
|
||||||
|
/*!
|
||||||
|
\brief
|
||||||
|
Produces a sphere and constructs a SHMesh using the SHGraphicsSystem provided.
|
||||||
|
|
||||||
|
\param gfxSystem
|
||||||
|
Reference to the SHGraphicsSystem to produce and store a sphere mesh in.
|
||||||
|
|
||||||
|
\return
|
||||||
|
SHMesh object that points to the generated sphere mesh in the SHGraphicsSystem.
|
||||||
|
*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
[[nodiscard]] static Handle<SHMesh> Sphere(SHGraphicsSystem& gfxSystem) noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Helper Functions */
|
/* Helper Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
[[nodiscard]] static SHMeshData genCubeData() noexcept;
|
static Handle<SHMesh> addMeshDataTo(const SHMeshData& meshData, SHMeshLibrary& meshLibrary) noexcept;
|
||||||
|
static Handle<SHMesh> addMeshDataTo(const SHMeshData& meshData, SHGraphicsSystem& gfxSystem) noexcept;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Data Members */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
static SHMeshData cubeMesh;
|
||||||
|
static SHMeshData sphereMesh;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -1,139 +0,0 @@
|
||||||
#include "SHPch.h"
|
|
||||||
#include "SHShaderModuleLibrary.h"
|
|
||||||
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
|
||||||
#include "Assets/SHAssetManager.h"
|
|
||||||
|
|
||||||
namespace SHADE
|
|
||||||
{
|
|
||||||
/***************************************************************************/
|
|
||||||
/*!
|
|
||||||
|
|
||||||
\brief
|
|
||||||
Imports all shader binaries from the source library.
|
|
||||||
|
|
||||||
\param logicalDeviceHdl
|
|
||||||
For creating shader modules.
|
|
||||||
|
|
||||||
\param sourceLib
|
|
||||||
The source library class that stores the container of shader binary data.
|
|
||||||
|
|
||||||
*/
|
|
||||||
/***************************************************************************/
|
|
||||||
//void SHShaderModuleLibrary::ImportFromSourceLibrary(Handle<SHVkLogicalDevice>& logicalDeviceHdl, SHShaderSourceLibrary const& sourceLib) noexcept
|
|
||||||
//{
|
|
||||||
// auto const& sources = sourceLib.GetSourceLibrary();
|
|
||||||
// for (auto const& source : sources)
|
|
||||||
// {
|
|
||||||
// vk::ShaderStageFlagBits shaderType{};
|
|
||||||
// switch (source.shaderType)
|
|
||||||
// {
|
|
||||||
// case SH_SHADER_TYPE::VERTEX:
|
|
||||||
// shaderType = vk::ShaderStageFlagBits::eVertex;
|
|
||||||
// break;
|
|
||||||
// case SH_SHADER_TYPE::FRAGMENT:
|
|
||||||
// shaderType = vk::ShaderStageFlagBits::eFragment;
|
|
||||||
// break;
|
|
||||||
// case SH_SHADER_TYPE::COMPUTE:
|
|
||||||
// shaderType = vk::ShaderStageFlagBits::eCompute;
|
|
||||||
// break;
|
|
||||||
// default:
|
|
||||||
// shaderType = vk::ShaderStageFlagBits::eVertex;
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Handle<SHVkShaderModule> newShaderModule = logicalDeviceHdl->CreateShaderModule(source.spirvBinary, "main", shaderType, source.name);
|
|
||||||
// shaderModules.emplace(source.id, newShaderModule);
|
|
||||||
// stringToID.emplace(source.name, source.id);
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
/*!
|
|
||||||
|
|
||||||
\brief
|
|
||||||
Gets the shader module based on module name.
|
|
||||||
|
|
||||||
\param shaderName
|
|
||||||
|
|
||||||
\return
|
|
||||||
|
|
||||||
*/
|
|
||||||
/***************************************************************************/
|
|
||||||
//Handle<SHVkShaderModule> SHShaderModuleLibrary::GetShaderModule(std::string shaderName) const noexcept
|
|
||||||
//{
|
|
||||||
// if (stringToID.contains(shaderName))
|
|
||||||
// return shaderModules.at(stringToID.at(shaderName));
|
|
||||||
// else
|
|
||||||
// return {};
|
|
||||||
//}
|
|
||||||
|
|
||||||
vk::ShaderStageFlagBits SHShaderModuleLibrary::GetVkShaderFlag(SH_SHADER_TYPE type) noexcept
|
|
||||||
{
|
|
||||||
vk::ShaderStageFlagBits shaderType{};
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case SH_SHADER_TYPE::VERTEX:
|
|
||||||
shaderType = vk::ShaderStageFlagBits::eVertex;
|
|
||||||
break;
|
|
||||||
case SH_SHADER_TYPE::FRAGMENT:
|
|
||||||
shaderType = vk::ShaderStageFlagBits::eFragment;
|
|
||||||
break;
|
|
||||||
case SH_SHADER_TYPE::COMPUTE:
|
|
||||||
shaderType = vk::ShaderStageFlagBits::eCompute;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
shaderType = vk::ShaderStageFlagBits::eVertex;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return shaderType;
|
|
||||||
}
|
|
||||||
|
|
||||||
Handle<SHVkShaderModule> SHShaderModuleLibrary::GetBuiltInShaderModule(std::string shaderName) const noexcept
|
|
||||||
{
|
|
||||||
if (builtInShaderModules.contains(shaderName))
|
|
||||||
return builtInShaderModules.at(shaderName);
|
|
||||||
else
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHShaderModuleLibrary::ImportAllShaderSource(Handle<SHVkLogicalDevice>& logicalDeviceHdl) noexcept
|
|
||||||
{
|
|
||||||
uint32_t idCounter{ 0 };
|
|
||||||
|
|
||||||
auto const data = SHAssetManager::GetAllDataOfType(AssetType::SHADER);
|
|
||||||
for (auto const& dataPtr : data)
|
|
||||||
{
|
|
||||||
auto const shader = dynamic_cast<SHShaderAsset const*>(dataPtr);
|
|
||||||
|
|
||||||
Handle<SHVkShaderModule> newShaderModule =
|
|
||||||
logicalDeviceHdl->CreateShaderModule(shader->spirvBinary, "main", GetVkShaderFlag(shader->shaderType), shader->name);
|
|
||||||
|
|
||||||
shaderModules.emplace(idCounter++, newShaderModule);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto const builtIn = SHAssetManager::GetAllDataOfType(AssetType::SHADER_BUILT_IN);
|
|
||||||
for (auto const& dataPtr : builtIn)
|
|
||||||
{
|
|
||||||
auto const shader = dynamic_cast<SHShaderAsset const*>(dataPtr);
|
|
||||||
|
|
||||||
Handle<SHVkShaderModule> newShaderModule =
|
|
||||||
logicalDeviceHdl->CreateShaderModule(shader->spirvBinary, "main", GetVkShaderFlag(shader->shaderType), shader->name);
|
|
||||||
|
|
||||||
builtInShaderModules.emplace(shader->name, newShaderModule);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHShaderModuleLibrary::ReflectAllShaderModules() noexcept
|
|
||||||
{
|
|
||||||
for (auto& module : shaderModules)
|
|
||||||
{
|
|
||||||
module.second->Reflect();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& module : builtInShaderModules)
|
|
||||||
{
|
|
||||||
module.second->Reflect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
#ifndef SH_SHADER_MODULE_LIBRARY_H
|
|
||||||
#define SH_SHADER_MODULE_LIBRARY_H
|
|
||||||
|
|
||||||
#include "Graphics/Shaders/SHVkShaderModule.h"
|
|
||||||
#include "Assets/Asset Types/SHShaderAsset.h"
|
|
||||||
|
|
||||||
namespace SHADE
|
|
||||||
{
|
|
||||||
class SHVkLogicalDevice;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The purpose of this shader module library is to be separate from the source library. The source library contains
|
|
||||||
* pure shader binary data that contains no vulkan related objects. Every time we load on unload a scene/level,
|
|
||||||
* this class and the source library class is cleared of its modules and recreated.
|
|
||||||
*/
|
|
||||||
class SHShaderModuleLibrary
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* PRIVATE MEMBER VARIABLES */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
//! Stored shader modules
|
|
||||||
std::unordered_map<uint32_t, Handle<SHVkShaderModule>> shaderModules;
|
|
||||||
std::unordered_map<std::string, Handle<SHVkShaderModule>> builtInShaderModules;
|
|
||||||
|
|
||||||
inline vk::ShaderStageFlagBits GetVkShaderFlag(SH_SHADER_TYPE type) noexcept;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* PUBLIC MEMBER FUNCTIONS */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
//void ImportFromSourceLibrary(Handle<SHVkLogicalDevice>& logicalDeviceHdl, SHShaderSourceLibrary const& sourceLib) noexcept;
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* SETTERS AND GETTERS */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
Handle<SHVkShaderModule> GetBuiltInShaderModule(std::string shaderName) const noexcept;
|
|
||||||
|
|
||||||
void ImportAllShaderSource(Handle<SHVkLogicalDevice>& logicalDeviceHdl) noexcept;
|
|
||||||
void ReflectAllShaderModules() noexcept;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -47,12 +47,13 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* CTORS AND DTORS */
|
/* CTORS AND DTORS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
//! For constructing a graphics pipeline
|
||||||
SHVkPipeline (Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl,
|
SHVkPipeline (Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl,
|
||||||
Handle<SHVkPipelineLayout> const& inPipelineLayout,
|
Handle<SHVkPipelineLayout> const& inPipelineLayout,
|
||||||
SHVkPipelineState const* const state,
|
SHVkPipelineState const* const state,
|
||||||
Handle<SHVkRenderpass> const& renderpassHdl,
|
Handle<SHVkRenderpass> const& renderpassHdl,
|
||||||
Handle<SHSubpass> subpass) noexcept;
|
Handle<SHSubpass> subpass) noexcept;
|
||||||
|
//! For constructing a compute pipeline
|
||||||
SHVkPipeline(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl,
|
SHVkPipeline(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl,
|
||||||
Handle<SHVkPipelineLayout> const& inPipelineLayout) noexcept;
|
Handle<SHVkPipelineLayout> const& inPipelineLayout) noexcept;
|
||||||
|
|
||||||
|
|
|
@ -54,13 +54,14 @@ namespace SHADE
|
||||||
|
|
||||||
if (wndData.isFullscreen)
|
if (wndData.isFullscreen)
|
||||||
{
|
{
|
||||||
dwExStyle = WS_EX_APPWINDOW | WS_EX_ACCEPTFILES;
|
dwExStyle = WS_EX_APPWINDOW;
|
||||||
dwStyle = WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
|
dwStyle = WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
|
||||||
|
dwExStyle |= WS_EX_ACCEPTFILES;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE | WS_EX_ACCEPTFILES;
|
dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
|
||||||
|
dwExStyle |= WS_EX_ACCEPTFILES;
|
||||||
if (wndData.frameEnabled)
|
if (wndData.frameEnabled)
|
||||||
{
|
{
|
||||||
dwStyle = WNDSTYLE::SHWS_WINDOWED;
|
dwStyle = WNDSTYLE::SHWS_WINDOWED;
|
||||||
|
@ -87,7 +88,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//DPI_AWARENESS_CONTEXT prevDPIContext = SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
|
DPI_AWARENESS_CONTEXT prevDPIContext = SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
|
||||||
|
|
||||||
RECT windowRect;
|
RECT windowRect;
|
||||||
windowRect.left = wndData.x; //or CW_USEDEFAULT ?
|
windowRect.left = wndData.x; //or CW_USEDEFAULT ?
|
||||||
|
@ -97,13 +98,16 @@ namespace SHADE
|
||||||
AdjustWindowRectEx(&windowRect, dwStyle, false, dwExStyle);
|
AdjustWindowRectEx(&windowRect, dwStyle, false, dwExStyle);
|
||||||
|
|
||||||
//Create window
|
//Create window
|
||||||
wndHWND = CreateWindowEx(0, (LPWSTR) wndData.name.c_str(), (LPWSTR)wndData.title.c_str(), dwStyle, 0, 0, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, parent, NULL, hInstance, NULL);
|
wndHWND = CreateWindowEx(dwExStyle, (LPWSTR) wndData.name.c_str(), (LPWSTR)wndData.title.c_str(), dwStyle, 0, 0, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, parent, NULL, hInstance, NULL);
|
||||||
|
|
||||||
if (!wndHWND)
|
if (!wndHWND)
|
||||||
{
|
{
|
||||||
//DWORD err = GetLastError();
|
//DWORD err = GetLastError();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
BOOL help = ChangeWindowMessageFilter (WM_DROPFILES, MSGFLT_ADD);
|
||||||
|
help &= ChangeWindowMessageFilter (WM_COPYDATA, MSGFLT_ADD);
|
||||||
|
help &= ChangeWindowMessageFilter (0x0049, MSGFLT_ADD);
|
||||||
|
|
||||||
if (wndData.isVisible)
|
if (wndData.isVisible)
|
||||||
{
|
{
|
||||||
|
@ -256,7 +260,7 @@ namespace SHADE
|
||||||
return wndHWND;
|
return wndHWND;
|
||||||
}
|
}
|
||||||
|
|
||||||
const WindowData SHWindow::GetWindowData()
|
const WindowData SHWindow::GetWindowData() const
|
||||||
{
|
{
|
||||||
return wndData;
|
return wndData;
|
||||||
}
|
}
|
||||||
|
@ -318,13 +322,13 @@ namespace SHADE
|
||||||
case WM_CREATE:
|
case WM_CREATE:
|
||||||
OnCreate(hwnd, reinterpret_cast<LPCREATESTRUCT>(wparam));
|
OnCreate(hwnd, reinterpret_cast<LPCREATESTRUCT>(wparam));
|
||||||
break;
|
break;
|
||||||
|
case WM_QUIT:
|
||||||
case WM_CLOSE:
|
case WM_CLOSE:
|
||||||
|
|
||||||
case WM_DESTROY:
|
case WM_DESTROY:
|
||||||
OnDestroy();
|
OnDestroy();
|
||||||
return 0;
|
return 0;
|
||||||
case WM_DROPFILES:
|
case WM_DROPFILES:
|
||||||
//OnFileDrop(reinterpret_cast<HDROP>(wparam));
|
OnFileDrop(reinterpret_cast<HDROP>(wparam));
|
||||||
break;
|
break;
|
||||||
case WM_ENTERSIZEMOVE:
|
case WM_ENTERSIZEMOVE:
|
||||||
case WM_EXITSIZEMOVE:
|
case WM_EXITSIZEMOVE:
|
||||||
|
@ -386,12 +390,25 @@ namespace SHADE
|
||||||
void SHWindow::OnDestroy()
|
void SHWindow::OnDestroy()
|
||||||
{
|
{
|
||||||
OnClose();
|
OnClose();
|
||||||
|
DragAcceptFiles(wndHWND, false);
|
||||||
this->Destroy();
|
this->Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
//void SHWindow::OnFileDrop(HDROP drop)
|
void SHWindow::OnFileDrop(HDROP drop)
|
||||||
//{
|
{
|
||||||
//}
|
|
||||||
|
int const numFiles = static_cast<int>(DragQueryFile(drop, 0xFFFFFFFF, nullptr, 0));
|
||||||
|
for(int i = 0; i < numFiles; ++i)
|
||||||
|
{
|
||||||
|
//char fileNameBuffer[MAX_PATH];
|
||||||
|
std::wstring fileNameBuffer;
|
||||||
|
fileNameBuffer.reserve(MAX_PATH);
|
||||||
|
DragQueryFile(drop, static_cast<UINT>(i), fileNameBuffer.data(), MAX_PATH);
|
||||||
|
std::string name(fileNameBuffer.begin(), fileNameBuffer.end());
|
||||||
|
SHLOG_INFO("Dropped: {}", name)
|
||||||
|
}
|
||||||
|
DragFinish(drop);
|
||||||
|
}
|
||||||
|
|
||||||
void SHWindow::OnSize([[maybe_unused]] UINT msg,[[maybe_unused]] UINT type, SIZE size)
|
void SHWindow::OnSize([[maybe_unused]] UINT msg,[[maybe_unused]] UINT type, SIZE size)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define SH_WINDOW_H
|
#define SH_WINDOW_H
|
||||||
|
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
#include <shellapi.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "SHWindowMap.h"
|
#include "SHWindowMap.h"
|
||||||
|
@ -47,7 +48,7 @@ namespace SHADE
|
||||||
|
|
||||||
//bool canFullscreen = true;
|
//bool canFullscreen = true;
|
||||||
|
|
||||||
unsigned bgColor = WHITE_BRUSH;
|
unsigned bgColor = DKGRAY_BRUSH;
|
||||||
|
|
||||||
//bool transparent = false;
|
//bool transparent = false;
|
||||||
|
|
||||||
|
@ -122,7 +123,7 @@ namespace SHADE
|
||||||
|
|
||||||
HWND GetHWND();
|
HWND GetHWND();
|
||||||
|
|
||||||
const WindowData GetWindowData();
|
const WindowData GetWindowData() const;
|
||||||
|
|
||||||
CALLBACKID RegisterWindowSizeCallback(WindowResizeCallbackFn);
|
CALLBACKID RegisterWindowSizeCallback(WindowResizeCallbackFn);
|
||||||
void UnregisterWindowSizeCallback(CALLBACKID const& callbackid);
|
void UnregisterWindowSizeCallback(CALLBACKID const& callbackid);
|
||||||
|
@ -168,7 +169,7 @@ namespace SHADE
|
||||||
void OnCreate(HWND hwnd, LPCREATESTRUCT create_struct);
|
void OnCreate(HWND hwnd, LPCREATESTRUCT create_struct);
|
||||||
void OnClose();
|
void OnClose();
|
||||||
void OnDestroy();
|
void OnDestroy();
|
||||||
//void OnFileDrop(HDROP drop);
|
void OnFileDrop(HDROP drop);
|
||||||
void OnSize(UINT msg, UINT type, SIZE size);
|
void OnSize(UINT msg, UINT type, SIZE size);
|
||||||
void OnPosChange(LPWINDOWPOS pos);
|
void OnPosChange(LPWINDOWPOS pos);
|
||||||
void OnPaint(HDC hdc, LPPAINTSTRUCT paint);
|
void OnPaint(HDC hdc, LPPAINTSTRUCT paint);
|
||||||
|
|
|
@ -87,19 +87,19 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHColour::SHColour() noexcept
|
SHColour::SHColour() noexcept
|
||||||
: SHVec4 { 0.0f, 0.0f, 0.0f, 1.0f }
|
: XMFLOAT4 { 0.0f, 0.0f, 0.0f, 1.0f }
|
||||||
{}
|
{}
|
||||||
|
|
||||||
SHColour::SHColour(float r, float g, float b) noexcept
|
SHColour::SHColour(float r, float g, float b) noexcept
|
||||||
: SHVec4 { r, g, b, 1.0f }
|
: XMFLOAT4 { r, g, b, 1.0f }
|
||||||
{}
|
{}
|
||||||
|
|
||||||
SHColour::SHColour(float r, float g, float b, float a) noexcept
|
SHColour::SHColour(float r, float g, float b, float a) noexcept
|
||||||
: SHVec4 { r, g, b, a }
|
: XMFLOAT4 { r, g, b, a }
|
||||||
{}
|
{}
|
||||||
|
|
||||||
SHColour::SHColour(uint8_t r, uint8_t g, uint8_t b) noexcept
|
SHColour::SHColour(uint8_t r, uint8_t g, uint8_t b) noexcept
|
||||||
: SHVec4
|
: XMFLOAT4
|
||||||
{
|
{
|
||||||
static_cast<float>(r) / 255.0f,
|
static_cast<float>(r) / 255.0f,
|
||||||
static_cast<float>(g) / 255.0f,
|
static_cast<float>(g) / 255.0f,
|
||||||
|
@ -109,7 +109,7 @@ namespace SHADE
|
||||||
{}
|
{}
|
||||||
|
|
||||||
SHColour::SHColour(uint8_t r, uint8_t g, uint8_t b, uint8_t a) noexcept
|
SHColour::SHColour(uint8_t r, uint8_t g, uint8_t b, uint8_t a) noexcept
|
||||||
: SHVec4
|
: XMFLOAT4
|
||||||
{
|
{
|
||||||
static_cast<float>(r) / 255.0f,
|
static_cast<float>(r) / 255.0f,
|
||||||
static_cast<float>(g) / 255.0f,
|
static_cast<float>(g) / 255.0f,
|
||||||
|
@ -118,12 +118,24 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
SHColour::SHColour(const DirectX::XMFLOAT3& colour) noexcept
|
SHColour::SHColour(const SHVec3& rgb) noexcept
|
||||||
: SHVec4 { colour.x, colour.y, colour.z, 1.0f }
|
: XMFLOAT4 { rgb.x, rgb.y, rgb.z, 1.0f }
|
||||||
|
{}
|
||||||
|
|
||||||
|
SHColour::SHColour(const SHVec4& rgba) noexcept
|
||||||
|
: XMFLOAT4 { rgba.x, rgba.y, rgba.z, rgba.w }
|
||||||
|
{}
|
||||||
|
|
||||||
|
SHColour::SHColour(const DirectX::XMFLOAT3& rgb) noexcept
|
||||||
|
: XMFLOAT4 { rgb.x, rgb.y, rgb.z, 1.0f }
|
||||||
|
{}
|
||||||
|
|
||||||
|
SHColour::SHColour(const DirectX::XMFLOAT4& rgba) noexcept
|
||||||
|
: XMFLOAT4 { rgba.x, rgba.y, rgba.z, rgba.w }
|
||||||
{}
|
{}
|
||||||
|
|
||||||
SHColour::SHColour(const DirectX::XMVECTORF32& colour) noexcept
|
SHColour::SHColour(const DirectX::XMVECTORF32& colour) noexcept
|
||||||
: SHVec4
|
: XMFLOAT4
|
||||||
{
|
{
|
||||||
XMVectorGetX(colour),
|
XMVectorGetX(colour),
|
||||||
XMVectorGetY(colour),
|
XMVectorGetY(colour),
|
||||||
|
@ -136,6 +148,86 @@ namespace SHADE
|
||||||
/* Operator Overload Definitions */
|
/* Operator Overload Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
SHColour::operator XMVECTOR() const noexcept
|
||||||
|
{
|
||||||
|
return XMLoadFloat4(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
SHColour::operator SHVec4() const noexcept
|
||||||
|
{
|
||||||
|
return SHVec4{ *this };
|
||||||
|
}
|
||||||
|
|
||||||
|
SHColour& SHColour::operator+=(const SHColour& rhs) noexcept
|
||||||
|
{
|
||||||
|
return *this = *this + rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHColour& SHColour::operator-=(const SHColour& rhs) noexcept
|
||||||
|
{
|
||||||
|
return *this = *this - rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHColour& SHColour::operator*=(const SHColour& rhs) noexcept
|
||||||
|
{
|
||||||
|
return *this = *this * rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHColour& SHColour::operator*=(float rhs) noexcept
|
||||||
|
{
|
||||||
|
return *this = *this * rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHColour& SHColour::operator/=(const SHColour& rhs) noexcept
|
||||||
|
{
|
||||||
|
return *this = *this / rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHColour SHColour::operator+(const SHColour& rhs) const noexcept
|
||||||
|
{
|
||||||
|
SHColour result;
|
||||||
|
|
||||||
|
XMStoreFloat4(&result, XMVectorAdd(*this, rhs));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHColour SHColour::operator-(const SHColour& rhs) const noexcept
|
||||||
|
{
|
||||||
|
SHColour result;
|
||||||
|
|
||||||
|
XMStoreFloat4(&result, XMVectorSubtract(*this, rhs));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHColour SHColour::operator-() const noexcept
|
||||||
|
{
|
||||||
|
return SHColour{ -x, -y, -z, -w };
|
||||||
|
}
|
||||||
|
|
||||||
|
SHColour SHColour::operator*(const SHColour& rhs) const noexcept
|
||||||
|
{
|
||||||
|
SHColour result;
|
||||||
|
|
||||||
|
XMStoreFloat4(&result, XMVectorMultiply(*this, rhs));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHColour SHColour::operator*(float rhs) const noexcept
|
||||||
|
{
|
||||||
|
SHColour result;
|
||||||
|
|
||||||
|
XMStoreFloat4(&result, XMVectorScale(*this, rhs));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHColour SHColour::operator/(const SHColour& rhs) const noexcept
|
||||||
|
{
|
||||||
|
SHColour result;
|
||||||
|
|
||||||
|
XMStoreFloat4(&result, XMVectorDivide(*this, rhs));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
bool SHColour::operator==(const SHColour& rhs) const noexcept
|
bool SHColour::operator==(const SHColour& rhs) const noexcept
|
||||||
{
|
{
|
||||||
return XMColorEqual(*this, rhs);
|
return XMColorEqual(*this, rhs);
|
||||||
|
@ -146,6 +238,70 @@ namespace SHADE
|
||||||
return XMColorNotEqual(*this, rhs);
|
return XMColorNotEqual(*this, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float& SHColour::operator[](int index)
|
||||||
|
{
|
||||||
|
if (index >= SIZE || index < 0)
|
||||||
|
throw std::invalid_argument("Index out of range!");
|
||||||
|
|
||||||
|
switch (index)
|
||||||
|
{
|
||||||
|
case 0: return x;
|
||||||
|
case 1: return y;
|
||||||
|
case 2: return z;
|
||||||
|
case 3: return w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float& SHColour::operator[](size_t index)
|
||||||
|
{
|
||||||
|
if (index >= SIZE || index < 0)
|
||||||
|
throw std::invalid_argument("Index out of range!");
|
||||||
|
|
||||||
|
switch (index)
|
||||||
|
{
|
||||||
|
case 0: return x;
|
||||||
|
case 1: return y;
|
||||||
|
case 2: return z;
|
||||||
|
case 3: return w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float SHColour::operator[](int index) const
|
||||||
|
{
|
||||||
|
if (index >= SIZE || index < 0)
|
||||||
|
throw std::invalid_argument("Index out of range!");
|
||||||
|
|
||||||
|
switch (index)
|
||||||
|
{
|
||||||
|
case 0: return x;
|
||||||
|
case 1: return y;
|
||||||
|
case 2: return z;
|
||||||
|
case 3: return w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float SHColour::operator[](size_t index) const
|
||||||
|
{
|
||||||
|
if (index >= SIZE || index < 0)
|
||||||
|
throw std::invalid_argument("Index out of range!");
|
||||||
|
|
||||||
|
switch (index)
|
||||||
|
{
|
||||||
|
case 0: return x;
|
||||||
|
case 1: return y;
|
||||||
|
case 2: return z;
|
||||||
|
case 3: return w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SHColour operator* (float lhs, const SHColour& rhs) noexcept
|
||||||
|
{
|
||||||
|
SHColour result;
|
||||||
|
|
||||||
|
XMStoreFloat4(&result, XMVectorScale(rhs, lhs));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Function Member Definitions */
|
/* Function Member Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -19,12 +19,6 @@
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
/* Forward Declarations */
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
class SHColour;
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -40,7 +34,7 @@ namespace SHADE
|
||||||
float v = 0.0f;
|
float v = 0.0f;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SH_API SHColour : private SHVec4
|
class SH_API SHColour : public DirectX::XMFLOAT4
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -53,9 +47,11 @@ namespace SHADE
|
||||||
SHColour (uint8_t r, uint8_t g, uint8_t b) noexcept;
|
SHColour (uint8_t r, uint8_t g, uint8_t b) noexcept;
|
||||||
SHColour (uint8_t r, uint8_t g, uint8_t b, uint8_t a) noexcept;
|
SHColour (uint8_t r, uint8_t g, uint8_t b, uint8_t a) noexcept;
|
||||||
|
|
||||||
SHColour (const SHVec3& colour) noexcept;
|
SHColour (const SHVec3& rgb) noexcept;
|
||||||
SHColour (const DirectX::XMFLOAT3& colour) noexcept;
|
SHColour (const SHVec4& rgba) noexcept;
|
||||||
SHColour (const DirectX::XMVECTORF32& colour) noexcept;
|
SHColour (const DirectX::XMFLOAT3& rgb) noexcept;
|
||||||
|
SHColour (const DirectX::XMFLOAT4& rgba) noexcept;
|
||||||
|
SHColour (const DirectX::XMVECTORF32& rgba) noexcept;
|
||||||
|
|
||||||
SHColour (const SHColour&) = default;
|
SHColour (const SHColour&) = default;
|
||||||
SHColour (SHColour&&) = default;
|
SHColour (SHColour&&) = default;
|
||||||
|
@ -69,8 +65,29 @@ namespace SHADE
|
||||||
SHColour& operator= (const SHColour&) = default;
|
SHColour& operator= (const SHColour&) = default;
|
||||||
SHColour& operator= (SHColour&&) = default;
|
SHColour& operator= (SHColour&&) = default;
|
||||||
|
|
||||||
bool operator== (const SHColour& rhs) const noexcept;
|
operator DirectX::XMVECTOR () const noexcept;
|
||||||
bool operator!= (const SHColour& rhs) const noexcept;
|
operator SHVec4 () const noexcept;
|
||||||
|
|
||||||
|
SHColour& operator+= (const SHColour& rhs) noexcept;
|
||||||
|
SHColour& operator-= (const SHColour& rhs) noexcept;
|
||||||
|
SHColour& operator*= (const SHColour& rhs) noexcept;
|
||||||
|
SHColour& operator*= (float rhs) noexcept;
|
||||||
|
SHColour& operator/= (const SHColour& rhs) noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]] SHColour operator+ (const SHColour& rhs) const noexcept;
|
||||||
|
[[nodiscard]] SHColour operator- (const SHColour& rhs) const noexcept;
|
||||||
|
[[nodiscard]] SHColour operator- () const noexcept;
|
||||||
|
[[nodiscard]] SHColour operator* (const SHColour& rhs) const noexcept;
|
||||||
|
[[nodiscard]] SHColour operator* (float rhs) const noexcept;
|
||||||
|
[[nodiscard]] SHColour operator/ (const SHColour& rhs) const noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]] bool operator== (const SHColour& rhs) const noexcept;
|
||||||
|
[[nodiscard]] bool operator!= (const SHColour& rhs) const noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]] float& operator[] (int index);
|
||||||
|
[[nodiscard]] float& operator[] (size_t index);
|
||||||
|
[[nodiscard]] float operator[] (int index) const;
|
||||||
|
[[nodiscard]] float operator[] (size_t index) const;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Properties */
|
/* Properties */
|
||||||
|
@ -105,6 +122,8 @@ namespace SHADE
|
||||||
/* Static Data Members */
|
/* Static Data Members */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
static constexpr size_t SIZE = 4U;
|
||||||
|
|
||||||
static const SHColour BEIGE ;
|
static const SHColour BEIGE ;
|
||||||
static const SHColour BLACK ;
|
static const SHColour BLACK ;
|
||||||
static const SHColour BLUE ;
|
static const SHColour BLUE ;
|
||||||
|
@ -162,5 +181,6 @@ namespace SHADE
|
||||||
static const SHColour YELLOW ;
|
static const SHColour YELLOW ;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
SHColour operator* (float lhs, const SHColour& rhs) noexcept;
|
||||||
|
|
||||||
} // namespace SHADE
|
} // namespace SHADE
|
||||||
|
|
|
@ -9,4 +9,6 @@
|
||||||
#include "SHQuaternion.h"
|
#include "SHQuaternion.h"
|
||||||
#include "SHMatrix.h"
|
#include "SHMatrix.h"
|
||||||
|
|
||||||
|
#include "SHColour.h"
|
||||||
|
|
||||||
#include "Transform/SHTransform.h"
|
#include "Transform/SHTransform.h"
|
|
@ -14,6 +14,7 @@
|
||||||
#include "SHTransformComponent.h"
|
#include "SHTransformComponent.h"
|
||||||
// Project Headers
|
// Project Headers
|
||||||
#include "Math/SHMathHelpers.h"
|
#include "Math/SHMathHelpers.h"
|
||||||
|
#include "Reflection/SHReflectionMetadata.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -184,7 +185,7 @@ RTTR_REGISTRATION
|
||||||
using namespace rttr;
|
using namespace rttr;
|
||||||
|
|
||||||
registration::class_<SHTransformComponent>("Transform Component")
|
registration::class_<SHTransformComponent>("Transform Component")
|
||||||
.property("Translate" , &SHTransformComponent::GetLocalPosition , &SHTransformComponent::SetLocalPosition )
|
.property("Translate" ,&SHTransformComponent::GetLocalPosition ,&SHTransformComponent::SetLocalPosition ) (metadata(META::tooltip, "Translate"))
|
||||||
.property("Rotate" , &SHTransformComponent::GetLocalRotation , select_overload<void(const SHVec3&)>(&SHTransformComponent::SetLocalRotation) )
|
.property("Rotate" ,&SHTransformComponent::GetLocalRotation ,select_overload<void(const SHVec3&)>(&SHTransformComponent::SetLocalRotation)) (metadata(META::tooltip, "Rotate"), metadata(META::angleInRad, true))
|
||||||
.property("Scale" , &SHTransformComponent::GetLocalScale , &SHTransformComponent::SetLocalScale );
|
.property("Scale" ,&SHTransformComponent::GetLocalScale ,&SHTransformComponent::SetLocalScale ) (metadata(META::tooltip, "Scale"));
|
||||||
}
|
}
|
|
@ -47,16 +47,14 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
// Get the current scene graph to traverse and update
|
// Get the current scene graph to traverse and update
|
||||||
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph();
|
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph();
|
||||||
|
UpdateEntity(SCENE_GRAPH.GetRoot(), !IsRunInEditorPause);
|
||||||
// TODO(Diren): Consider how to clear dirty in pause / stop mode and update physics, but do not clear in play mode.
|
|
||||||
UpdateEntity(SCENE_GRAPH.GetRoot(), false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHTransformSystem::TransformPostPhysicsUpdate::Execute(double) noexcept
|
void SHTransformSystem::TransformPostPhysicsUpdate::Execute(double) noexcept
|
||||||
{
|
{
|
||||||
// Get the current scene graph to traverse and update
|
// Get the current scene graph to traverse and update
|
||||||
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph();
|
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph();
|
||||||
UpdateEntity(SCENE_GRAPH.GetRoot(), true);
|
UpdateEntity(SCENE_GRAPH.GetRoot(), IsRunInEditorPause);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHTransformSystem::Init()
|
void SHTransformSystem::Init()
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "SHVec4.h"
|
#include "SHVec4.h"
|
||||||
// Project Headers
|
// Project Headers
|
||||||
#include "Math/SHMatrix.h"
|
#include "Math/SHMatrix.h"
|
||||||
|
#include "Math/SHColour.h"
|
||||||
#include "Tools/SHLogger.h"
|
#include "Tools/SHLogger.h"
|
||||||
|
|
||||||
using namespace DirectX;
|
using namespace DirectX;
|
||||||
|
|
|
@ -23,7 +23,9 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Forward Declarations */
|
/* Forward Declarations */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
class SHMatrix;
|
class SHMatrix;
|
||||||
|
class SHColour;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
|
|
|
@ -147,3 +147,11 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace SHADE
|
} // namespace SHADE
|
||||||
|
|
||||||
|
RTTR_REGISTRATION
|
||||||
|
{
|
||||||
|
using namespace rttr;
|
||||||
|
using namespace SHADE;
|
||||||
|
|
||||||
|
registration::class_<SHColliderComponent>("Collider Component");
|
||||||
|
}
|
|
@ -100,5 +100,6 @@ namespace SHADE
|
||||||
SHQuaternion orientation;
|
SHQuaternion orientation;
|
||||||
Colliders colliders;
|
Colliders colliders;
|
||||||
|
|
||||||
|
RTTR_ENABLE()
|
||||||
};
|
};
|
||||||
} // namespace SHADE
|
} // namespace SHADE
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
// Project Headers
|
// Project Headers
|
||||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
#include "Math/SHMathHelpers.h"
|
||||||
#include "Physics/SHPhysicsSystem.h"
|
#include "Physics/SHPhysicsSystem.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
|
@ -28,21 +29,9 @@ namespace SHADE
|
||||||
|
|
||||||
SHRigidBodyComponent::SHRigidBodyComponent() noexcept
|
SHRigidBodyComponent::SHRigidBodyComponent() noexcept
|
||||||
: type { Type::DYNAMIC }
|
: type { Type::DYNAMIC }
|
||||||
, flags { 0 }
|
|
||||||
, dirtyFlags { 0 }
|
|
||||||
, interpolate { true }
|
, interpolate { true }
|
||||||
, rp3dBody { nullptr }
|
, rp3dBody { 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 */
|
/* Getter Function Definitions */
|
||||||
|
@ -50,12 +39,24 @@ namespace SHADE
|
||||||
|
|
||||||
bool SHRigidBodyComponent::IsGravityEnabled() const noexcept
|
bool SHRigidBodyComponent::IsGravityEnabled() const noexcept
|
||||||
{
|
{
|
||||||
return flags & (1U << 0);
|
if (rp3dBody == nullptr)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rp3dBody->isGravityEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHRigidBodyComponent::IsAllowedToSleep() const noexcept
|
bool SHRigidBodyComponent::IsAllowedToSleep() const noexcept
|
||||||
{
|
{
|
||||||
return flags & (1U << 1);
|
if (rp3dBody == nullptr)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rp3dBody->isAllowedToSleep();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHRigidBodyComponent::IsInterpolating() const noexcept
|
bool SHRigidBodyComponent::IsInterpolating() const noexcept
|
||||||
|
@ -70,67 +71,151 @@ namespace SHADE
|
||||||
|
|
||||||
float SHRigidBodyComponent::GetMass() const noexcept
|
float SHRigidBodyComponent::GetMass() const noexcept
|
||||||
{
|
{
|
||||||
return mass;
|
if (rp3dBody == nullptr)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rp3dBody->getMass();
|
||||||
}
|
}
|
||||||
|
|
||||||
float SHRigidBodyComponent::GetDrag() const noexcept
|
float SHRigidBodyComponent::GetDrag() const noexcept
|
||||||
{
|
{
|
||||||
return drag;
|
if (rp3dBody == nullptr)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rp3dBody->getLinearDamping();
|
||||||
}
|
}
|
||||||
|
|
||||||
float SHRigidBodyComponent::GetAngularDrag() const noexcept
|
float SHRigidBodyComponent::GetAngularDrag() const noexcept
|
||||||
{
|
{
|
||||||
return angularDrag;
|
if (rp3dBody == nullptr)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rp3dBody->getAngularDamping();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHRigidBodyComponent::GetFreezePositionX() const noexcept
|
bool SHRigidBodyComponent::GetFreezePositionX() const noexcept
|
||||||
{
|
{
|
||||||
return flags & (1U << 2);
|
if (rp3dBody == nullptr)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& LINEAR_CONSTRAINTS = rp3dBody->getLinearLockAxisFactor();
|
||||||
|
return SHMath::CompareFloat(LINEAR_CONSTRAINTS.x, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHRigidBodyComponent::GetFreezePositionY() const noexcept
|
bool SHRigidBodyComponent::GetFreezePositionY() const noexcept
|
||||||
{
|
{
|
||||||
return flags & (1U << 3);
|
if (rp3dBody == nullptr)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& LINEAR_CONSTRAINTS = rp3dBody->getLinearLockAxisFactor();
|
||||||
|
return SHMath::CompareFloat(LINEAR_CONSTRAINTS.y, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHRigidBodyComponent::GetFreezePositionZ() const noexcept
|
bool SHRigidBodyComponent::GetFreezePositionZ() const noexcept
|
||||||
{
|
{
|
||||||
return flags & (1U << 4);
|
if (rp3dBody == nullptr)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& LINEAR_CONSTRAINTS = rp3dBody->getLinearLockAxisFactor();
|
||||||
|
return SHMath::CompareFloat(LINEAR_CONSTRAINTS.z, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHRigidBodyComponent::GetFreezeRotationX() const noexcept
|
bool SHRigidBodyComponent::GetFreezeRotationX() const noexcept
|
||||||
{
|
{
|
||||||
return flags & (1U << 5);
|
if (rp3dBody == nullptr)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& ANGULAR_CONSTRAINTS = rp3dBody->getAngularLockAxisFactor();
|
||||||
|
return SHMath::CompareFloat(ANGULAR_CONSTRAINTS.x, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHRigidBodyComponent::GetFreezeRotationY() const noexcept
|
bool SHRigidBodyComponent::GetFreezeRotationY() const noexcept
|
||||||
{
|
{
|
||||||
return flags & (1U << 6);
|
if (rp3dBody == nullptr)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& ANGULAR_CONSTRAINTS = rp3dBody->getAngularLockAxisFactor();
|
||||||
|
return SHMath::CompareFloat(ANGULAR_CONSTRAINTS.y, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHRigidBodyComponent::GetFreezeRotationZ() const noexcept
|
bool SHRigidBodyComponent::GetFreezeRotationZ() const noexcept
|
||||||
{
|
{
|
||||||
return flags & (1U << 7);
|
if (rp3dBody == nullptr)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SHVec3& SHRigidBodyComponent::GetForce() const noexcept
|
const auto& ANGULAR_CONSTRAINTS = rp3dBody->getAngularLockAxisFactor();
|
||||||
{
|
return SHMath::CompareFloat(ANGULAR_CONSTRAINTS.z, 0.0f);
|
||||||
return force;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const SHVec3& SHRigidBodyComponent::GetTorque() const noexcept
|
SHVec3 SHRigidBodyComponent::GetForce() const noexcept
|
||||||
{
|
{
|
||||||
return torque;
|
if (rp3dBody == nullptr)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SHVec3& SHRigidBodyComponent::GetLinearVelocity() const noexcept
|
return rp3dBody->getForce();
|
||||||
{
|
|
||||||
return linearVelocity;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const SHVec3& SHRigidBodyComponent::GetAngularVelocity() const noexcept
|
SHVec3 SHRigidBodyComponent::GetTorque() const noexcept
|
||||||
{
|
{
|
||||||
return angularVelocity;
|
if (rp3dBody == nullptr)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
|
return SHVec3::Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rp3dBody->getTorque();
|
||||||
|
}
|
||||||
|
|
||||||
|
SHVec3 SHRigidBodyComponent::GetLinearVelocity() const noexcept
|
||||||
|
{
|
||||||
|
if (rp3dBody == nullptr)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
|
return SHVec3::Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rp3dBody->getLinearVelocity();
|
||||||
|
}
|
||||||
|
|
||||||
|
SHVec3 SHRigidBodyComponent::GetAngularVelocity() const noexcept
|
||||||
|
{
|
||||||
|
if (rp3dBody == nullptr)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
|
return SHVec3::Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rp3dBody->getAngularVelocity();
|
||||||
}
|
}
|
||||||
|
|
||||||
const SHVec3& SHRigidBodyComponent::GetPosition() const noexcept
|
const SHVec3& SHRigidBodyComponent::GetPosition() const noexcept
|
||||||
|
@ -157,8 +242,15 @@ namespace SHADE
|
||||||
if (type == newType)
|
if (type == newType)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dirtyFlags |= 1U << 4;
|
|
||||||
type = newType;
|
type = newType;
|
||||||
|
|
||||||
|
if (rp3dBody == nullptr)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rp3dBody->setType(static_cast<rp3d::BodyType>(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRigidBodyComponent::SetGravityEnabled(bool enableGravity) noexcept
|
void SHRigidBodyComponent::SetGravityEnabled(bool enableGravity) noexcept
|
||||||
|
@ -171,8 +263,13 @@ namespace SHADE
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dirtyFlags |= 1U << FLAG_POS;
|
if (rp3dBody == nullptr)
|
||||||
enableGravity ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
|
{
|
||||||
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rp3dBody->enableGravity(enableGravity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRigidBodyComponent::SetIsAllowedToSleep(bool isAllowedToSleep) noexcept
|
void SHRigidBodyComponent::SetIsAllowedToSleep(bool isAllowedToSleep) noexcept
|
||||||
|
@ -185,92 +282,127 @@ namespace SHADE
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dirtyFlags |= 1U << 1;
|
if (rp3dBody == nullptr)
|
||||||
isAllowedToSleep ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
|
{
|
||||||
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rp3dBody->setIsAllowedToSleep(isAllowedToSleep);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRigidBodyComponent::SetFreezePositionX(bool freezePositionX) noexcept
|
void SHRigidBodyComponent::SetFreezePositionX(bool freezePositionX) noexcept
|
||||||
{
|
{
|
||||||
static constexpr int FLAG_POS = 2;
|
|
||||||
|
|
||||||
if (type == Type::STATIC)
|
if (type == Type::STATIC)
|
||||||
{
|
{
|
||||||
SHLOG_WARNING("Cannot set linear constraints of a static object {}", GetEID())
|
SHLOG_WARNING("Cannot set linear constraints of a static object {}", GetEID())
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dirtyFlags |= 1U << 2;
|
if (rp3dBody == nullptr)
|
||||||
freezePositionX ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
|
{
|
||||||
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto linearConstraints = rp3dBody->getLinearLockAxisFactor();
|
||||||
|
linearConstraints.x = freezePositionX ? 0.0f : 1.0f;
|
||||||
|
rp3dBody->setLinearLockAxisFactor(linearConstraints);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRigidBodyComponent::SetFreezePositionY(bool freezePositionY) noexcept
|
void SHRigidBodyComponent::SetFreezePositionY(bool freezePositionY) noexcept
|
||||||
{
|
{
|
||||||
static constexpr int FLAG_POS = 3;
|
|
||||||
|
|
||||||
if (type == Type::STATIC)
|
if (type == Type::STATIC)
|
||||||
{
|
{
|
||||||
SHLOG_WARNING("Cannot set linear constraints of a static object {}", GetEID())
|
SHLOG_WARNING("Cannot set linear constraints of a static object {}", GetEID())
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dirtyFlags |= 1U << 2;
|
if (rp3dBody == nullptr)
|
||||||
freezePositionY ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
|
{
|
||||||
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto linearConstraints = rp3dBody->getLinearLockAxisFactor();
|
||||||
|
linearConstraints.y = freezePositionY ? 0.0f : 1.0f;
|
||||||
|
rp3dBody->setLinearLockAxisFactor(linearConstraints);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRigidBodyComponent::SetFreezePositionZ(bool freezePositionZ) noexcept
|
void SHRigidBodyComponent::SetFreezePositionZ(bool freezePositionZ) noexcept
|
||||||
{
|
{
|
||||||
static constexpr int FLAG_POS = 4;
|
|
||||||
|
|
||||||
if (type == Type::STATIC)
|
if (type == Type::STATIC)
|
||||||
{
|
{
|
||||||
SHLOG_WARNING("Cannot set linear constraints of a static object {}", GetEID())
|
SHLOG_WARNING("Cannot set linear constraints of a static object {}", GetEID())
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dirtyFlags |= 1U << 2;
|
if (rp3dBody == nullptr)
|
||||||
freezePositionZ ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
|
{
|
||||||
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto linearConstraints = rp3dBody->getLinearLockAxisFactor();
|
||||||
|
linearConstraints.z = freezePositionZ ? 0.0f : 1.0f;
|
||||||
|
rp3dBody->setLinearLockAxisFactor(linearConstraints);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRigidBodyComponent::SetFreezeRotationX(bool freezeRotationX) noexcept
|
void SHRigidBodyComponent::SetFreezeRotationX(bool freezeRotationX) noexcept
|
||||||
{
|
{
|
||||||
static constexpr int FLAG_POS = 5;
|
|
||||||
|
|
||||||
if (type == Type::STATIC)
|
if (type == Type::STATIC)
|
||||||
{
|
{
|
||||||
SHLOG_WARNING("Cannot set angular constraints of a static object {}", GetEID())
|
SHLOG_WARNING("Cannot set angular constraints of a static object {}", GetEID())
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dirtyFlags |= 1U << 3;
|
if (rp3dBody == nullptr)
|
||||||
freezeRotationX ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
|
{
|
||||||
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto angularConstraints = rp3dBody->getAngularLockAxisFactor();
|
||||||
|
angularConstraints.x = freezeRotationX ? 0.0f : 1.0f;
|
||||||
|
rp3dBody->setAngularLockAxisFactor(angularConstraints);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRigidBodyComponent::SetFreezeRotationY(bool freezeRotationY) noexcept
|
void SHRigidBodyComponent::SetFreezeRotationY(bool freezeRotationY) noexcept
|
||||||
{
|
{
|
||||||
static constexpr int FLAG_POS = 6;
|
|
||||||
|
|
||||||
if (type == Type::STATIC)
|
if (type == Type::STATIC)
|
||||||
{
|
{
|
||||||
SHLOG_WARNING("Cannot set angular constraints of a static object {}", GetEID())
|
SHLOG_WARNING("Cannot set angular constraints of a static object {}", GetEID())
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dirtyFlags |= 1U << 3;
|
if (rp3dBody == nullptr)
|
||||||
freezeRotationY ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
|
{
|
||||||
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto angularConstraints = rp3dBody->getAngularLockAxisFactor();
|
||||||
|
angularConstraints.y = freezeRotationY ? 0.0f : 1.0f;
|
||||||
|
rp3dBody->setAngularLockAxisFactor(angularConstraints);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRigidBodyComponent::SetFreezeRotationZ(bool freezeRotationZ) noexcept
|
void SHRigidBodyComponent::SetFreezeRotationZ(bool freezeRotationZ) noexcept
|
||||||
{
|
{
|
||||||
static constexpr int FLAG_POS = 7;
|
|
||||||
|
|
||||||
if (type == Type::STATIC)
|
if (type == Type::STATIC)
|
||||||
{
|
{
|
||||||
SHLOG_WARNING("Cannot set angular constraints of a static object {}", GetEID())
|
SHLOG_WARNING("Cannot set angular constraints of a static object {}", GetEID())
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dirtyFlags |= 1U << 3;
|
if (rp3dBody == nullptr)
|
||||||
freezeRotationZ ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
|
{
|
||||||
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto angularConstraints = rp3dBody->getAngularLockAxisFactor();
|
||||||
|
angularConstraints.z = freezeRotationZ ? 0.0f : 1.0f;
|
||||||
|
rp3dBody->setAngularLockAxisFactor(angularConstraints);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRigidBodyComponent::SetInterpolate(bool allowInterpolation) noexcept
|
void SHRigidBodyComponent::SetInterpolate(bool allowInterpolation) noexcept
|
||||||
|
@ -286,8 +418,13 @@ namespace SHADE
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dirtyFlags |= 1U << 5;
|
if (rp3dBody == nullptr)
|
||||||
mass = newMass;
|
{
|
||||||
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rp3dBody->setMass(newMass);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRigidBodyComponent::SetDrag(float newDrag) noexcept
|
void SHRigidBodyComponent::SetDrag(float newDrag) noexcept
|
||||||
|
@ -298,8 +435,13 @@ namespace SHADE
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dirtyFlags |= 1U << 6;
|
if (rp3dBody == nullptr)
|
||||||
drag = newDrag;
|
{
|
||||||
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rp3dBody->setLinearDamping(newDrag);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRigidBodyComponent::SetAngularDrag(float newAngularDrag) noexcept
|
void SHRigidBodyComponent::SetAngularDrag(float newAngularDrag) noexcept
|
||||||
|
@ -310,8 +452,13 @@ namespace SHADE
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dirtyFlags |= 1U << 7;
|
if (rp3dBody == nullptr)
|
||||||
angularDrag = newAngularDrag;
|
{
|
||||||
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rp3dBody->setLinearDamping(newAngularDrag);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRigidBodyComponent::SetLinearVelocity(const SHVec3& newLinearVelocity) noexcept
|
void SHRigidBodyComponent::SetLinearVelocity(const SHVec3& newLinearVelocity) noexcept
|
||||||
|
@ -322,8 +469,13 @@ namespace SHADE
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dirtyFlags |= 1U << 8;
|
if (rp3dBody == nullptr)
|
||||||
linearVelocity = newLinearVelocity;
|
{
|
||||||
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rp3dBody->setLinearVelocity(newLinearVelocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRigidBodyComponent::SetAngularVelocity(const SHVec3& newAngularVelocity) noexcept
|
void SHRigidBodyComponent::SetAngularVelocity(const SHVec3& newAngularVelocity) noexcept
|
||||||
|
@ -334,8 +486,13 @@ namespace SHADE
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dirtyFlags |= 1U << 9;
|
if (rp3dBody == nullptr)
|
||||||
angularVelocity = newAngularVelocity;
|
{
|
||||||
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rp3dBody->setAngularVelocity(newAngularVelocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -346,7 +503,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if (rp3dBody == nullptr)
|
if (rp3dBody == nullptr)
|
||||||
{
|
{
|
||||||
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID())
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,7 +514,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if (rp3dBody == nullptr)
|
if (rp3dBody == nullptr)
|
||||||
{
|
{
|
||||||
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID())
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,7 +525,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if (rp3dBody == nullptr)
|
if (rp3dBody == nullptr)
|
||||||
{
|
{
|
||||||
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID())
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,7 +536,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if (rp3dBody == nullptr)
|
if (rp3dBody == nullptr)
|
||||||
{
|
{
|
||||||
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID())
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -390,7 +547,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if (rp3dBody == nullptr)
|
if (rp3dBody == nullptr)
|
||||||
{
|
{
|
||||||
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID())
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -401,7 +558,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if (rp3dBody == nullptr)
|
if (rp3dBody == nullptr)
|
||||||
{
|
{
|
||||||
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID())
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,7 +569,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if (rp3dBody == nullptr)
|
if (rp3dBody == nullptr)
|
||||||
{
|
{
|
||||||
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID())
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,7 +580,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if (rp3dBody == nullptr)
|
if (rp3dBody == nullptr)
|
||||||
{
|
{
|
||||||
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID())
|
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -94,10 +94,10 @@ namespace SHADE
|
||||||
[[nodiscard]] bool GetFreezeRotationY () const noexcept;
|
[[nodiscard]] bool GetFreezeRotationY () const noexcept;
|
||||||
[[nodiscard]] bool GetFreezeRotationZ () const noexcept;
|
[[nodiscard]] bool GetFreezeRotationZ () const noexcept;
|
||||||
|
|
||||||
[[nodiscard]] const SHVec3& GetForce () const noexcept;
|
[[nodiscard]] SHVec3 GetForce () const noexcept;
|
||||||
[[nodiscard]] const SHVec3& GetTorque () const noexcept;
|
[[nodiscard]] SHVec3 GetTorque () const noexcept;
|
||||||
[[nodiscard]] const SHVec3& GetLinearVelocity () const noexcept;
|
[[nodiscard]] SHVec3 GetLinearVelocity () const noexcept;
|
||||||
[[nodiscard]] const SHVec3& GetAngularVelocity () const noexcept;
|
[[nodiscard]] SHVec3 GetAngularVelocity () const noexcept;
|
||||||
|
|
||||||
[[nodiscard]] const SHVec3& GetPosition () const noexcept;
|
[[nodiscard]] const SHVec3& GetPosition () const noexcept;
|
||||||
[[nodiscard]] const SHQuaternion& GetOrientation () const noexcept;
|
[[nodiscard]] const SHQuaternion& GetOrientation () const noexcept;
|
||||||
|
@ -150,25 +150,10 @@ namespace SHADE
|
||||||
static constexpr size_t NUM_DIRTY_FLAGS = 16;
|
static constexpr size_t NUM_DIRTY_FLAGS = 16;
|
||||||
|
|
||||||
Type type;
|
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;
|
bool interpolate;
|
||||||
|
|
||||||
reactphysics3d::RigidBody* rp3dBody;
|
reactphysics3d::RigidBody* rp3dBody;
|
||||||
|
|
||||||
float mass;
|
|
||||||
float drag;
|
|
||||||
float angularDrag;
|
|
||||||
|
|
||||||
SHVec3 force;
|
|
||||||
SHVec3 linearVelocity;
|
|
||||||
|
|
||||||
SHVec3 torque;
|
|
||||||
SHVec3 angularVelocity;
|
|
||||||
|
|
||||||
SHVec3 position;
|
SHVec3 position;
|
||||||
SHQuaternion orientation;
|
SHQuaternion orientation;
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "Math/Geometry/SHBoundingSphere.h"
|
#include "Math/Geometry/SHBoundingSphere.h"
|
||||||
#include "Math/Transform/SHTransformComponent.h"
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
#include "Math/SHMathHelpers.h"
|
#include "Math/SHMathHelpers.h"
|
||||||
|
#include "Reflection/SHReflectionMetadata.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -158,6 +159,11 @@ namespace SHADE
|
||||||
return positionOffset;
|
return positionOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SHVec3& SHCollider::GetRotationOffset() const noexcept
|
||||||
|
{
|
||||||
|
return rotationOffset;
|
||||||
|
}
|
||||||
|
|
||||||
SHShape* SHCollider::GetShape() noexcept
|
SHShape* SHCollider::GetShape() noexcept
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
|
@ -275,6 +281,12 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHCollider::SetRotationOffset(const SHVec3& rotOffset) noexcept
|
||||||
|
{
|
||||||
|
dirty = true;
|
||||||
|
rotationOffset = rotOffset;
|
||||||
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Private Function Member Definitions */
|
/* Private Function Member Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -316,5 +328,6 @@ RTTR_REGISTRATION
|
||||||
);
|
);
|
||||||
|
|
||||||
registration::class_<SHCollider>("Collider")
|
registration::class_<SHCollider>("Collider")
|
||||||
.property("Position Offset", &SHCollider::GetPositionOffset, &SHCollider::SetPositionOffset);
|
.property("Position Offset", &SHCollider::GetPositionOffset, &SHCollider::SetPositionOffset)
|
||||||
|
.property("Rotation Offset", &SHCollider::GetRotationOffset, &SHCollider::SetRotationOffset) (metadata(META::angleInRad, true));
|
||||||
}
|
}
|
|
@ -80,6 +80,7 @@ namespace SHADE
|
||||||
[[nodiscard]] const SHPhysicsMaterial& GetMaterial () const noexcept;
|
[[nodiscard]] const SHPhysicsMaterial& GetMaterial () const noexcept;
|
||||||
|
|
||||||
[[nodiscard]] const SHVec3& GetPositionOffset () const noexcept;
|
[[nodiscard]] const SHVec3& GetPositionOffset () const noexcept;
|
||||||
|
[[nodiscard]] const SHVec3& GetRotationOffset () const noexcept;
|
||||||
|
|
||||||
[[nodiscard]] SHShape* GetShape () noexcept;
|
[[nodiscard]] SHShape* GetShape () noexcept;
|
||||||
|
|
||||||
|
@ -96,7 +97,8 @@ namespace SHADE
|
||||||
void SetDensity (float density) noexcept;
|
void SetDensity (float density) noexcept;
|
||||||
void SetMaterial (const SHPhysicsMaterial& newMaterial) noexcept;
|
void SetMaterial (const SHPhysicsMaterial& newMaterial) noexcept;
|
||||||
|
|
||||||
void SetPositionOffset (const SHVec3& positionOffset) noexcept;
|
void SetPositionOffset (const SHVec3& posOffset) noexcept;
|
||||||
|
void SetRotationOffset (const SHVec3& rotOffset) noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -110,6 +112,7 @@ namespace SHADE
|
||||||
SHShape* shape;
|
SHShape* shape;
|
||||||
SHPhysicsMaterial material;
|
SHPhysicsMaterial material;
|
||||||
SHVec3 positionOffset;
|
SHVec3 positionOffset;
|
||||||
|
SHVec3 rotationOffset;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
|
|
|
@ -130,6 +130,8 @@ namespace SHADE
|
||||||
|
|
||||||
int SHPhysicsObject::AddCollider(SHCollider* collider)
|
int SHPhysicsObject::AddCollider(SHCollider* collider)
|
||||||
{
|
{
|
||||||
|
const rp3d::Transform OFFSETS{ collider->GetPositionOffset(), collider->GetRotationOffset() };
|
||||||
|
|
||||||
switch (collider->GetType())
|
switch (collider->GetType())
|
||||||
{
|
{
|
||||||
case SHCollider::Type::BOX:
|
case SHCollider::Type::BOX:
|
||||||
|
@ -137,7 +139,7 @@ namespace SHADE
|
||||||
const auto* box = reinterpret_cast<SHBoundingBox*>(collider->GetShape());
|
const auto* box = reinterpret_cast<SHBoundingBox*>(collider->GetShape());
|
||||||
rp3d::BoxShape* newBox = factory->createBoxShape(box->GetHalfExtents());
|
rp3d::BoxShape* newBox = factory->createBoxShape(box->GetHalfExtents());
|
||||||
|
|
||||||
rp3dBody->addCollider(newBox, rp3d::Transform{ collider->GetPositionOffset(), SHQuaternion::Identity });
|
rp3dBody->addCollider(newBox, OFFSETS);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SHCollider::Type::SPHERE:
|
case SHCollider::Type::SPHERE:
|
||||||
|
@ -145,7 +147,7 @@ namespace SHADE
|
||||||
const auto* sphere = reinterpret_cast<SHBoundingSphere*>(collider->GetShape());
|
const auto* sphere = reinterpret_cast<SHBoundingSphere*>(collider->GetShape());
|
||||||
rp3d::SphereShape* newSphere = factory->createSphereShape(sphere->GetRadius());
|
rp3d::SphereShape* newSphere = factory->createSphereShape(sphere->GetRadius());
|
||||||
|
|
||||||
rp3dBody->addCollider(newSphere, rp3d::Transform{ collider->GetPositionOffset(), SHQuaternion::Identity });
|
rp3dBody->addCollider(newSphere, OFFSETS);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// TODO(Diren): Add more collider shapes
|
// TODO(Diren): Add more collider shapes
|
||||||
|
@ -168,96 +170,6 @@ namespace SHADE
|
||||||
rp3dBody->removeCollider(collider);
|
rp3dBody->removeCollider(collider);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHPhysicsObject::SyncRigidBody(SHRigidBodyComponent* rb) const noexcept
|
|
||||||
{
|
|
||||||
SHASSERT(rp3dBody != nullptr, "ReactPhysics body does not exist!")
|
|
||||||
|
|
||||||
if (rb->dirtyFlags == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto* rigidBody = reinterpret_cast<rp3d::RigidBody*>(rp3dBody);
|
|
||||||
|
|
||||||
const uint16_t RB_FLAGS = rb->dirtyFlags;
|
|
||||||
for (size_t i = 0; i < SHRigidBodyComponent::NUM_DIRTY_FLAGS; ++i)
|
|
||||||
{
|
|
||||||
// Check if current dirty flag has been set to true
|
|
||||||
if (RB_FLAGS & 1U << i)
|
|
||||||
{
|
|
||||||
switch (i)
|
|
||||||
{
|
|
||||||
case 0: // Gravity
|
|
||||||
{
|
|
||||||
rigidBody->enableGravity(rb->IsGravityEnabled());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 1: // Sleeping
|
|
||||||
{
|
|
||||||
rigidBody->setIsAllowedToSleep(rb->IsAllowedToSleep());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 2: // Linear Constraints
|
|
||||||
{
|
|
||||||
const rp3d::Vector3 CONSTRAINTS
|
|
||||||
{
|
|
||||||
rb->flags & 1U << 2 ? 0.0f : 1.0f,
|
|
||||||
rb->flags & 1U << 3 ? 0.0f : 1.0f,
|
|
||||||
rb->flags & 1U << 4 ? 0.0f : 1.0f
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
rigidBody->setLinearLockAxisFactor(CONSTRAINTS);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 3: // Angular Constraints
|
|
||||||
{
|
|
||||||
const rp3d::Vector3 CONSTRAINTS
|
|
||||||
{
|
|
||||||
rb->flags & 1U << 5 ? 0.0f : 1.0f,
|
|
||||||
rb->flags & 1U << 6 ? 0.0f : 1.0f,
|
|
||||||
rb->flags & 1U << 7 ? 0.0f : 1.0f
|
|
||||||
};
|
|
||||||
|
|
||||||
rigidBody->setAngularLockAxisFactor(CONSTRAINTS);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 4: // Type
|
|
||||||
{
|
|
||||||
rigidBody->setType(static_cast<rp3d::BodyType>(rb->GetType()));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 5: // Mass
|
|
||||||
{
|
|
||||||
rigidBody->setMass(rb->GetMass());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 6: // Drag
|
|
||||||
{
|
|
||||||
rigidBody->setLinearDamping(rb->GetDrag());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 7: // Angular Drag
|
|
||||||
{
|
|
||||||
rigidBody->setAngularDamping(rb->GetAngularDrag());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 8: // Linear Velocity
|
|
||||||
{
|
|
||||||
rigidBody->setLinearVelocity(rb->GetLinearVelocity());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 9: // Angular Velocity
|
|
||||||
{
|
|
||||||
rigidBody->setAngularVelocity(rb->GetAngularVelocity());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rb->dirtyFlags = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHPhysicsObject::SyncColliders(SHColliderComponent* c) const noexcept
|
void SHPhysicsObject::SyncColliders(SHColliderComponent* c) const noexcept
|
||||||
{
|
{
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
@ -266,9 +178,13 @@ namespace SHADE
|
||||||
if (!collider.dirty)
|
if (!collider.dirty)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Update offsets
|
|
||||||
auto* rp3dCollider = rp3dBody->getCollider(index);
|
auto* rp3dCollider = rp3dBody->getCollider(index);
|
||||||
rp3dCollider->setLocalToBodyTransform(rp3d::Transform(collider.GetPositionOffset(), SHQuaternion::Identity));
|
|
||||||
|
// Update trigger flag
|
||||||
|
rp3dCollider->setIsTrigger(collider.IsTrigger());
|
||||||
|
|
||||||
|
// Update offsets
|
||||||
|
rp3dCollider->setLocalToBodyTransform(rp3d::Transform(collider.GetPositionOffset(), collider.GetRotationOffset()));
|
||||||
|
|
||||||
switch (collider.GetType())
|
switch (collider.GetType())
|
||||||
{
|
{
|
||||||
|
@ -293,6 +209,8 @@ namespace SHADE
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(Diren): Update Material
|
||||||
|
|
||||||
collider.dirty = false;
|
collider.dirty = false;
|
||||||
++index;
|
++index;
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,6 @@ namespace SHADE
|
||||||
int AddCollider (SHCollider* collider);
|
int AddCollider (SHCollider* collider);
|
||||||
void RemoveCollider (int index);
|
void RemoveCollider (int index);
|
||||||
|
|
||||||
void SyncRigidBody (SHRigidBodyComponent* rb) const noexcept;
|
|
||||||
void SyncColliders (SHColliderComponent* c) const noexcept;
|
void SyncColliders (SHColliderComponent* c) const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -17,10 +17,10 @@
|
||||||
#include "ECS_Base/Managers/SHComponentManager.h"
|
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||||
#include "ECS_Base/Managers/SHEntityManager.h"
|
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
#include "Editor/SHEditor.hpp"
|
|
||||||
#include "Math/SHMathHelpers.h"
|
#include "Math/SHMathHelpers.h"
|
||||||
#include "Scene/SHSceneManager.h"
|
|
||||||
#include "Math/Transform/SHTransformComponent.h"
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
|
#include "Scene/SHSceneManager.h"
|
||||||
|
#include "Scripting/SHScriptEngine.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -99,6 +99,16 @@ namespace SHADE
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SHPhysicsSystem::CollisionEvents& SHPhysicsSystem::GetCollisionInfo() const noexcept
|
||||||
|
{
|
||||||
|
return collisionInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SHPhysicsSystem::CollisionEvents& SHPhysicsSystem::GetTriggerInfo() const noexcept
|
||||||
|
{
|
||||||
|
return triggerInfo;
|
||||||
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Setter Function Definitions */
|
/* Setter Function Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -187,6 +197,7 @@ namespace SHADE
|
||||||
settings.defaultBounciness = 0.0f;
|
settings.defaultBounciness = 0.0f;
|
||||||
|
|
||||||
world = factory.createPhysicsWorld(settings);
|
world = factory.createPhysicsWorld(settings);
|
||||||
|
world->setEventListener(this);
|
||||||
|
|
||||||
// Set up solvers
|
// Set up solvers
|
||||||
world->setContactsPositionCorrectionTechnique(rp3d::ContactsPositionCorrectionTechnique::SPLIT_IMPULSES);
|
world->setContactsPositionCorrectionTechnique(rp3d::ContactsPositionCorrectionTechnique::SPLIT_IMPULSES);
|
||||||
|
@ -200,6 +211,12 @@ namespace SHADE
|
||||||
const std::shared_ptr REMOVE_COMPONENT_RECEIVER { std::make_shared<SHEventReceiverSpec<SHPhysicsSystem>>(this, &SHPhysicsSystem::RemovePhysicsComponent) };
|
const std::shared_ptr REMOVE_COMPONENT_RECEIVER { std::make_shared<SHEventReceiverSpec<SHPhysicsSystem>>(this, &SHPhysicsSystem::RemovePhysicsComponent) };
|
||||||
const ReceiverPtr REMOVE_COMPONENT_RECEIVER_PTR = std::dynamic_pointer_cast<SHEventReceiver>(REMOVE_COMPONENT_RECEIVER);
|
const ReceiverPtr REMOVE_COMPONENT_RECEIVER_PTR = std::dynamic_pointer_cast<SHEventReceiver>(REMOVE_COMPONENT_RECEIVER);
|
||||||
SHEventManager::SubscribeTo(SH_COMPONENT_REMOVED_EVENT, REMOVE_COMPONENT_RECEIVER_PTR);
|
SHEventManager::SubscribeTo(SH_COMPONENT_REMOVED_EVENT, REMOVE_COMPONENT_RECEIVER_PTR);
|
||||||
|
|
||||||
|
#ifdef SHEDITOR
|
||||||
|
const std::shared_ptr EDITOR_STOP_RECEIVER { std::make_shared<SHEventReceiverSpec<SHPhysicsSystem>>(this, &SHPhysicsSystem::ResetWorld) };
|
||||||
|
const ReceiverPtr EDITOR_STOP_RECEIVER_PTR = std::dynamic_pointer_cast<SHEventReceiver>(EDITOR_STOP_RECEIVER);
|
||||||
|
SHEventManager::SubscribeTo(SH_EDITOR_ON_STOP_EVENT, EDITOR_STOP_RECEIVER_PTR);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHPhysicsSystem::Exit()
|
void SHPhysicsSystem::Exit()
|
||||||
|
@ -247,6 +264,9 @@ namespace SHADE
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
|
const auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
|
||||||
|
auto* rigidBodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(entityID);
|
||||||
|
auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(entityID);
|
||||||
|
|
||||||
if (transformComponent && transformComponent->HasChanged())
|
if (transformComponent && transformComponent->HasChanged())
|
||||||
{
|
{
|
||||||
const auto WORLD_POS = transformComponent->GetWorldPosition();
|
const auto WORLD_POS = transformComponent->GetWorldPosition();
|
||||||
|
@ -255,68 +275,119 @@ namespace SHADE
|
||||||
physicsObject.SetPosition(WORLD_POS);
|
physicsObject.SetPosition(WORLD_POS);
|
||||||
physicsObject.SetOrientation(WORLD_ROT);
|
physicsObject.SetOrientation(WORLD_ROT);
|
||||||
|
|
||||||
auto* rigidBodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(entityID);
|
// Sync physics component transforms
|
||||||
|
|
||||||
if (rigidBodyComponent)
|
if (rigidBodyComponent)
|
||||||
{
|
{
|
||||||
rigidBodyComponent->position = WORLD_POS;
|
rigidBodyComponent->position = WORLD_POS;
|
||||||
rigidBodyComponent->orientation = WORLD_ROT;
|
rigidBodyComponent->orientation = WORLD_ROT;
|
||||||
|
|
||||||
// Clear all forces and velocities if editor is stopped
|
|
||||||
if (SHSystemManager::GetSystem<SHEditor>()->editorState == SHEditor::State::STOP)
|
|
||||||
{
|
|
||||||
auto* rp3dRigidBody = reinterpret_cast<rp3d::RigidBody*>(physicsObject.rp3dBody);
|
|
||||||
rp3dRigidBody->resetForce();
|
|
||||||
rp3dRigidBody->resetTorque();
|
|
||||||
rp3dRigidBody->setLinearVelocity(SHVec3::Zero);
|
|
||||||
rp3dRigidBody->setAngularVelocity(SHVec3::Zero);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(entityID);
|
|
||||||
if (colliderComponent)
|
if (colliderComponent)
|
||||||
{
|
{
|
||||||
colliderComponent->position = WORLD_POS;
|
colliderComponent->position = WORLD_POS;
|
||||||
colliderComponent->orientation = WORLD_ROT;
|
colliderComponent->orientation = WORLD_ROT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sync rigid bodies
|
||||||
|
|
||||||
|
if (rigidBodyComponent)
|
||||||
|
{
|
||||||
|
// Sync active states
|
||||||
|
const bool COMPONENT_ACTIVE = rigidBodyComponent->isActive;
|
||||||
|
SyncActiveStates(physicsObject, COMPONENT_ACTIVE);
|
||||||
|
|
||||||
|
if (!COMPONENT_ACTIVE)
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update bodies and colliders if component is dirty
|
// Sync colliders
|
||||||
system->SyncRigidBodyComponents(SHComponentManager::GetDense<SHRigidBodyComponent>());
|
|
||||||
system->SyncColliderComponents(SHComponentManager::GetDense<SHColliderComponent>());
|
if (colliderComponent)
|
||||||
|
{
|
||||||
|
const bool COMPONENT_ACTIVE = colliderComponent->isActive;
|
||||||
|
SyncActiveStates(physicsObject, colliderComponent->isActive);
|
||||||
|
|
||||||
|
if (!COMPONENT_ACTIVE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
physicsObject.SyncColliders(colliderComponent);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHPhysicsSystem::PhysicsFixedUpdate::Execute(double dt) noexcept
|
void SHPhysicsSystem::PhysicsFixedUpdate::Execute(double dt) noexcept
|
||||||
{
|
{
|
||||||
auto* system = reinterpret_cast<SHPhysicsSystem*>(GetSystem());
|
auto* physicsSystem = reinterpret_cast<SHPhysicsSystem*>(GetSystem());
|
||||||
fixedTimeStep = 1.0 / system->fixedDT;
|
auto* scriptingSystem = SHSystemManager::GetSystem<SHScriptEngine>();
|
||||||
|
if (scriptingSystem == nullptr)
|
||||||
|
{
|
||||||
|
SHLOGV_WARNING("Unable to invoke FixedUpdate() on scripts due to missing SHScriptEngine!");
|
||||||
|
}
|
||||||
|
|
||||||
|
fixedTimeStep = 1.0 / physicsSystem->fixedDT;
|
||||||
accumulatedTime += dt;
|
accumulatedTime += dt;
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
while (accumulatedTime > fixedTimeStep)
|
while (accumulatedTime > fixedTimeStep)
|
||||||
{
|
{
|
||||||
system->world->update(static_cast<rp3d::decimal>(fixedTimeStep));
|
if (scriptingSystem != nullptr)
|
||||||
|
scriptingSystem->ExecuteFixedUpdates();
|
||||||
|
|
||||||
|
physicsSystem->world->update(static_cast<rp3d::decimal>(fixedTimeStep));
|
||||||
|
|
||||||
accumulatedTime -= fixedTimeStep;
|
accumulatedTime -= fixedTimeStep;
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
|
|
||||||
stats.numSteps = count;
|
stats.numSteps = count;
|
||||||
system->worldUpdated = count > 0;
|
physicsSystem->worldUpdated = count > 0;
|
||||||
|
|
||||||
system->interpolationFactor = accumulatedTime / fixedTimeStep;
|
physicsSystem->interpolationFactor = accumulatedTime / fixedTimeStep;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHPhysicsSystem::PhysicsPostUpdate::Execute(double) noexcept
|
void SHPhysicsSystem::PhysicsPostUpdate::Execute(double) noexcept
|
||||||
{
|
{
|
||||||
auto* system = reinterpret_cast<SHPhysicsSystem*>(GetSystem());
|
auto* physicsSystem = reinterpret_cast<SHPhysicsSystem*>(GetSystem());
|
||||||
|
auto* scriptingSystem = SHSystemManager::GetSystem<SHScriptEngine>();
|
||||||
|
if (scriptingSystem == nullptr)
|
||||||
|
{
|
||||||
|
SHLOGV_WARNING("Unable to invoke collision and trigger script events due to missing SHScriptEngine!");
|
||||||
|
}
|
||||||
|
|
||||||
// Interpolate transforms for rendering
|
// Interpolate transforms for rendering
|
||||||
if (system->worldUpdated)
|
if (physicsSystem->worldUpdated)
|
||||||
{
|
{
|
||||||
system->SyncTransforms();
|
physicsSystem->SyncTransforms();
|
||||||
|
|
||||||
// TODO(Diren): Handle trigger messages for scripting
|
// Collision & Trigger messages
|
||||||
|
if (scriptingSystem != nullptr)
|
||||||
|
scriptingSystem->ExecuteCollisionFunctions();
|
||||||
|
|
||||||
|
physicsSystem->ClearInvalidCollisions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHPhysicsSystem::onContact(const CallbackData& callbackData)
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < callbackData.getNbContactPairs(); ++i)
|
||||||
|
{
|
||||||
|
const auto CONTACT_PAIR = callbackData.getContactPair(i);
|
||||||
|
const SHCollisionEvent NEW_EVENT = GenerateCollisionEvent(CONTACT_PAIR);
|
||||||
|
|
||||||
|
UpdateEventContainers(NEW_EVENT, collisionInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHPhysicsSystem::onTrigger(const rp3d::OverlapCallback::CallbackData& callbackData)
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < callbackData.getNbOverlappingPairs(); ++i)
|
||||||
|
{
|
||||||
|
const auto& OVERLAP_PAIR = callbackData.getOverlappingPair(i);
|
||||||
|
const SHCollisionEvent NEW_EVENT = GenerateCollisionEvent(OVERLAP_PAIR);
|
||||||
|
|
||||||
|
UpdateEventContainers(NEW_EVENT, triggerInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,58 +424,11 @@ namespace SHADE
|
||||||
map.erase(entityID);
|
map.erase(entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHPhysicsSystem::SyncActiveStates(SHPhysicsObject* physicsObject, bool componentActive) noexcept
|
void SHPhysicsSystem::SyncActiveStates(SHPhysicsObject& physicsObject, bool componentActive) noexcept
|
||||||
{
|
{
|
||||||
const bool RP3D_ACTIVE = physicsObject->rp3dBody->isActive();
|
const bool RP3D_ACTIVE = physicsObject.rp3dBody->isActive();
|
||||||
if (RP3D_ACTIVE != componentActive)
|
if (RP3D_ACTIVE != componentActive)
|
||||||
physicsObject->rp3dBody->setIsActive(componentActive);
|
physicsObject.rp3dBody->setIsActive(componentActive);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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* physicsObject = GetPhysicsObject(ENTITY_ID);
|
|
||||||
|
|
||||||
// TODO(Diren): Check if active in hierarchy
|
|
||||||
const bool COMPONENT_ACTIVE = comp.isActive;
|
|
||||||
SyncActiveStates(physicsObject, COMPONENT_ACTIVE);
|
|
||||||
|
|
||||||
if (!COMPONENT_ACTIVE)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
physicsObject->SyncRigidBody(&comp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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* physicsObject = GetPhysicsObject(ENTITY_ID);
|
|
||||||
|
|
||||||
// TODO(Diren): Check if active in hierarchy
|
|
||||||
const bool COMPONENT_ACTIVE = comp.isActive;
|
|
||||||
SyncActiveStates(physicsObject, COMPONENT_ACTIVE);
|
|
||||||
|
|
||||||
if (!COMPONENT_ACTIVE)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
physicsObject->SyncColliders(&comp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHPhysicsSystem::SyncTransforms() noexcept
|
void SHPhysicsSystem::SyncTransforms() noexcept
|
||||||
|
@ -459,15 +483,54 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert RP3D Transform to SHADE
|
// Convert RP3D Transform to SHADE
|
||||||
auto* transformComponent = SHComponentManager::GetComponent<SHTransformComponent>(entityID);
|
auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
|
||||||
|
|
||||||
|
if (transformComponent != nullptr)
|
||||||
|
{
|
||||||
transformComponent->SetWorldPosition(rp3dPos);
|
transformComponent->SetWorldPosition(rp3dPos);
|
||||||
transformComponent->SetWorldOrientation(rp3dRot);
|
transformComponent->SetWorldOrientation(rp3dRot);
|
||||||
|
}
|
||||||
|
|
||||||
// Cache transforms
|
// Cache transforms
|
||||||
physicsObject.prevTransform = CURRENT_TF;
|
physicsObject.prevTransform = CURRENT_TF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHPhysicsSystem::UpdateEventContainers(const SHCollisionEvent& collisionEvent, CollisionEvents& container) noexcept
|
||||||
|
{
|
||||||
|
const auto IT = std::ranges::find_if(container.begin(), container.end(), [&](const SHCollisionEvent& e)
|
||||||
|
{
|
||||||
|
const bool ENTITY_MATCH = e.value[0] == collisionEvent.value[0];
|
||||||
|
const bool COLLIDERS_MATCH = e.value[1] == collisionEvent.value[1];
|
||||||
|
return ENTITY_MATCH && COLLIDERS_MATCH;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (IT == container.end())
|
||||||
|
container.emplace_back(collisionEvent);
|
||||||
|
else
|
||||||
|
IT->collisionState = collisionEvent.collisionState;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHPhysicsSystem::ClearInvalidCollisions() noexcept
|
||||||
|
{
|
||||||
|
static const auto CLEAR = [](CollisionEvents& container)
|
||||||
|
{
|
||||||
|
for (auto eventIter = container.begin(); eventIter != container.end();)
|
||||||
|
{
|
||||||
|
const bool CLEAR_EVENT = eventIter->GetCollisionState() == SHCollisionEvent::State::EXIT
|
||||||
|
|| eventIter->GetCollisionState() == SHCollisionEvent::State::INVALID;
|
||||||
|
|
||||||
|
if (CLEAR_EVENT)
|
||||||
|
eventIter = container.erase(eventIter);
|
||||||
|
else
|
||||||
|
++eventIter;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
CLEAR(collisionInfo);
|
||||||
|
CLEAR(triggerInfo);
|
||||||
|
}
|
||||||
|
|
||||||
SHEventHandle SHPhysicsSystem::AddPhysicsComponent(SHEventPtr addComponentEvent)
|
SHEventHandle SHPhysicsSystem::AddPhysicsComponent(SHEventPtr addComponentEvent)
|
||||||
{
|
{
|
||||||
const auto& EVENT_DATA = reinterpret_cast<const SHEventSpec<SHComponentAddedEvent>*>(addComponentEvent.get());
|
const auto& EVENT_DATA = reinterpret_cast<const SHEventSpec<SHComponentAddedEvent>*>(addComponentEvent.get());
|
||||||
|
@ -556,14 +619,21 @@ namespace SHADE
|
||||||
const EntityID ENTITY_ID = EVENT_DATA->data->eid;
|
const EntityID ENTITY_ID = EVENT_DATA->data->eid;
|
||||||
auto* physicsObject = GetPhysicsObject(ENTITY_ID);
|
auto* physicsObject = GetPhysicsObject(ENTITY_ID);
|
||||||
|
|
||||||
SHASSERT(physicsObject != nullptr, "Physics object has been lost from the world!")
|
auto* rigidBodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(ENTITY_ID);
|
||||||
|
auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(ENTITY_ID);
|
||||||
|
|
||||||
if (REMOVED_ID == RIGID_BODY_ID)
|
// Wake up all physics objects
|
||||||
|
for (auto& [entityID, object] : map)
|
||||||
|
{
|
||||||
|
if (SHComponentManager::HasComponent<SHRigidBodyComponent>(entityID))
|
||||||
|
reinterpret_cast<rp3d::RigidBody*>(object.rp3dBody)->setIsSleeping(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (REMOVED_ID == RIGID_BODY_ID && physicsObject != nullptr)
|
||||||
{
|
{
|
||||||
world->destroyRigidBody(reinterpret_cast<rp3d::RigidBody*>(physicsObject->rp3dBody));
|
world->destroyRigidBody(reinterpret_cast<rp3d::RigidBody*>(physicsObject->rp3dBody));
|
||||||
physicsObject->rp3dBody = nullptr;
|
physicsObject->rp3dBody = nullptr;
|
||||||
|
|
||||||
auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(ENTITY_ID);
|
|
||||||
if (colliderComponent != nullptr)
|
if (colliderComponent != nullptr)
|
||||||
{
|
{
|
||||||
// Preserve colliders as a collision body
|
// Preserve colliders as a collision body
|
||||||
|
@ -575,16 +645,9 @@ namespace SHADE
|
||||||
for (auto& collider : colliderComponent->colliders)
|
for (auto& collider : colliderComponent->colliders)
|
||||||
physicsObject->AddCollider(&collider);
|
physicsObject->AddCollider(&collider);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wake up all physics objects
|
|
||||||
for (auto& [entityID, object] : map)
|
|
||||||
{
|
|
||||||
if (SHComponentManager::HasComponent<SHRigidBodyComponent>(entityID))
|
|
||||||
reinterpret_cast<rp3d::RigidBody*>(object.rp3dBody)->setIsSleeping(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (REMOVED_ID == COLLIDER_ID)
|
if (REMOVED_ID == COLLIDER_ID && physicsObject != nullptr)
|
||||||
{
|
{
|
||||||
// Remove all colliders
|
// Remove all colliders
|
||||||
const int NUM_COLLIDERS = static_cast<int>(physicsObject->rp3dBody->getNbColliders());
|
const int NUM_COLLIDERS = static_cast<int>(physicsObject->rp3dBody->getNbColliders());
|
||||||
|
@ -594,13 +657,36 @@ namespace SHADE
|
||||||
auto* collider = physicsObject->rp3dBody->getCollider(i);
|
auto* collider = physicsObject->rp3dBody->getCollider(i);
|
||||||
physicsObject->rp3dBody->removeCollider(collider);
|
physicsObject->rp3dBody->removeCollider(collider);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for a rigidbody component
|
||||||
|
if (rigidBodyComponent == nullptr)
|
||||||
|
physicsObject->rp3dBody = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (physicsObject->rp3dBody == nullptr)
|
if (physicsObject != nullptr && physicsObject->rp3dBody == nullptr)
|
||||||
DestroyPhysicsObject(ENTITY_ID);
|
DestroyPhysicsObject(ENTITY_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
return EVENT_DATA->handle;
|
return EVENT_DATA->handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHEventHandle SHPhysicsSystem::ResetWorld(SHEventPtr editorStopEvent)
|
||||||
|
{
|
||||||
|
// TODO(Diren): Rebuild world based on how scene reloading is done
|
||||||
|
|
||||||
|
for (auto& [entityID, physicsObject] : map)
|
||||||
|
{
|
||||||
|
if (SHComponentManager::HasComponent<SHRigidBodyComponent>(entityID))
|
||||||
|
{
|
||||||
|
auto* rp3dRigidBody = reinterpret_cast<rp3d::RigidBody*>(physicsObject.rp3dBody);
|
||||||
|
rp3dRigidBody->resetForce();
|
||||||
|
rp3dRigidBody->resetTorque();
|
||||||
|
rp3dRigidBody->setLinearVelocity(SHVec3::Zero);
|
||||||
|
rp3dRigidBody->setAngularVelocity(SHVec3::Zero);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return editorStopEvent->handle;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace SHADE
|
} // namespace SHADE
|
|
@ -23,16 +23,18 @@
|
||||||
#include "Math/Transform/SHTransformComponent.h"
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
#include "Scene/SHSceneGraph.h"
|
#include "Scene/SHSceneGraph.h"
|
||||||
#include "SHPhysicsObject.h"
|
#include "SHPhysicsObject.h"
|
||||||
|
#include "SHPhysicsUtils.h"
|
||||||
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
class SH_API SHPhysicsSystem final : public SHSystem
|
class SH_API SHPhysicsSystem final : public SHSystem
|
||||||
|
, public rp3d::EventListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -47,6 +49,8 @@ namespace SHADE
|
||||||
bool sleepingEnabled;
|
bool sleepingEnabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using CollisionEvents = std::vector<SHCollisionEvent>;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Constructors & Destructor */
|
/* Constructors & Destructor */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -65,6 +69,9 @@ namespace SHADE
|
||||||
[[nodiscard]] uint16_t GetNumberVelocityIterations () const noexcept;
|
[[nodiscard]] uint16_t GetNumberVelocityIterations () const noexcept;
|
||||||
[[nodiscard]] uint16_t GetNumberPositionIterations () const noexcept;
|
[[nodiscard]] uint16_t GetNumberPositionIterations () const noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]] const CollisionEvents& GetCollisionInfo () const noexcept;
|
||||||
|
[[nodiscard]] const CollisionEvents& GetTriggerInfo () const noexcept;
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Setter Functions */
|
/* Setter Functions */
|
||||||
|
@ -85,14 +92,12 @@ namespace SHADE
|
||||||
void Init () override;
|
void Init () override;
|
||||||
void Exit () 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 AddCollisionShape (EntityID entityID, SHCollider* collider);
|
void AddCollisionShape (EntityID entityID, SHCollider* collider);
|
||||||
void RemoveCollisionShape (EntityID entityID, int index);
|
void RemoveCollisionShape (EntityID entityID, int index);
|
||||||
|
|
||||||
|
void onContact (const rp3d::CollisionCallback::CallbackData& callbackData) override;
|
||||||
|
void onTrigger (const rp3d::OverlapCallback::CallbackData& callbackData) override;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* System Routines */
|
/* System Routines */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -165,40 +170,32 @@ namespace SHADE
|
||||||
rp3d::PhysicsCommon factory;
|
rp3d::PhysicsCommon factory;
|
||||||
|
|
||||||
EntityObjectMap map;
|
EntityObjectMap map;
|
||||||
|
CollisionEvents collisionInfo;
|
||||||
|
CollisionEvents triggerInfo;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHPhysicsObject* EnsurePhysicsObject (EntityID entityID) noexcept;
|
SHPhysicsObject* EnsurePhysicsObject (EntityID entityID) noexcept;
|
||||||
SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept;
|
SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept;
|
||||||
void DestroyPhysicsObject (EntityID entityID) noexcept;
|
void DestroyPhysicsObject (EntityID entityID) noexcept;
|
||||||
|
|
||||||
void SyncActiveStates (SHPhysicsObject* physicsObject, bool componentActive) noexcept;
|
static void SyncActiveStates (SHPhysicsObject& physicsObject, bool componentActive) noexcept;
|
||||||
void SyncRigidBodyComponents (std::vector<SHRigidBodyComponent>& denseArray) noexcept;
|
|
||||||
void SyncColliderComponents (std::vector<SHColliderComponent>& denseArray) noexcept;
|
|
||||||
void SyncTransforms () noexcept;
|
void SyncTransforms () noexcept;
|
||||||
|
|
||||||
|
static void UpdateEventContainers (const SHCollisionEvent& collisionEvent, CollisionEvents& container) noexcept;
|
||||||
|
void ClearInvalidCollisions () noexcept;
|
||||||
|
|
||||||
SHEventHandle AddPhysicsComponent (SHEventPtr addComponentEvent);
|
SHEventHandle AddPhysicsComponent (SHEventPtr addComponentEvent);
|
||||||
SHEventHandle RemovePhysicsComponent (SHEventPtr removeComponentEvent);
|
SHEventHandle RemovePhysicsComponent (SHEventPtr removeComponentEvent);
|
||||||
|
SHEventHandle ResetWorld (SHEventPtr editorStopEvent);
|
||||||
|
|
||||||
|
template <typename RP3DCollisionPair, typename = std::enable_if_t
|
||||||
|
<std::is_same_v<RP3DCollisionPair, rp3d::CollisionCallback::ContactPair>
|
||||||
|
|| std::is_same_v<RP3DCollisionPair, rp3d::OverlapCallback::OverlapPair>>>
|
||||||
|
SHCollisionEvent GenerateCollisionEvent (const RP3DCollisionPair& cp) noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
/* Event Data Definitions */
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
struct SHPhysicsColliderAddedEvent
|
|
||||||
{
|
|
||||||
EntityID entityID;
|
|
||||||
SHCollider::Type colliderType;
|
|
||||||
int colliderIndex;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SHPhysicsColliderRemovedEvent
|
|
||||||
{
|
|
||||||
EntityID entityID;
|
|
||||||
int colliderIndex;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace SHADE
|
} // namespace SHADE
|
||||||
|
|
||||||
|
#include "SHPhysicsSystem.hpp"
|
|
@ -0,0 +1,84 @@
|
||||||
|
/****************************************************************************************
|
||||||
|
* \file SHPhysicsSystem.hpp
|
||||||
|
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||||
|
* \brief Implementation for templated functions 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 <type_traits>
|
||||||
|
|
||||||
|
// Primary Header
|
||||||
|
#include "SHPhysicsSystem.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Private Function Member Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
template <typename RP3DCollisionPair, typename Condition>
|
||||||
|
SHCollisionEvent SHPhysicsSystem::GenerateCollisionEvent(const RP3DCollisionPair& cp) noexcept
|
||||||
|
{
|
||||||
|
static const auto MATCH_COLLIDER = []
|
||||||
|
(
|
||||||
|
const SHPhysicsObject& physicsObject
|
||||||
|
, const rp3d::Entity colliderID
|
||||||
|
)->uint32_t
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < physicsObject.rp3dBody->getNbColliders(); ++i)
|
||||||
|
{
|
||||||
|
const auto* collider = physicsObject.rp3dBody->getCollider(i);
|
||||||
|
if (collider->getEntity() == colliderID)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::numeric_limits<uint32_t>::max();
|
||||||
|
};
|
||||||
|
|
||||||
|
SHCollisionEvent cInfo;
|
||||||
|
|
||||||
|
// Update collision state
|
||||||
|
cInfo.collisionState = static_cast<SHCollisionEvent::State>(cp.getEventType());
|
||||||
|
|
||||||
|
// Match body and collider for collision event
|
||||||
|
const rp3d::Entity body1 = cp.getBody1()->getEntity();
|
||||||
|
const rp3d::Entity body2 = cp.getBody2()->getEntity();
|
||||||
|
const rp3d::Entity collider1 = cp.getCollider1()->getEntity();
|
||||||
|
const rp3d::Entity collider2 = cp.getCollider2()->getEntity();
|
||||||
|
|
||||||
|
// Find and match both ids
|
||||||
|
bool matched[2] = { false, false };
|
||||||
|
|
||||||
|
|
||||||
|
for (auto& [entityID, physicsObject] : map)
|
||||||
|
{
|
||||||
|
// Match body 1
|
||||||
|
if (matched[SHCollisionEvent::ENTITY_A] == false && physicsObject.rp3dBody->getEntity() == body1)
|
||||||
|
{
|
||||||
|
cInfo.ids[SHCollisionEvent::ENTITY_A] = entityID;
|
||||||
|
cInfo.ids[SHCollisionEvent::COLLIDER_A] = MATCH_COLLIDER(physicsObject, collider1);
|
||||||
|
|
||||||
|
matched[SHCollisionEvent::ENTITY_A] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Match body 2
|
||||||
|
if (matched[SHCollisionEvent::ENTITY_B] == false && physicsObject.rp3dBody->getEntity() == body2)
|
||||||
|
{
|
||||||
|
cInfo.ids[SHCollisionEvent::ENTITY_B] = entityID;
|
||||||
|
cInfo.ids[SHCollisionEvent::COLLIDER_B] = MATCH_COLLIDER(physicsObject, collider2);
|
||||||
|
|
||||||
|
matched[SHCollisionEvent::ENTITY_B] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matched[SHCollisionEvent::ENTITY_A] == true && matched[SHCollisionEvent::ENTITY_B] == true)
|
||||||
|
return cInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cInfo;
|
||||||
|
}
|
||||||
|
} // namespace SHADE
|
|
@ -0,0 +1,65 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SHPhysicsSystemInterface.cpp
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Oct 31, 2022
|
||||||
|
\brief Contains the definitions of the functions of the static
|
||||||
|
SHPhysicsSystemInterface class.
|
||||||
|
|
||||||
|
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 "SHPhysicsSystemInterface.h"
|
||||||
|
// Project Includes
|
||||||
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
#include "Physics/SHPhysicsSystem.h"
|
||||||
|
#include "Physics/SHPhysicsUtils.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Static Usage Functions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
const std::vector<SHCollisionEvent>& SHPhysicsSystemInterface::GetCollisionInfo() noexcept
|
||||||
|
{
|
||||||
|
static std::vector<SHCollisionEvent> emptyVec;
|
||||||
|
|
||||||
|
auto phySystem = SHSystemManager::GetSystem<SHPhysicsSystem>();
|
||||||
|
if (phySystem)
|
||||||
|
{
|
||||||
|
return phySystem->GetCollisionInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
SHLOG_WARNING("[SHPhysicsSystemInterface] Failed to get collision events. Empty vector returned instead.");
|
||||||
|
return emptyVec;
|
||||||
|
}
|
||||||
|
const std::vector<SHCollisionEvent>& SHPhysicsSystemInterface::GetTriggerInfo() noexcept
|
||||||
|
{
|
||||||
|
static std::vector<SHCollisionEvent> emptyVec;
|
||||||
|
|
||||||
|
auto phySystem = SHSystemManager::GetSystem<SHPhysicsSystem>();
|
||||||
|
if (phySystem)
|
||||||
|
{
|
||||||
|
return phySystem->GetTriggerInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
SHLOG_WARNING("[SHPhysicsSystemInterface] Failed to get trigger events. Empty vector returned instead.");
|
||||||
|
return emptyVec;
|
||||||
|
}
|
||||||
|
|
||||||
|
double SHPhysicsSystemInterface::GetFixedDT() noexcept
|
||||||
|
{
|
||||||
|
auto phySystem = SHSystemManager::GetSystem<SHPhysicsSystem>();
|
||||||
|
if (phySystem)
|
||||||
|
{
|
||||||
|
return phySystem->GetFixedDT();
|
||||||
|
}
|
||||||
|
|
||||||
|
SHLOG_WARNING("[SHPhysicsSystemInterface] Failed to get fixed delta time. 0.0 returned instead.");
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SHPhysicsSystemInterface.h
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Oct 31, 2022
|
||||||
|
\brief Contains the definition of the SHGraphicsSystemInterface static class.
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
// STL Includes
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Forward Declarations */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
class SHCollisionEvent;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Type Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Static class that wraps up certain functions in the SHPhysicsSystem so that
|
||||||
|
/// accessing it from SHADE_Managed would not cause issues due to C++20 features.
|
||||||
|
/// </summary>
|
||||||
|
class SH_API SHPhysicsSystemInterface final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Constructor */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
SHPhysicsSystemInterface() = delete;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Static Usage Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
[[nodiscard]] static const std::vector<SHCollisionEvent>& GetCollisionInfo() noexcept;
|
||||||
|
[[nodiscard]] static const std::vector<SHCollisionEvent>& GetTriggerInfo() noexcept;
|
||||||
|
[[nodiscard]] static double GetFixedDT() noexcept;
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,93 @@
|
||||||
|
/****************************************************************************************
|
||||||
|
* \file SHPhysicsUtils.cpp
|
||||||
|
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||||
|
* \brief Implementation for some Physics Utilities
|
||||||
|
*
|
||||||
|
* \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 "SHPhysicsUtils.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Constructors & Destructor Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
SHCollisionEvent::SHCollisionEvent() noexcept
|
||||||
|
: collisionState { State::INVALID }
|
||||||
|
{
|
||||||
|
ids[ENTITY_A] = MAX_EID;
|
||||||
|
ids[ENTITY_B] = MAX_EID;
|
||||||
|
ids[COLLIDER_A] = std::numeric_limits<uint32_t>::max();
|
||||||
|
ids[COLLIDER_B] = std::numeric_limits<uint32_t>::max();
|
||||||
|
}
|
||||||
|
|
||||||
|
SHCollisionEvent::SHCollisionEvent(EntityID entityA, EntityID entityB) noexcept
|
||||||
|
: collisionState { State::INVALID }
|
||||||
|
{
|
||||||
|
ids[ENTITY_A] = entityA;
|
||||||
|
ids[ENTITY_B] = entityB;
|
||||||
|
ids[COLLIDER_A] = std::numeric_limits<uint32_t>::max();
|
||||||
|
ids[COLLIDER_B] = std::numeric_limits<uint32_t>::max();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Operator Overload Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
bool SHCollisionEvent::operator==(const SHCollisionEvent& rhs) const noexcept
|
||||||
|
{
|
||||||
|
return value[0] == rhs.value[0] && value[1] == rhs.value[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHCollisionEvent::operator!=(const SHCollisionEvent& rhs) const noexcept
|
||||||
|
{
|
||||||
|
return value[0] != rhs.value[0] || value[1] != rhs.value[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Getter Function Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
EntityID SHCollisionEvent::GetEntityA() const noexcept
|
||||||
|
{
|
||||||
|
return ids[ENTITY_A];
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityID SHCollisionEvent::GetEntityB() const noexcept
|
||||||
|
{
|
||||||
|
return ids[ENTITY_B];
|
||||||
|
}
|
||||||
|
|
||||||
|
const SHRigidBodyComponent* SHCollisionEvent::GetRigidBodyA() const noexcept
|
||||||
|
{
|
||||||
|
return SHComponentManager::GetComponent_s<SHRigidBodyComponent>(ids[ENTITY_A]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const SHRigidBodyComponent* SHCollisionEvent::GetRigidBodyB() const noexcept
|
||||||
|
{
|
||||||
|
return SHComponentManager::GetComponent_s<SHRigidBodyComponent>(ids[ENTITY_B]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const SHCollider* SHCollisionEvent::GetColliderA() const noexcept
|
||||||
|
{
|
||||||
|
return &SHComponentManager::GetComponent<SHColliderComponent>(ids[ENTITY_A])->GetCollider(ids[COLLIDER_A]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const SHCollider* SHCollisionEvent::GetColliderB() const noexcept
|
||||||
|
{
|
||||||
|
return &SHComponentManager::GetComponent<SHColliderComponent>(ids[ENTITY_B])->GetCollider(ids[COLLIDER_B]);
|
||||||
|
}
|
||||||
|
|
||||||
|
SHCollisionEvent::State SHCollisionEvent::GetCollisionState() const noexcept
|
||||||
|
{
|
||||||
|
return collisionState;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace SHADE
|
|
@ -0,0 +1,116 @@
|
||||||
|
/****************************************************************************************
|
||||||
|
* \file SHPhysicsUtils.h
|
||||||
|
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||||
|
* \brief Interface for some Physics Utilities
|
||||||
|
*
|
||||||
|
* \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 "Components/SHColliderComponent.h"
|
||||||
|
#include "Components/SHRigidBodyComponent.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Type Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
struct SHPhysicsColliderAddedEvent
|
||||||
|
{
|
||||||
|
EntityID entityID;
|
||||||
|
SHCollider::Type colliderType;
|
||||||
|
int colliderIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SHPhysicsColliderRemovedEvent
|
||||||
|
{
|
||||||
|
EntityID entityID;
|
||||||
|
int colliderIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SH_API SHCollisionEvent
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Friends */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
friend class SHPhysicsSystem;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Type Definitions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
enum class State
|
||||||
|
{
|
||||||
|
ENTER
|
||||||
|
, STAY
|
||||||
|
, EXIT
|
||||||
|
|
||||||
|
, TOTAL
|
||||||
|
, INVALID = -1
|
||||||
|
};
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Constructors & Destructor */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
SHCollisionEvent () noexcept;
|
||||||
|
SHCollisionEvent (EntityID entityA, EntityID entityB) noexcept;
|
||||||
|
|
||||||
|
|
||||||
|
SHCollisionEvent (const SHCollisionEvent& rhs) = default;
|
||||||
|
SHCollisionEvent (SHCollisionEvent&& rhs) = default;
|
||||||
|
~SHCollisionEvent () = default;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Operator Overloads */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
bool operator== (const SHCollisionEvent& rhs) const noexcept;
|
||||||
|
bool operator!= (const SHCollisionEvent& rhs) const noexcept;
|
||||||
|
|
||||||
|
SHCollisionEvent& operator= (const SHCollisionEvent& rhs) = default;
|
||||||
|
SHCollisionEvent& operator= (SHCollisionEvent&& rhs) = default;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Getter Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
[[nodiscard]] EntityID GetEntityA () const noexcept;
|
||||||
|
[[nodiscard]] EntityID GetEntityB () const noexcept;
|
||||||
|
[[nodiscard]] const SHRigidBodyComponent* GetRigidBodyA () const noexcept;
|
||||||
|
[[nodiscard]] const SHRigidBodyComponent* GetRigidBodyB () const noexcept;
|
||||||
|
[[nodiscard]] const SHCollider* GetColliderA () const noexcept;
|
||||||
|
[[nodiscard]] const SHCollider* GetColliderB () const noexcept;
|
||||||
|
[[nodiscard]] State GetCollisionState () const noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
static constexpr uint32_t ENTITY_A = 0;
|
||||||
|
static constexpr uint32_t ENTITY_B = 1;
|
||||||
|
static constexpr uint32_t COLLIDER_A = 2;
|
||||||
|
static constexpr uint32_t COLLIDER_B = 3;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Data Members */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
uint64_t value[2]; // EntityValue, ColliderIndexValue
|
||||||
|
uint32_t ids [4]; // EntityA, EntityB, ColliderIndexA, ColliderIndexB
|
||||||
|
};
|
||||||
|
|
||||||
|
State collisionState;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace SHADE
|
|
@ -7,5 +7,6 @@ namespace SHADE
|
||||||
constexpr const char* min = "MIN";
|
constexpr const char* min = "MIN";
|
||||||
constexpr const char* max = "MAX";
|
constexpr const char* max = "MAX";
|
||||||
constexpr const char* tooltip = "tooltip";
|
constexpr const char* tooltip = "tooltip";
|
||||||
|
constexpr const char* angleInRad = "angleInRad";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,9 +21,11 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
SHResourceHub SHResourceManager::resourceHub;
|
SHResourceHub SHResourceManager::resourceHub;
|
||||||
std::unordered_map<std::type_index, std::unordered_map<AssetID, Handle<void>>> SHResourceManager::handlesMap;
|
std::unordered_map<std::type_index, std::unordered_map<AssetID, Handle<void>>> SHResourceManager::handlesMap;
|
||||||
std::unordered_map<std::type_index, SHADE::SHResourceManager::HandleAssetMap> SHResourceManager::assetIdMap;
|
std::unordered_map<std::type_index, SHResourceManager::HandleAssetMap> SHResourceManager::assetIdMap;
|
||||||
std::unordered_map<std::type_index, std::function<void(AssetID)>> SHResourceManager::typedFreeFuncMap;
|
std::unordered_map<std::type_index, std::function<void(AssetID)>> SHResourceManager::typedFreeFuncMap;
|
||||||
std::vector<AssetID> SHResourceManager::loadedAssetData;
|
std::vector<AssetID> SHResourceManager::loadedAssetData;
|
||||||
|
bool SHResourceManager::textureChanged = false;
|
||||||
|
bool SHResourceManager::meshChanged = false;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Function Definitions */
|
/* Function Definitions */
|
||||||
|
@ -63,8 +65,17 @@ namespace SHADE
|
||||||
SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||||
if (gfxSystem == nullptr)
|
if (gfxSystem == nullptr)
|
||||||
throw std::runtime_error("[SHResourceManager] Attempted to load graphics resource without a SHGraphicsSystem installed.");
|
throw std::runtime_error("[SHResourceManager] Attempted to load graphics resource without a SHGraphicsSystem installed.");
|
||||||
|
|
||||||
|
if (meshChanged)
|
||||||
|
{
|
||||||
gfxSystem->BuildMeshBuffers();
|
gfxSystem->BuildMeshBuffers();
|
||||||
|
meshChanged = false;
|
||||||
|
}
|
||||||
|
if (textureChanged)
|
||||||
|
{
|
||||||
gfxSystem->BuildTextures();
|
gfxSystem->BuildTextures();
|
||||||
|
textureChanged = false;
|
||||||
|
}
|
||||||
|
|
||||||
// Free CPU Resources
|
// Free CPU Resources
|
||||||
for (auto assetId : loadedAssetData)
|
for (auto assetId : loadedAssetData)
|
||||||
|
|
|
@ -17,9 +17,27 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "SH_API.h"
|
#include "SH_API.h"
|
||||||
#include "SHResourceLibrary.h"
|
#include "SHResourceLibrary.h"
|
||||||
#include "Assets/SHAssetMacros.h"
|
#include "Assets/SHAssetMacros.h"
|
||||||
|
#include "Assets/Asset Types/SHMeshAsset.h"
|
||||||
|
#include "Assets/Asset Types/SHTextureAsset.h"
|
||||||
|
#include "Assets/Asset Types/SHShaderAsset.h"
|
||||||
|
#include "Graphics/Shaders/SHVkShaderModule.h"
|
||||||
|
#include "Graphics/MiddleEnd/Textures/SHTextureLibrary.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHMeshLibrary.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHMaterial.h"
|
||||||
|
#include "Assets/Asset Types/SHMaterialAsset.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Template structs that maps a resource to their loaded asset representation type.
|
||||||
|
/// </summary>
|
||||||
|
template<typename T = void>
|
||||||
|
struct SHResourceLoader { using AssetType = void; };
|
||||||
|
template<> struct SHResourceLoader<SHMesh> { using AssetType = SHMeshAsset; };
|
||||||
|
template<> struct SHResourceLoader<SHTexture> { using AssetType = SHTextureAsset; };
|
||||||
|
template<> struct SHResourceLoader<SHVkShaderModule> { using AssetType = SHShaderAsset; };
|
||||||
|
template<> struct SHResourceLoader<SHMaterial> { using AssetType = SHMaterialAsset; };
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Static class responsible for loading and caching runtime resources from their
|
/// Static class responsible for loading and caching runtime resources from their
|
||||||
/// serialised Asset IDs.
|
/// serialised Asset IDs.
|
||||||
|
@ -61,7 +79,7 @@ namespace SHADE
|
||||||
/// <param name="assetId">Handle to the resource to unload.</param>
|
/// <param name="assetId">Handle to the resource to unload.</param>
|
||||||
static void Unload(AssetID assetId);
|
static void Unload(AssetID assetId);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Needs to be called to finalise all changes to loads.
|
/// Needs to be called to finalise all changes to loads, unless at runtime.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
static void FinaliseChanges();
|
static void FinaliseChanges();
|
||||||
|
|
||||||
|
@ -111,6 +129,9 @@ namespace SHADE
|
||||||
static std::unordered_map<std::type_index, std::function<void(AssetID)>> typedFreeFuncMap;
|
static std::unordered_map<std::type_index, std::function<void(AssetID)>> typedFreeFuncMap;
|
||||||
// Pointers to temp CPU resources
|
// Pointers to temp CPU resources
|
||||||
static std::vector<AssetID> loadedAssetData;
|
static std::vector<AssetID> loadedAssetData;
|
||||||
|
// Dirty Flags
|
||||||
|
static bool meshChanged;
|
||||||
|
static bool textureChanged;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Helper Functions */
|
/* Helper Functions */
|
||||||
|
@ -124,6 +145,14 @@ namespace SHADE
|
||||||
/// <returns>Reference to the AssetHandleMap of the specified type.</returns>
|
/// <returns>Reference to the AssetHandleMap of the specified type.</returns>
|
||||||
template<typename ResourceType>
|
template<typename ResourceType>
|
||||||
static std::pair<AssetHandleMapRef, HandleAssetMapRef> getAssetHandleMap();
|
static std::pair<AssetHandleMapRef, HandleAssetMapRef> getAssetHandleMap();
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="ResourceType"></typeparam>
|
||||||
|
/// <param name="assetData"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
template<typename ResourceType>
|
||||||
|
static Handle<ResourceType> load(AssetID assetId, const typename SHResourceLoader<ResourceType>::AssetType& assetData);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,12 +13,17 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#pragma once
|
#pragma once
|
||||||
// Primary Include
|
// Primary Include
|
||||||
#include "SHResourceManager.h"
|
#include "SHResourceManager.h"
|
||||||
|
// External Dependencies
|
||||||
|
#include <yaml-cpp/yaml.h>
|
||||||
// Project Includes
|
// Project Includes
|
||||||
#include "Assets/SHAssetManager.h"
|
#include "Assets/SHAssetManager.h"
|
||||||
#include "Assets/Asset Types/SHAssetIncludes.h"
|
#include "Assets/Asset Types/SHAssetIncludes.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
||||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
#include "Tools/SHLog.h"
|
#include "Tools/SHLog.h"
|
||||||
|
#include "Graphics/Shaders/SHVkShaderModule.h"
|
||||||
|
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||||
|
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -40,67 +45,19 @@ namespace SHADE
|
||||||
return Handle<ResourceType>(typedHandleMap.get()[assetId]);
|
return Handle<ResourceType>(typedHandleMap.get()[assetId]);
|
||||||
|
|
||||||
/* Otherwise, we need to load it! */
|
/* Otherwise, we need to load it! */
|
||||||
// Meshes
|
// Load Asset Data
|
||||||
if constexpr (std::is_same_v<ResourceType, SHMesh>)
|
const auto* assetData = SHAssetManager::GetData<SHResourceLoader<ResourceType>::AssetType>(assetId);
|
||||||
{
|
|
||||||
// Get system
|
|
||||||
SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
|
||||||
if (gfxSystem == nullptr)
|
|
||||||
throw std::runtime_error("[SHResourceManager] Attempted to load graphics resource without a SHGraphicsSystem installed.");
|
|
||||||
|
|
||||||
// Load
|
|
||||||
const SHMeshAsset* assetData = SHAssetManager::GetData<SHMeshAsset>(assetId);
|
|
||||||
if (assetData == nullptr)
|
if (assetData == nullptr)
|
||||||
{
|
{
|
||||||
SHLog::Warning("[SHResourceManager] Attempted to load an asset with an invalid Asset ID.");
|
SHLog::Warning("[SHResourceManager] Attempted to load an asset with an invalid Asset ID.");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
loadedAssetData.emplace_back(assetId);
|
|
||||||
|
|
||||||
Handle<SHMesh> meshHandle = gfxSystem->AddMesh
|
auto handle = load<ResourceType>(assetId, *assetData);
|
||||||
(
|
Handle genericHandle = Handle(handle);
|
||||||
assetData->vertexPosition.size(),
|
|
||||||
assetData->vertexPosition.data(),
|
|
||||||
assetData->texCoords.data(),
|
|
||||||
assetData->vertexTangent.data(),
|
|
||||||
assetData->vertexNormal.data(),
|
|
||||||
assetData->indices.size(),
|
|
||||||
assetData->indices.data()
|
|
||||||
);
|
|
||||||
Handle genericHandle = Handle(meshHandle);
|
|
||||||
typedHandleMap.get().emplace(assetId, genericHandle);
|
typedHandleMap.get().emplace(assetId, genericHandle);
|
||||||
typedAssetIdMap.get().emplace(genericHandle, assetId);
|
typedAssetIdMap.get().emplace(genericHandle, assetId);
|
||||||
return meshHandle;
|
return handle;
|
||||||
}
|
|
||||||
// Textures
|
|
||||||
else if constexpr (std::is_same_v<ResourceType, SHTexture>)
|
|
||||||
{
|
|
||||||
// Get system
|
|
||||||
SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
|
||||||
if (gfxSystem == nullptr)
|
|
||||||
throw std::runtime_error("[SHResourceManager] Attempted to load graphics resource without a SHGraphicsSystem installed.");
|
|
||||||
|
|
||||||
// Load
|
|
||||||
const SHTextureAsset* assetData = SHAssetManager::GetData<SHTextureAsset>(assetId);
|
|
||||||
if (assetData == nullptr)
|
|
||||||
{
|
|
||||||
SHLog::Warning("[SHResourceManager] Attempted to load an asset with an invalid Asset ID.");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
loadedAssetData.emplace_back(assetId);
|
|
||||||
|
|
||||||
Handle<SHTexture> texHandle = gfxSystem->AddTexture
|
|
||||||
(
|
|
||||||
assetData->numBytes,
|
|
||||||
assetData->pixelData,
|
|
||||||
assetData->width,
|
|
||||||
assetData->height,
|
|
||||||
assetData->format,
|
|
||||||
assetData->mipOffsets
|
|
||||||
);
|
|
||||||
typedHandleMap.get().emplace(assetId, Handle(texHandle));
|
|
||||||
return texHandle;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ResourceType>
|
template<typename ResourceType>
|
||||||
|
@ -169,4 +126,131 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
return std::make_pair(std::ref(handlesMap[TYPE]), std::ref(assetIdMap[TYPE]));
|
return std::make_pair(std::ref(handlesMap[TYPE]), std::ref(assetIdMap[TYPE]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename ResourceType>
|
||||||
|
Handle<ResourceType> SHResourceManager::load(AssetID assetId, const typename SHResourceLoader<ResourceType>::AssetType& assetData)
|
||||||
|
{
|
||||||
|
// Get system
|
||||||
|
SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||||
|
if (gfxSystem == nullptr)
|
||||||
|
throw std::runtime_error("[SHResourceManager] Attempted to load graphics resource without a SHGraphicsSystem installed.");
|
||||||
|
|
||||||
|
// Meshes
|
||||||
|
if constexpr (std::is_same_v<ResourceType, SHMesh>)
|
||||||
|
{
|
||||||
|
loadedAssetData.emplace_back(assetId);
|
||||||
|
meshChanged = true;
|
||||||
|
|
||||||
|
return gfxSystem->AddMesh
|
||||||
|
(
|
||||||
|
assetData.vertexPosition.size(),
|
||||||
|
assetData.vertexPosition.data(),
|
||||||
|
assetData.texCoords.data(),
|
||||||
|
assetData.vertexTangent.data(),
|
||||||
|
assetData.vertexNormal.data(),
|
||||||
|
assetData.indices.size(),
|
||||||
|
assetData.indices.data()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// Textures
|
||||||
|
else if constexpr (std::is_same_v<ResourceType, SHTexture>)
|
||||||
|
{
|
||||||
|
loadedAssetData.emplace_back(assetId);
|
||||||
|
textureChanged = true;
|
||||||
|
|
||||||
|
return gfxSystem->AddTexture
|
||||||
|
(
|
||||||
|
assetData.numBytes,
|
||||||
|
assetData.pixelData,
|
||||||
|
assetData.width,
|
||||||
|
assetData.height,
|
||||||
|
assetData.format,
|
||||||
|
assetData.mipOffsets
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// Shaders
|
||||||
|
else if constexpr (std::is_same_v<ResourceType, SHVkShaderModule>)
|
||||||
|
{
|
||||||
|
auto shader = gfxSystem->GetDevice()->CreateShaderModule
|
||||||
|
(
|
||||||
|
assetData.spirvBinary,
|
||||||
|
"main",
|
||||||
|
static_cast<vk::ShaderStageFlagBits>(assetData.shaderType),
|
||||||
|
assetData.name
|
||||||
|
);
|
||||||
|
shader->Reflect();
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
// Materials
|
||||||
|
else if constexpr (std::is_same_v<ResourceType, SHMaterial>)
|
||||||
|
{
|
||||||
|
// Get the data we need to construct
|
||||||
|
SHMaterialSpec matSpec = YAML::Node(assetData.data).as<SHMaterialSpec>();
|
||||||
|
|
||||||
|
// Load shaders
|
||||||
|
auto vertexShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(matSpec.vertexShader);
|
||||||
|
auto fragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(matSpec.fragShader);
|
||||||
|
|
||||||
|
// Ensure that both shaders are present
|
||||||
|
if (!(vertexShader && fragShader))
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("[SHResourceManager] Failed to load material as shaders failed to be loaded.");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grab subpass from worldRenderer
|
||||||
|
auto renderPass = gfxSystem->GetPrimaryRenderpass();
|
||||||
|
if (!renderPass)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("[SHResourceManager] Failed to load material as RenderPass could not be found.");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
auto subPass = renderPass->GetSubpass(matSpec.subpassName);
|
||||||
|
if (!subPass)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("[SHResourceManager] Failed to load material as SubPass could not be found.");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create material
|
||||||
|
auto matHandle = gfxSystem->AddMaterial(vertexShader, fragShader, subPass);
|
||||||
|
|
||||||
|
// Set properties for the material
|
||||||
|
Handle<SHShaderBlockInterface> pipelineProperties = matHandle->GetShaderBlockInterface();
|
||||||
|
for (int i = 0; i < static_cast<int>(pipelineProperties->GetVariableCount()); ++i)
|
||||||
|
{
|
||||||
|
const std::string& PROP_NAME = pipelineProperties->GetVariableName(i);
|
||||||
|
const auto& PROP_NODE = matSpec.properties;
|
||||||
|
if (PROP_NODE)
|
||||||
|
{
|
||||||
|
const std::string& VAR_NAME = pipelineProperties->GetVariableName(i);
|
||||||
|
const SHShaderBlockInterface::Variable* VARIABLE = pipelineProperties->GetVariable(i);
|
||||||
|
switch (VARIABLE->type)
|
||||||
|
{
|
||||||
|
case SHADE::SHShaderBlockInterface::Variable::Type::FLOAT:
|
||||||
|
matHandle->SetProperty(VARIABLE->offset, PROP_NODE.as<float>());
|
||||||
|
break;
|
||||||
|
case SHADE::SHShaderBlockInterface::Variable::Type::INT:
|
||||||
|
matHandle->SetProperty(VARIABLE->offset, PROP_NODE.as<int>());
|
||||||
|
break;
|
||||||
|
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR2:
|
||||||
|
matHandle->SetProperty(VARIABLE->offset, PROP_NODE.as<SHVec2>());
|
||||||
|
break;
|
||||||
|
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR3:
|
||||||
|
matHandle->SetProperty(VARIABLE->offset, PROP_NODE.as<SHVec3>());
|
||||||
|
break;
|
||||||
|
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR4:
|
||||||
|
matHandle->SetProperty(VARIABLE->offset, PROP_NODE.as<SHVec4>());
|
||||||
|
break;
|
||||||
|
case SHADE::SHShaderBlockInterface::Variable::Type::OTHER:
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return matHandle;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,10 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
csScriptsExecuteFixedUpdate();
|
csScriptsExecuteFixedUpdate();
|
||||||
}
|
}
|
||||||
|
void SHScriptEngine::ExecuteCollisionFunctions()
|
||||||
|
{
|
||||||
|
csScriptsExecutePhysicsEvents();
|
||||||
|
}
|
||||||
void SHScriptEngine::Exit()
|
void SHScriptEngine::Exit()
|
||||||
{
|
{
|
||||||
// Do not allow deinitialization if not initialised
|
// Do not allow deinitialization if not initialised
|
||||||
|
@ -377,6 +380,12 @@ namespace SHADE
|
||||||
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
||||||
"ExecuteLateUpdate"
|
"ExecuteLateUpdate"
|
||||||
);
|
);
|
||||||
|
csScriptsExecutePhysicsEvents = dotNet.GetFunctionPtr<CsFuncPtr>
|
||||||
|
(
|
||||||
|
DEFAULT_CSHARP_LIB_NAME,
|
||||||
|
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
||||||
|
"ExecuteCollisionFunctions"
|
||||||
|
);
|
||||||
csScriptsFrameCleanUp = dotNet.GetFunctionPtr<CsFuncPtr>
|
csScriptsFrameCleanUp = dotNet.GetFunctionPtr<CsFuncPtr>
|
||||||
(
|
(
|
||||||
DEFAULT_CSHARP_LIB_NAME,
|
DEFAULT_CSHARP_LIB_NAME,
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue