Merge branch 'main' into SP3-5-ECS
This commit is contained in:
commit
43604066b2
Binary file not shown.
|
@ -1,3 +1,3 @@
|
|||
Name: DeferredComposite_CS
|
||||
ID: 42814284
|
||||
ID: 45072428
|
||||
Type: 2
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,3 +1,3 @@
|
|||
Name: TestCube_FS
|
||||
ID: 37450402
|
||||
ID: 46377769
|
||||
Type: 2
|
||||
|
|
Binary file not shown.
|
@ -1,3 +1,3 @@
|
|||
Name: TestCube_VS
|
||||
ID: 41688429
|
||||
ID: 39210065
|
||||
Type: 2
|
||||
|
|
|
@ -108,13 +108,10 @@ namespace Sandbox
|
|||
SHComponentManager::CreateComponentSparseSet<SHColliderComponent>();
|
||||
SHComponentManager::CreateComponentSparseSet<SHTransformComponent>();
|
||||
SHComponentManager::CreateComponentSparseSet<SHRenderable>();
|
||||
SHComponentManager::CreateComponentSparseSet<SHCameraComponent>();
|
||||
//SHComponentManager::CreateComponentSparseSet<SHCameraComponent>();
|
||||
|
||||
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>();
|
||||
|
||||
|
|
|
@ -128,7 +128,6 @@ namespace Sandbox
|
|||
floorRigidBody.SetType(SHRigidBodyComponent::Type::STATIC);
|
||||
|
||||
auto* floorBox = floorCollider.AddBoundingBox();
|
||||
floorBox->SetHalfExtents(floorTransform.GetWorldScale() * 0.5f);
|
||||
|
||||
// Create blank entity with a script
|
||||
//testObj = SHADE::SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
*****************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <vulkan/vulkan.hpp>
|
||||
#include "SHAssetData.h"
|
||||
#include "SH_API.h"
|
||||
#include <vector>
|
||||
|
@ -17,12 +18,14 @@
|
|||
|
||||
namespace SHADE
|
||||
{
|
||||
//! Tighter control over types of shaders. Maps directly to their
|
||||
//! equivalent vk::ShaderStageFlagBits.
|
||||
enum class SH_SHADER_TYPE : uint8_t
|
||||
{
|
||||
VERTEX,
|
||||
FRAGMENT,
|
||||
COMPUTE,
|
||||
INAVLID_TYPE
|
||||
VERTEX = static_cast<uint8_t>(vk::ShaderStageFlagBits::eVertex),
|
||||
FRAGMENT = static_cast<uint8_t>(vk::ShaderStageFlagBits::eFragment),
|
||||
COMPUTE = static_cast<uint8_t>(vk::ShaderStageFlagBits::eCompute),
|
||||
INAVLID_TYPE = std::numeric_limits<uint8_t>::max()
|
||||
};
|
||||
|
||||
struct SH_API SHShaderAsset : SHAssetData
|
||||
|
|
|
@ -19,144 +19,145 @@
|
|||
|
||||
namespace SHADE
|
||||
{
|
||||
std::string SHShaderSourceCompiler::CompileShaderSourceToBinary(AssetPath path, SHShaderAsset const& data) noexcept
|
||||
{
|
||||
std::string newPath{ path.string() };
|
||||
std::string SHShaderSourceCompiler::CompileShaderSourceToBinary(AssetPath path, SHShaderAsset const& data) noexcept
|
||||
{
|
||||
std::string newPath{ path.string() };
|
||||
newPath = newPath.substr(0, newPath.find_last_of('.'));
|
||||
newPath += SHADER_BUILT_IN_EXTENSION.data();
|
||||
|
||||
std::ofstream file{ newPath, std::ios::binary | std::ios::out | std::ios::trunc };
|
||||
std::ofstream file{ newPath, std::ios::binary | std::ios::out | std::ios::trunc };
|
||||
|
||||
file.write(
|
||||
reinterpret_cast<char const*>(& data.shaderType), sizeof(uint8_t)
|
||||
);
|
||||
file.write(
|
||||
reinterpret_cast<char const*>(& data.shaderType), sizeof(uint8_t)
|
||||
);
|
||||
|
||||
size_t const byteCount = sizeof(uint32_t) * data.spirvBinary.size();
|
||||
size_t const byteCount = sizeof(uint32_t) * data.spirvBinary.size();
|
||||
|
||||
file.write(
|
||||
reinterpret_cast<char const*>(&byteCount), sizeof(size_t)
|
||||
);
|
||||
file.write(
|
||||
reinterpret_cast<char const*>(&byteCount), sizeof(size_t)
|
||||
);
|
||||
|
||||
file.write(
|
||||
reinterpret_cast<char const*>(data.spirvBinary.data()), byteCount
|
||||
);
|
||||
file.write(
|
||||
reinterpret_cast<char const*>(data.spirvBinary.data()), byteCount
|
||||
);
|
||||
|
||||
file.close();
|
||||
file.close();
|
||||
|
||||
return newPath;
|
||||
}
|
||||
return newPath;
|
||||
}
|
||||
|
||||
SHShaderAsset const* SHShaderSourceCompiler::CompileShaderSourceToMemory(std::string const& data, std::string const& name, SH_SHADER_TYPE type) noexcept
|
||||
{
|
||||
// shaderc compiler
|
||||
shaderc::Compiler compiler;
|
||||
shaderc::CompileOptions options;
|
||||
SHShaderAsset const* SHShaderSourceCompiler::CompileShaderSourceToMemory(std::string const& data, std::string const& name, SH_SHADER_TYPE type) noexcept
|
||||
{
|
||||
// shaderc compiler
|
||||
shaderc::Compiler compiler;
|
||||
shaderc::CompileOptions options;
|
||||
|
||||
options.AddMacroDefinition("MY_DEFINE", "1");
|
||||
options.AddMacroDefinition("MY_DEFINE", "1");
|
||||
|
||||
//TODO: Check if we need optimisation levels when compiling into spirv
|
||||
// Set optimization levels
|
||||
//if (opLevel != shaderc_optimization_level_zero)
|
||||
// options.SetOptimizationLevel(opLevel);
|
||||
//TODO: Check if we need optimisation levels when compiling into spirv
|
||||
// Set optimization levels
|
||||
//if (opLevel != shaderc_optimization_level_zero)
|
||||
// options.SetOptimizationLevel(opLevel);
|
||||
|
||||
// Attempt to get the shaderc equivalent shader stage
|
||||
shaderc_shader_kind shaderKind;
|
||||
switch (type)
|
||||
{
|
||||
case SH_SHADER_TYPE::VERTEX:
|
||||
shaderKind = shaderc_shader_kind::shaderc_glsl_vertex_shader;
|
||||
break;
|
||||
case SH_SHADER_TYPE::FRAGMENT:
|
||||
shaderKind = shaderc_shader_kind::shaderc_glsl_fragment_shader;
|
||||
break;
|
||||
case SH_SHADER_TYPE::COMPUTE:
|
||||
shaderKind = shaderc_shader_kind::shaderc_glsl_compute_shader;
|
||||
break;
|
||||
default:
|
||||
shaderKind = shaderc_shader_kind::shaderc_glsl_vertex_shader;
|
||||
break;
|
||||
}
|
||||
// Attempt to get the shaderc equivalent shader stage
|
||||
shaderc_shader_kind shaderKind;
|
||||
switch (type)
|
||||
{
|
||||
case SH_SHADER_TYPE::VERTEX:
|
||||
shaderKind = shaderc_shader_kind::shaderc_glsl_vertex_shader;
|
||||
break;
|
||||
case SH_SHADER_TYPE::FRAGMENT:
|
||||
shaderKind = shaderc_shader_kind::shaderc_glsl_fragment_shader;
|
||||
break;
|
||||
case SH_SHADER_TYPE::COMPUTE:
|
||||
shaderKind = shaderc_shader_kind::shaderc_glsl_compute_shader;
|
||||
break;
|
||||
default:
|
||||
shaderKind = shaderc_shader_kind::shaderc_glsl_vertex_shader;
|
||||
break;
|
||||
}
|
||||
|
||||
// Compile the shader and get the result
|
||||
shaderc::SpvCompilationResult compileResult = compiler.CompileGlslToSpv(data, shaderKind, name.c_str(), options);
|
||||
// Compile the shader and get the result
|
||||
shaderc::SpvCompilationResult compileResult = compiler.CompileGlslToSpv(data, shaderKind, name.c_str(), options);
|
||||
|
||||
if (compileResult.GetCompilationStatus() != shaderc_compilation_status_success)
|
||||
{
|
||||
SHLOG_ERROR("Shaderc failed to compile GLSL shader to binary | " + compileResult.GetErrorMessage());
|
||||
return nullptr;
|
||||
}
|
||||
if (compileResult.GetCompilationStatus() != shaderc_compilation_status_success)
|
||||
{
|
||||
SHLOG_ERROR("Shaderc failed to compile GLSL shader to binary | " + compileResult.GetErrorMessage());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto result = new SHShaderAsset();
|
||||
result->spirvBinary.resize(compileResult.end() - compileResult.begin());
|
||||
auto result = new SHShaderAsset();
|
||||
result->spirvBinary.resize(compileResult.end() - compileResult.begin());
|
||||
|
||||
std::ranges::copy(compileResult.begin(), compileResult.end(), result->spirvBinary.data());
|
||||
std::ranges::copy(compileResult.begin(), compileResult.end(), result->spirvBinary.data());
|
||||
|
||||
result->name = name;
|
||||
result->shaderType = type;
|
||||
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
SH_SHADER_TYPE SHShaderSourceCompiler::GetShaderTypeFromFilename(std::string name) noexcept
|
||||
{
|
||||
for (auto i { 0}; i < SHADER_TYPE_MAX_COUNT; ++i)
|
||||
{
|
||||
if (name.find(SHADER_IDENTIFIERS[i].data()) != std::string::npos)
|
||||
{
|
||||
return static_cast<SH_SHADER_TYPE>(i);
|
||||
}
|
||||
}
|
||||
SH_SHADER_TYPE SHShaderSourceCompiler::GetShaderTypeFromFilename(std::string name) noexcept
|
||||
{
|
||||
for (auto i { 0 }; i < SHADER_TYPE_MAX_COUNT; ++i)
|
||||
{
|
||||
const auto& [SHADER_SUFFIX, SHADER_TYPE] = SHADER_IDENTIFIERS[i];
|
||||
if (name.find(SHADER_SUFFIX.data()) != std::string::npos)
|
||||
{
|
||||
return SHADER_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
return SH_SHADER_TYPE::INAVLID_TYPE;
|
||||
}
|
||||
return SH_SHADER_TYPE::INAVLID_TYPE;
|
||||
}
|
||||
|
||||
std::optional<AssetPath> SHShaderSourceCompiler::LoadAndCompileShader(AssetPath path) noexcept
|
||||
{
|
||||
auto type = GetShaderTypeFromFilename(path.filename().string());
|
||||
{
|
||||
auto type = GetShaderTypeFromFilename(path.filename().string());
|
||||
|
||||
if (type == SH_SHADER_TYPE::INAVLID_TYPE)
|
||||
{
|
||||
SHLOG_ERROR("Invalid filename for shaders, follow suffix in SHAssetMacros.h: {}", path.string());
|
||||
return {};
|
||||
}
|
||||
if (type == SH_SHADER_TYPE::INAVLID_TYPE)
|
||||
{
|
||||
SHLOG_ERROR("Invalid filename for shaders, follow suffix in SHAssetMacros.h: {}", path.string());
|
||||
return {};
|
||||
}
|
||||
|
||||
path.make_preferred();
|
||||
|
||||
std::ifstream file{ path.string(), std::ios::in };
|
||||
std::ifstream file{ path.string(), std::ios::in };
|
||||
|
||||
if (file.is_open())
|
||||
{
|
||||
std::stringstream stream;
|
||||
if (file.is_open())
|
||||
{
|
||||
std::stringstream stream;
|
||||
|
||||
stream << file.rdbuf();
|
||||
stream << file.rdbuf();
|
||||
|
||||
std::string const content = stream.str();
|
||||
std::string const content = stream.str();
|
||||
|
||||
auto data = CompileShaderSourceToMemory(content, path.filename().string(), type);
|
||||
auto data = CompileShaderSourceToMemory(content, path.filename().string(), type);
|
||||
|
||||
if (data == nullptr)
|
||||
{
|
||||
return{};
|
||||
}
|
||||
if (data == nullptr)
|
||||
{
|
||||
return{};
|
||||
}
|
||||
|
||||
return CompileShaderSourceToBinary(path, *data);
|
||||
}
|
||||
return CompileShaderSourceToBinary(path, *data);
|
||||
}
|
||||
|
||||
SHLOG_ERROR("Unable to open shader file: {}", path.string());
|
||||
SHLOG_ERROR("Unable to open shader file: {}", path.string());
|
||||
|
||||
return {};
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::optional<AssetPath> SHShaderSourceCompiler::CompileShaderFromString
|
||||
(std::string const& string, AssetPath path, SH_SHADER_TYPE type) noexcept
|
||||
{
|
||||
auto const data = CompileShaderSourceToMemory(string, path.filename().string(), type);
|
||||
std::optional<AssetPath> SHShaderSourceCompiler::CompileShaderFromString
|
||||
(std::string const& string, AssetPath path, SH_SHADER_TYPE type) noexcept
|
||||
{
|
||||
auto const data = CompileShaderSourceToMemory(string, path.filename().string(), type);
|
||||
|
||||
if (data == nullptr)
|
||||
{
|
||||
return{};
|
||||
}
|
||||
if (data == nullptr)
|
||||
{
|
||||
return{};
|
||||
}
|
||||
|
||||
return CompileShaderSourceToBinary(path, *data);
|
||||
}
|
||||
return CompileShaderSourceToBinary(path, *data);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,10 @@
|
|||
#pragma once
|
||||
#include "SHAssetLoader.h"
|
||||
|
||||
#include "Assets/Asset Types/SHPrefabAsset.h"
|
||||
#include "Assets/Asset Types/SHSceneAsset.h"
|
||||
#include "Assets/Asset Types/SHMaterialAsset.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
struct SHTextBasedLoader : SHAssetLoader
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <filesystem>
|
||||
#include "Asset Types/SHShaderAsset.h"
|
||||
|
||||
// FMOD Fwd Declare
|
||||
namespace FMOD
|
||||
|
@ -113,10 +114,10 @@ constexpr std::string_view VERTEX_SHADER{ "_VS" };
|
|||
constexpr std::string_view FRAGMENT_SHADER{ "_FS" };
|
||||
constexpr std::string_view COMPUTER_SHADER{ "_CS" };
|
||||
|
||||
constexpr std::string_view SHADER_IDENTIFIERS[] = {
|
||||
VERTEX_SHADER,
|
||||
FRAGMENT_SHADER,
|
||||
COMPUTER_SHADER
|
||||
constexpr std::pair<std::string_view, SHADE::SH_SHADER_TYPE> SHADER_IDENTIFIERS[] = {
|
||||
std::make_pair(VERTEX_SHADER, SHADE::SH_SHADER_TYPE::VERTEX),
|
||||
std::make_pair(FRAGMENT_SHADER, SHADE::SH_SHADER_TYPE::FRAGMENT),
|
||||
std::make_pair(COMPUTER_SHADER, SHADE::SH_SHADER_TYPE::COMPUTE)
|
||||
};
|
||||
|
||||
constexpr size_t SHADER_TYPE_MAX_COUNT{ 3 };
|
||||
|
|
|
@ -151,19 +151,23 @@ namespace SHADE
|
|||
****************************************************************************/
|
||||
AssetID SHAssetManager::CreateNewAsset(AssetType type, AssetName name) noexcept
|
||||
{
|
||||
SHAssetData* data = nullptr;
|
||||
std::string newPath{ ASSET_ROOT };
|
||||
switch (type)
|
||||
{
|
||||
case AssetType::PREFAB:
|
||||
newPath += PREFAB_FOLDER;
|
||||
data = new SHPrefabAsset();
|
||||
break;
|
||||
|
||||
case AssetType::SCENE:
|
||||
newPath += SCENE_FOLDER;
|
||||
data = new SHSceneAsset();
|
||||
break;
|
||||
|
||||
case AssetType::MATERIAL:
|
||||
newPath += MATERIAL_FOLDER;
|
||||
data = new SHMaterialAsset();
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -189,6 +193,8 @@ namespace SHADE
|
|||
)
|
||||
});
|
||||
|
||||
assetData.emplace(id, data);
|
||||
|
||||
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)
|
||||
, perspProj(true), dirtyView(true), dirtyProj(true)
|
||||
, viewMatrix(), projMatrix()
|
||||
, position()
|
||||
, position(), offset()
|
||||
{
|
||||
ComponentFamily::GetID<SHCameraComponent>();
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace SHADE
|
|||
SHVec3 position;
|
||||
|
||||
bool perspProj;
|
||||
|
||||
SHVec3 offset;
|
||||
|
||||
|
||||
|
||||
|
@ -41,7 +41,7 @@ namespace SHADE
|
|||
friend class SHCameraSystem;
|
||||
|
||||
SHCameraComponent();
|
||||
~SHCameraComponent();
|
||||
virtual ~SHCameraComponent();
|
||||
|
||||
|
||||
//Getters and setters.
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "SHpch.h"
|
||||
#include "SHCameraDirector.h"
|
||||
#include "SHCameraComponent.h"
|
||||
#include "SHCameraArmComponent.h"
|
||||
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||
#include "ECS_Base/SHECSMacros.h"
|
||||
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||
|
@ -48,6 +49,7 @@ namespace SHADE
|
|||
viewMatrix = camComponent->GetViewMatrix();
|
||||
projMatrix = camComponent->GetProjMatrix();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SHCameraDirector::SetMainCamera(SHCameraComponent& camera) noexcept
|
||||
|
|
|
@ -21,6 +21,7 @@ namespace SHADE
|
|||
|
||||
EntityID mainCameraEID;
|
||||
EntityID transitionCameraEID;
|
||||
|
||||
|
||||
SHMatrix GetViewMatrix() const noexcept;
|
||||
SHMatrix GetProjMatrix() const noexcept;
|
||||
|
@ -35,7 +36,7 @@ namespace SHADE
|
|||
protected:
|
||||
SHMatrix viewMatrix;
|
||||
SHMatrix projMatrix;
|
||||
|
||||
|
||||
};
|
||||
|
||||
typedef Handle<SHCameraDirector> DirectorHandle;
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
#include "SHpch.h"
|
||||
#include "SHCameraSystem.h"
|
||||
#include "SHCameraArmComponent.h"
|
||||
#include "Math/SHMathHelpers.h"
|
||||
#include "Input/SHInputManager.h"
|
||||
#include "Math/Vector/SHVec2.h"
|
||||
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||
#include "Math/Transform/SHTransformComponent.h"
|
||||
#include <math.h>
|
||||
|
||||
|
||||
namespace SHADE
|
||||
|
@ -59,6 +61,7 @@ namespace SHADE
|
|||
}
|
||||
|
||||
UpdateCameraComponent(editorCamera);
|
||||
|
||||
}
|
||||
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;
|
||||
system->UpdateCameraComponent(system->editorCamera);
|
||||
|
||||
system->DecomposeViewMatrix(camera.viewMatrix, camera.pitch, camera.yaw, camera.roll, camera.position);
|
||||
}
|
||||
|
||||
void SHCameraSystem::Init(void)
|
||||
|
@ -121,6 +126,9 @@ namespace SHADE
|
|||
editorCamera.SetYaw(0.0f);
|
||||
editorCamera.SetRoll(0.0f);
|
||||
editorCamera.movementSpeed = 2.0f;
|
||||
|
||||
SHComponentManager::CreateComponentSparseSet<SHCameraComponent>();
|
||||
SHComponentManager::CreateComponentSparseSet<SHCameraArmComponent>();
|
||||
|
||||
}
|
||||
|
||||
|
@ -134,6 +142,26 @@ namespace SHADE
|
|||
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
|
||||
{
|
||||
if (SHComponentManager::HasComponent<SHTransformComponent>(camera.GetEID()) == true && &camera != &editorCamera)
|
||||
|
@ -151,6 +179,15 @@ namespace SHADE
|
|||
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;
|
||||
|
||||
|
||||
|
@ -171,9 +208,12 @@ namespace SHADE
|
|||
camera.viewMatrix(2, 1) = view[1];
|
||||
camera.viewMatrix(2, 2) = view[2];
|
||||
|
||||
camera.viewMatrix(0, 3) = -right.Dot(camera.position);
|
||||
camera.viewMatrix(1, 3) = -UP.Dot(camera.position);
|
||||
camera.viewMatrix(2, 3) = -view.Dot(camera.position);
|
||||
camera.viewMatrix(0, 3) = -right.Dot(camera.position + camera.offset);
|
||||
camera.viewMatrix(1, 3) = -UP.Dot(camera.position + camera.offset);
|
||||
camera.viewMatrix(2, 3) = -view.Dot(camera.position + camera.offset);
|
||||
|
||||
|
||||
|
||||
|
||||
camera.dirtyView = false;
|
||||
}
|
||||
|
@ -221,6 +261,8 @@ namespace SHADE
|
|||
SHVec3 up = { 0.0f,1.0f,0.0f };
|
||||
|
||||
|
||||
|
||||
|
||||
target = SHVec3::RotateX(target, SHMath::DegreesToRadians(camera.pitch));
|
||||
target = SHVec3::RotateY(target, SHMath::DegreesToRadians(camera.yaw));
|
||||
target += camera.position;
|
||||
|
@ -241,6 +283,13 @@ namespace SHADE
|
|||
{
|
||||
SHCameraSystem* system = static_cast<SHCameraSystem*>(GetSystem());
|
||||
auto& dense = SHComponentManager::GetDense<SHCameraComponent>();
|
||||
auto& pivotDense = SHComponentManager::GetDense<SHCameraArmComponent>();
|
||||
|
||||
for (auto& pivot : pivotDense)
|
||||
{
|
||||
system->UpdatePivotArmComponent(pivot);
|
||||
}
|
||||
|
||||
for (auto& cam : dense)
|
||||
{
|
||||
system->UpdateCameraComponent(cam);
|
||||
|
@ -274,18 +323,115 @@ namespace SHADE
|
|||
}
|
||||
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)
|
||||
camera.SetPitch(85);
|
||||
if (camera.pitch < -85)
|
||||
camera.SetPitch(-85);
|
||||
if (camera.roll > 85)
|
||||
camera.SetRoll(85);
|
||||
if (camera.roll < -85)
|
||||
camera.SetRoll(-85);
|
||||
while (camera.yaw > 360)
|
||||
camera.yaw -= 360;
|
||||
while (camera.yaw < -360)
|
||||
camera.yaw += 360;
|
||||
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
class SHCameraArmComponent;
|
||||
|
||||
class SH_API SHCameraSystem final : public SHSystem
|
||||
{
|
||||
private:
|
||||
|
@ -19,6 +22,11 @@ namespace SHADE
|
|||
SHResourceLibrary<SHCameraDirector> directorLibrary;
|
||||
std::vector<DirectorHandle> directorHandleList;
|
||||
|
||||
|
||||
void UpdateCameraComponent(SHCameraComponent& camera) noexcept;
|
||||
void UpdatePivotArmComponent(SHCameraArmComponent& pivot) noexcept;
|
||||
|
||||
|
||||
public:
|
||||
SHCameraSystem(void) = default;
|
||||
virtual ~SHCameraSystem(void) = default;
|
||||
|
@ -39,7 +47,7 @@ namespace SHADE
|
|||
class SH_API CameraSystemUpdate final: public SHSystemRoutine
|
||||
{
|
||||
public:
|
||||
CameraSystemUpdate() : SHSystemRoutine("Camera System Update", false) {};
|
||||
CameraSystemUpdate() : SHSystemRoutine("Camera System Update", true) {};
|
||||
virtual void Execute(double dt)noexcept override final;
|
||||
};
|
||||
friend class CameraSystemUpdate;
|
||||
|
@ -51,12 +59,10 @@ namespace SHADE
|
|||
DirectorHandle GetDirector(size_t index) noexcept;
|
||||
void ClampCameraRotation(SHCameraComponent& camera) noexcept;
|
||||
void UpdateEditorCamera(double dt) noexcept;
|
||||
protected:
|
||||
|
||||
void UpdateCameraComponent(SHCameraComponent& camera) noexcept;
|
||||
|
||||
|
||||
|
||||
void SetMainCamera(EntityID eid, size_t directorIndex) noexcept;
|
||||
void DecomposeViewMatrix(SHMatrix const& matrix, float& pitch, float& yaw, float& roll, SHVec3& pos) noexcept;
|
||||
void SetCameraViewMatrix(SHCameraComponent& camera, SHMatrix const& viewMatrix) noexcept;
|
||||
void CameraLookAt(SHCameraComponent& camera, SHVec3 target) noexcept;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -251,7 +251,7 @@ namespace SHADE
|
|||
SHEditorWidgets::DragVec3
|
||||
(
|
||||
"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); });
|
||||
}
|
||||
else if (collider->GetType() == SHCollider::Type::SPHERE)
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "Physics/Components/SHRigidBodyComponent.h"
|
||||
#include "Physics/Components/SHColliderComponent.h"
|
||||
#include "Camera/SHCameraComponent.h"
|
||||
#include "Camera/SHCameraArmComponent.h"
|
||||
#include "SHEditorComponentView.h"
|
||||
|
||||
namespace SHADE
|
||||
|
@ -126,6 +127,9 @@ namespace SHADE
|
|||
if (auto cameraComponent = SHComponentManager::GetComponent_s<SHCameraComponent>(eid))
|
||||
{
|
||||
DrawComponent(cameraComponent);
|
||||
}if (auto cameraArmComponent = SHComponentManager::GetComponent_s<SHCameraArmComponent>(eid))
|
||||
{
|
||||
DrawComponent(cameraArmComponent);
|
||||
}
|
||||
ImGui::Separator();
|
||||
// Render Scripts
|
||||
|
@ -136,6 +140,7 @@ namespace SHADE
|
|||
{
|
||||
DrawAddComponentButton<SHTransformComponent>(eid);
|
||||
DrawAddComponentButton<SHCameraComponent>(eid);
|
||||
DrawAddComponentButton<SHCameraArmComponent>(eid);
|
||||
DrawAddComponentButton<SHLightComponent>(eid);
|
||||
|
||||
// Components that require Transforms
|
||||
|
|
|
@ -37,6 +37,8 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include "Assets/Asset Types/SHTextureAsset.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h"
|
||||
#include "Graphics/MiddleEnd/Lights/SHLightingSubSystem.h"
|
||||
#include "Assets/SHAssetManager.h"
|
||||
#include "Resource/SHResourceManager.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -109,9 +111,10 @@ namespace SHADE
|
|||
transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
||||
graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
||||
|
||||
|
||||
shaderModuleLibrary.ImportAllShaderSource(device);
|
||||
shaderModuleLibrary.ReflectAllShaderModules();
|
||||
// Load Built In Shaders
|
||||
static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEFAULT);
|
||||
static constexpr AssetID FS_DEFAULT = 46377769; defaultFragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(FS_DEFAULT);
|
||||
static constexpr AssetID CS_COMPOSITE = 45072428; deferredCompositeShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(CS_COMPOSITE);
|
||||
}
|
||||
|
||||
void SHGraphicsSystem::InitSceneRenderGraph(void) noexcept
|
||||
|
@ -180,16 +183,7 @@ namespace SHADE
|
|||
gBufferSubpass->AddColorOutput("Albedo");
|
||||
gBufferSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL);
|
||||
|
||||
//// kirsch
|
||||
//auto kirschShader = shaderModuleLibrary.GetShaderModule("KirschCs.glsl");
|
||||
//gBufferNode->AddNodeCompute(kirschShader, { "Position", "Scene" });
|
||||
|
||||
//// copy
|
||||
//auto pureCopyShader = shaderModuleLibrary.GetShaderModule("PureCopyCs.glsl");
|
||||
//gBufferNode->AddNodeCompute(pureCopyShader, { "Position", "Scene" });
|
||||
|
||||
// deferred composite
|
||||
auto deferredCompositeShader = shaderModuleLibrary.GetBuiltInShaderModule("DeferredComposite_CS");
|
||||
gBufferNode->AddNodeCompute(deferredCompositeShader, { "Position", "Normals", "Albedo", "Light Layer Indices", "Scene" });
|
||||
|
||||
|
||||
|
@ -207,10 +201,7 @@ namespace SHADE
|
|||
|
||||
worldRenderer->SetCameraDirector(cameraSystem->CreateDirector());
|
||||
|
||||
auto cubeVS = shaderModuleLibrary.GetBuiltInShaderModule("TestCube_VS");
|
||||
auto cubeFS = shaderModuleLibrary.GetBuiltInShaderModule("TestCube_FS");
|
||||
|
||||
defaultMaterial = AddMaterial(cubeVS, cubeFS, gBufferSubpass);
|
||||
defaultMaterial = AddMaterial(defaultVertShader, defaultFragShader, gBufferSubpass);
|
||||
}
|
||||
|
||||
void SHGraphicsSystem::InitMiddleEnd(void) noexcept
|
||||
|
|
|
@ -25,7 +25,6 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include "ECS_Base/System/SHSystemRoutine.h"
|
||||
#include "Graphics/Descriptors/SHVkDescriptorPool.h"
|
||||
#include "Graphics/RenderGraph/SHRenderGraph.h"
|
||||
#include "Graphics/MiddleEnd/Shaders/SHShaderModuleLibrary.h"
|
||||
#include "SHMeshLibrary.h"
|
||||
#include "Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.h"
|
||||
#include "../Textures/SHTextureLibrary.h"
|
||||
|
@ -329,6 +328,7 @@ namespace SHADE
|
|||
SHTextureLibrary texLibrary;
|
||||
SHSamplerCache samplerCache;
|
||||
SHMaterialInstanceCache materialInstanceCache;
|
||||
|
||||
// Viewports
|
||||
#ifdef SHEDITOR
|
||||
Handle<SHViewport> editorViewport;
|
||||
|
@ -349,10 +349,13 @@ namespace SHADE
|
|||
// Temp Cameras
|
||||
Handle<SHCamera> worldCamera;
|
||||
Handle<SHCamera> screenCamera;
|
||||
|
||||
SHShaderModuleLibrary shaderModuleLibrary;
|
||||
|
||||
// Temp Materials
|
||||
// Built-In Shaders
|
||||
Handle<SHVkShaderModule> defaultVertShader;
|
||||
Handle<SHVkShaderModule> defaultFragShader;
|
||||
Handle<SHVkShaderModule> deferredCompositeShader;
|
||||
|
||||
// Built-In Materials
|
||||
Handle<SHMaterial> defaultMaterial;
|
||||
|
||||
Handle<SHRenderGraph> worldRenderGraph;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
|
@ -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
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
// Project Headers
|
||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
#include "Math/SHMathHelpers.h"
|
||||
#include "Physics/SHPhysicsSystem.h"
|
||||
|
||||
namespace SHADE
|
||||
|
@ -28,21 +29,9 @@ namespace SHADE
|
|||
|
||||
SHRigidBodyComponent::SHRigidBodyComponent() noexcept
|
||||
: type { Type::DYNAMIC }
|
||||
, flags { 0 }
|
||||
, dirtyFlags { 0 }
|
||||
, interpolate { true }
|
||||
, 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 */
|
||||
|
@ -50,12 +39,24 @@ namespace SHADE
|
|||
|
||||
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
|
||||
{
|
||||
return flags & (1U << 1);
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return false;
|
||||
}
|
||||
|
||||
return rp3dBody->isAllowedToSleep();
|
||||
}
|
||||
|
||||
bool SHRigidBodyComponent::IsInterpolating() const noexcept
|
||||
|
@ -70,67 +71,151 @@ namespace SHADE
|
|||
|
||||
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
|
||||
{
|
||||
return drag;
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
return rp3dBody->getLinearDamping();
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
return flags & (1U << 7);
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& ANGULAR_CONSTRAINTS = rp3dBody->getAngularLockAxisFactor();
|
||||
return SHMath::CompareFloat(ANGULAR_CONSTRAINTS.z, 0.0f);
|
||||
}
|
||||
|
||||
const SHVec3& SHRigidBodyComponent::GetForce() const noexcept
|
||||
SHVec3 SHRigidBodyComponent::GetForce() const noexcept
|
||||
{
|
||||
return force;
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return false;
|
||||
}
|
||||
|
||||
return rp3dBody->getForce();
|
||||
}
|
||||
|
||||
const SHVec3& SHRigidBodyComponent::GetTorque() const noexcept
|
||||
SHVec3 SHRigidBodyComponent::GetTorque() const noexcept
|
||||
{
|
||||
return torque;
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return SHVec3::Zero;
|
||||
}
|
||||
|
||||
return rp3dBody->getTorque();
|
||||
}
|
||||
|
||||
const SHVec3& SHRigidBodyComponent::GetLinearVelocity() const noexcept
|
||||
SHVec3 SHRigidBodyComponent::GetLinearVelocity() const noexcept
|
||||
{
|
||||
return linearVelocity;
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return SHVec3::Zero;
|
||||
}
|
||||
|
||||
return rp3dBody->getLinearVelocity();
|
||||
}
|
||||
|
||||
const SHVec3& SHRigidBodyComponent::GetAngularVelocity() const noexcept
|
||||
SHVec3 SHRigidBodyComponent::GetAngularVelocity() const noexcept
|
||||
{
|
||||
return angularVelocity;
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return SHVec3::Zero;
|
||||
}
|
||||
|
||||
return rp3dBody->getAngularVelocity();
|
||||
}
|
||||
|
||||
const SHVec3& SHRigidBodyComponent::GetPosition() const noexcept
|
||||
|
@ -157,8 +242,15 @@ namespace SHADE
|
|||
if (type == newType)
|
||||
return;
|
||||
|
||||
dirtyFlags |= 1U << 4;
|
||||
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
|
||||
|
@ -171,8 +263,13 @@ namespace SHADE
|
|||
return;
|
||||
}
|
||||
|
||||
dirtyFlags |= 1U << FLAG_POS;
|
||||
enableGravity ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
rp3dBody->enableGravity(enableGravity);
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::SetIsAllowedToSleep(bool isAllowedToSleep) noexcept
|
||||
|
@ -185,92 +282,127 @@ namespace SHADE
|
|||
return;
|
||||
}
|
||||
|
||||
dirtyFlags |= 1U << 1;
|
||||
isAllowedToSleep ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
rp3dBody->setIsAllowedToSleep(isAllowedToSleep);
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::SetFreezePositionX(bool freezePositionX) noexcept
|
||||
{
|
||||
static constexpr int FLAG_POS = 2;
|
||||
|
||||
if (type == Type::STATIC)
|
||||
{
|
||||
SHLOG_WARNING("Cannot set linear constraints of a static object {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
dirtyFlags |= 1U << 2;
|
||||
freezePositionX ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
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
|
||||
{
|
||||
static constexpr int FLAG_POS = 3;
|
||||
|
||||
if (type == Type::STATIC)
|
||||
{
|
||||
SHLOG_WARNING("Cannot set linear constraints of a static object {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
dirtyFlags |= 1U << 2;
|
||||
freezePositionY ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
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
|
||||
{
|
||||
static constexpr int FLAG_POS = 4;
|
||||
|
||||
if (type == Type::STATIC)
|
||||
{
|
||||
SHLOG_WARNING("Cannot set linear constraints of a static object {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
dirtyFlags |= 1U << 2;
|
||||
freezePositionZ ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
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
|
||||
{
|
||||
static constexpr int FLAG_POS = 5;
|
||||
|
||||
if (type == Type::STATIC)
|
||||
{
|
||||
SHLOG_WARNING("Cannot set angular constraints of a static object {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
dirtyFlags |= 1U << 3;
|
||||
freezeRotationX ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
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
|
||||
{
|
||||
static constexpr int FLAG_POS = 6;
|
||||
|
||||
if (type == Type::STATIC)
|
||||
{
|
||||
SHLOG_WARNING("Cannot set angular constraints of a static object {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
dirtyFlags |= 1U << 3;
|
||||
freezeRotationY ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
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
|
||||
{
|
||||
static constexpr int FLAG_POS = 7;
|
||||
|
||||
if (type == Type::STATIC)
|
||||
{
|
||||
SHLOG_WARNING("Cannot set angular constraints of a static object {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
dirtyFlags |= 1U << 3;
|
||||
freezeRotationZ ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
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
|
||||
|
@ -283,11 +415,16 @@ namespace SHADE
|
|||
if (type != Type::DYNAMIC)
|
||||
{
|
||||
SHLOG_WARNING("Cannot set mass of a non-dynamic object {}", GetEID())
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
dirtyFlags |= 1U << 5;
|
||||
mass = newMass;
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
rp3dBody->setMass(newMass);
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::SetDrag(float newDrag) noexcept
|
||||
|
@ -298,8 +435,13 @@ namespace SHADE
|
|||
return;
|
||||
}
|
||||
|
||||
dirtyFlags |= 1U << 6;
|
||||
drag = newDrag;
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
rp3dBody->setLinearDamping(newDrag);
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::SetAngularDrag(float newAngularDrag) noexcept
|
||||
|
@ -310,8 +452,13 @@ namespace SHADE
|
|||
return;
|
||||
}
|
||||
|
||||
dirtyFlags |= 1U << 7;
|
||||
angularDrag = newAngularDrag;
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
rp3dBody->setLinearDamping(newAngularDrag);
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::SetLinearVelocity(const SHVec3& newLinearVelocity) noexcept
|
||||
|
@ -322,8 +469,13 @@ namespace SHADE
|
|||
return;
|
||||
}
|
||||
|
||||
dirtyFlags |= 1U << 8;
|
||||
linearVelocity = newLinearVelocity;
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
rp3dBody->setLinearVelocity(newLinearVelocity);
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::SetAngularVelocity(const SHVec3& newAngularVelocity) noexcept
|
||||
|
@ -334,8 +486,13 @@ namespace SHADE
|
|||
return;
|
||||
}
|
||||
|
||||
dirtyFlags |= 1U << 9;
|
||||
angularVelocity = newAngularVelocity;
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
rp3dBody->setAngularVelocity(newAngularVelocity);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -346,7 +503,7 @@ namespace SHADE
|
|||
{
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID())
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -357,7 +514,7 @@ namespace SHADE
|
|||
{
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID())
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -368,7 +525,7 @@ namespace SHADE
|
|||
{
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID())
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -379,7 +536,7 @@ namespace SHADE
|
|||
{
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID())
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -390,7 +547,7 @@ namespace SHADE
|
|||
{
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID())
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -401,7 +558,7 @@ namespace SHADE
|
|||
{
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID())
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -412,7 +569,7 @@ namespace SHADE
|
|||
{
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID())
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -423,7 +580,7 @@ namespace SHADE
|
|||
{
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID())
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -94,10 +94,10 @@ namespace SHADE
|
|||
[[nodiscard]] bool GetFreezeRotationY () const noexcept;
|
||||
[[nodiscard]] bool GetFreezeRotationZ () const noexcept;
|
||||
|
||||
[[nodiscard]] const SHVec3& GetForce () const noexcept;
|
||||
[[nodiscard]] const SHVec3& GetTorque () const noexcept;
|
||||
[[nodiscard]] const SHVec3& GetLinearVelocity () const noexcept;
|
||||
[[nodiscard]] const SHVec3& GetAngularVelocity () const noexcept;
|
||||
[[nodiscard]] SHVec3 GetForce () const noexcept;
|
||||
[[nodiscard]] SHVec3 GetTorque () const noexcept;
|
||||
[[nodiscard]] SHVec3 GetLinearVelocity () const noexcept;
|
||||
[[nodiscard]] SHVec3 GetAngularVelocity () const noexcept;
|
||||
|
||||
[[nodiscard]] const SHVec3& GetPosition () const noexcept;
|
||||
[[nodiscard]] const SHQuaternion& GetOrientation () const noexcept;
|
||||
|
@ -149,28 +149,13 @@ namespace SHADE
|
|||
static constexpr size_t NUM_FLAGS = 8;
|
||||
static constexpr size_t NUM_DIRTY_FLAGS = 16;
|
||||
|
||||
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;
|
||||
Type type;
|
||||
bool interpolate;
|
||||
|
||||
reactphysics3d::RigidBody* rp3dBody;
|
||||
|
||||
float mass;
|
||||
float drag;
|
||||
float angularDrag;
|
||||
|
||||
SHVec3 force;
|
||||
SHVec3 linearVelocity;
|
||||
|
||||
SHVec3 torque;
|
||||
SHVec3 angularVelocity;
|
||||
|
||||
SHVec3 position;
|
||||
SHQuaternion orientation;
|
||||
SHVec3 position;
|
||||
SHQuaternion orientation;
|
||||
|
||||
RTTR_ENABLE()
|
||||
};
|
||||
|
|
|
@ -168,100 +168,6 @@ namespace SHADE
|
|||
rp3dBody->removeCollider(collider);
|
||||
}
|
||||
|
||||
void SHPhysicsObject::SyncRigidBody(SHRigidBodyComponent* rb) const noexcept
|
||||
{
|
||||
SHASSERT(rp3dBody != nullptr, "ReactPhysics body does not exist!")
|
||||
|
||||
auto* rigidBody = reinterpret_cast<rp3d::RigidBody*>(rp3dBody);
|
||||
|
||||
// Sync velocities
|
||||
rb->linearVelocity = rigidBody->getLinearVelocity();
|
||||
rb->angularVelocity = rigidBody->getAngularVelocity();
|
||||
|
||||
if (rb->dirtyFlags == 0)
|
||||
return;
|
||||
|
||||
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
|
||||
{
|
||||
int index = 0;
|
||||
|
|
|
@ -72,7 +72,6 @@ namespace SHADE
|
|||
int AddCollider (SHCollider* collider);
|
||||
void RemoveCollider (int index);
|
||||
|
||||
void SyncRigidBody (SHRigidBodyComponent* rb) const noexcept;
|
||||
void SyncColliders (SHColliderComponent* c) const noexcept;
|
||||
|
||||
private:
|
||||
|
|
|
@ -19,8 +19,9 @@
|
|||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
#include "Editor/SHEditor.h"
|
||||
#include "Math/SHMathHelpers.h"
|
||||
#include "Scene/SHSceneManager.h"
|
||||
#include "Math/Transform/SHTransformComponent.h"
|
||||
#include "Scene/SHSceneManager.h"
|
||||
#include "Scripting/SHScriptEngine.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -257,7 +258,10 @@ namespace SHADE
|
|||
if (physicsObject.rp3dBody == nullptr)
|
||||
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())
|
||||
{
|
||||
const auto WORLD_POS = transformComponent->GetWorldPosition();
|
||||
|
@ -266,82 +270,110 @@ namespace SHADE
|
|||
physicsObject.SetPosition(WORLD_POS);
|
||||
physicsObject.SetOrientation(WORLD_ROT);
|
||||
|
||||
auto* rigidBodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(entityID);
|
||||
// Sync physics component transforms
|
||||
|
||||
if (rigidBodyComponent)
|
||||
{
|
||||
rigidBodyComponent->position = WORLD_POS;
|
||||
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);
|
||||
}
|
||||
|
||||
const bool COMPONENT_ACTIVE = rigidBodyComponent->isActive;
|
||||
system->SyncActiveStates(&physicsObject, COMPONENT_ACTIVE);
|
||||
|
||||
if (!COMPONENT_ACTIVE)
|
||||
continue;
|
||||
|
||||
physicsObject.SyncRigidBody(rigidBodyComponent);
|
||||
}
|
||||
|
||||
auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(entityID);
|
||||
if (colliderComponent)
|
||||
{
|
||||
colliderComponent->position = WORLD_POS;
|
||||
colliderComponent->orientation = WORLD_ROT;
|
||||
|
||||
const bool COMPONENT_ACTIVE = colliderComponent->isActive;
|
||||
system->SyncActiveStates(&physicsObject, COMPONENT_ACTIVE);
|
||||
|
||||
if (!COMPONENT_ACTIVE)
|
||||
continue;
|
||||
|
||||
physicsObject.SyncColliders(colliderComponent);
|
||||
}
|
||||
}
|
||||
|
||||
// Sync rigid bodies
|
||||
|
||||
if (rigidBodyComponent)
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
|
||||
// Sync active states
|
||||
const bool COMPONENT_ACTIVE = rigidBodyComponent->isActive;
|
||||
SyncActiveStates(physicsObject, COMPONENT_ACTIVE);
|
||||
|
||||
if (!COMPONENT_ACTIVE)
|
||||
continue;
|
||||
}
|
||||
|
||||
// Sync colliders
|
||||
|
||||
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
|
||||
{
|
||||
auto* system = reinterpret_cast<SHPhysicsSystem*>(GetSystem());
|
||||
fixedTimeStep = 1.0 / system->fixedDT;
|
||||
auto* physicsSystem = reinterpret_cast<SHPhysicsSystem*>(GetSystem());
|
||||
auto scriptSys = SHSystemManager::GetSystem<SHScriptEngine>();
|
||||
if (!scriptSys)
|
||||
{
|
||||
SHLOG_WARNING("[SHPhysicsSystem] Unable to invoke FixedUpdate() on scripts due to missing SHScriptEngine!");
|
||||
}
|
||||
|
||||
fixedTimeStep = 1.0 / physicsSystem->fixedDT;
|
||||
accumulatedTime += dt;
|
||||
|
||||
int count = 0;
|
||||
while (accumulatedTime > fixedTimeStep)
|
||||
{
|
||||
system->world->update(static_cast<rp3d::decimal>(fixedTimeStep));
|
||||
if (scriptSys)
|
||||
{
|
||||
scriptSys->ExecuteFixedUpdates();
|
||||
}
|
||||
physicsSystem->world->update(static_cast<rp3d::decimal>(fixedTimeStep));
|
||||
|
||||
accumulatedTime -= fixedTimeStep;
|
||||
++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
|
||||
{
|
||||
auto* system = reinterpret_cast<SHPhysicsSystem*>(GetSystem());
|
||||
auto* physicsSystem = reinterpret_cast<SHPhysicsSystem*>(GetSystem());
|
||||
|
||||
// Interpolate transforms for rendering
|
||||
if (system->worldUpdated)
|
||||
if (physicsSystem->worldUpdated)
|
||||
{
|
||||
system->SyncTransforms();
|
||||
physicsSystem->SyncTransforms();
|
||||
|
||||
// TODO(Kah Wei): Take Collision & Trigger messages here
|
||||
// Collision & Trigger messages
|
||||
auto scriptSys = SHSystemManager::GetSystem<SHScriptEngine>();
|
||||
if (scriptSys)
|
||||
{
|
||||
scriptSys->ExecuteCollisionFunctions();
|
||||
}
|
||||
else
|
||||
{
|
||||
SHLOG_WARNING("[SHPhysicsSystem] Unable to invoke collision and trigger script events due to missing SHScriptEngine!");
|
||||
}
|
||||
|
||||
system->ClearInvalidCollisions();
|
||||
physicsSystem->ClearInvalidCollisions();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -349,26 +381,10 @@ namespace SHADE
|
|||
{
|
||||
for (uint32_t i = 0; i < callbackData.getNbContactPairs(); ++i)
|
||||
{
|
||||
auto contactPair = callbackData.getContactPair(i);
|
||||
SHCollisionEvent newCollisionEvent = GenerateCollisionEvent(contactPair);
|
||||
const auto CONTACT_PAIR = callbackData.getContactPair(i);
|
||||
const SHCollisionEvent NEW_EVENT = GenerateCollisionEvent(CONTACT_PAIR);
|
||||
|
||||
// Find contact pair in container
|
||||
auto existingEvent = std::ranges::find_if(collisionInfo.begin(), collisionInfo.end(), [&](const SHCollisionEvent& e)
|
||||
{
|
||||
const bool ENTITY_MATCH = e.value[0] == newCollisionEvent.value[0];
|
||||
const bool COLLIDERS_MATCH = e.value[1] == newCollisionEvent.value[1];
|
||||
return ENTITY_MATCH && COLLIDERS_MATCH;
|
||||
});
|
||||
|
||||
if (existingEvent == collisionInfo.end())
|
||||
{
|
||||
// Add new event
|
||||
collisionInfo.emplace_back(newCollisionEvent);
|
||||
}
|
||||
else
|
||||
{
|
||||
existingEvent->collisionState = newCollisionEvent.collisionState;
|
||||
}
|
||||
UpdateEventContainers(NEW_EVENT, collisionInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -376,26 +392,10 @@ namespace SHADE
|
|||
{
|
||||
for (uint32_t i = 0; i < callbackData.getNbOverlappingPairs(); ++i)
|
||||
{
|
||||
auto contactPair = callbackData.getOverlappingPair(i);
|
||||
SHCollisionEvent newTriggerEvent = GenerateCollisionEvent(contactPair);
|
||||
const auto& OVERLAP_PAIR = callbackData.getOverlappingPair(i);
|
||||
const SHCollisionEvent NEW_EVENT = GenerateCollisionEvent(OVERLAP_PAIR);
|
||||
|
||||
// Find contact pair in container
|
||||
auto existingEvent = std::ranges::find_if(collisionInfo.begin(), collisionInfo.end(), [&](const SHCollisionEvent& e)
|
||||
{
|
||||
const bool ENTITY_MATCH = e.value[0] == newTriggerEvent.value[0];
|
||||
const bool COLLIDERS_MATCH = e.value[1] == newTriggerEvent.value[1];
|
||||
return ENTITY_MATCH && COLLIDERS_MATCH;
|
||||
});
|
||||
|
||||
if (existingEvent == collisionInfo.end())
|
||||
{
|
||||
// Add new event
|
||||
triggerInfo.emplace_back(newTriggerEvent);
|
||||
}
|
||||
else
|
||||
{
|
||||
existingEvent->collisionState = newTriggerEvent.collisionState;
|
||||
}
|
||||
UpdateEventContainers(NEW_EVENT, triggerInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -432,11 +432,11 @@ namespace SHADE
|
|||
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)
|
||||
physicsObject->rp3dBody->setIsActive(componentActive);
|
||||
physicsObject.rp3dBody->setIsActive(componentActive);
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::SyncTransforms() noexcept
|
||||
|
@ -491,155 +491,54 @@ namespace SHADE
|
|||
}
|
||||
|
||||
// Convert RP3D Transform to SHADE
|
||||
auto* transformComponent = SHComponentManager::GetComponent<SHTransformComponent>(entityID);
|
||||
transformComponent->SetWorldPosition(rp3dPos);
|
||||
transformComponent->SetWorldOrientation(rp3dRot);
|
||||
auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
|
||||
|
||||
if (transformComponent != nullptr)
|
||||
{
|
||||
transformComponent->SetWorldPosition(rp3dPos);
|
||||
transformComponent->SetWorldOrientation(rp3dRot);
|
||||
}
|
||||
|
||||
// Cache transforms
|
||||
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
|
||||
{
|
||||
for (auto collisionInfoIter = collisionInfo.begin(); collisionInfoIter != collisionInfo.end();)
|
||||
static const auto CLEAR = [](CollisionEvents& container)
|
||||
{
|
||||
if (collisionInfoIter->GetCollisionState() == SHCollisionEvent::State::EXIT
|
||||
|| collisionInfoIter->GetCollisionState() == SHCollisionEvent::State::INVALID)
|
||||
for (auto eventIter = container.begin(); eventIter != container.end();)
|
||||
{
|
||||
collisionInfoIter = collisionInfo.erase(collisionInfoIter);
|
||||
}
|
||||
else
|
||||
{
|
||||
++collisionInfoIter;
|
||||
}
|
||||
}
|
||||
const bool CLEAR_EVENT = eventIter->GetCollisionState() == SHCollisionEvent::State::EXIT
|
||||
|| eventIter->GetCollisionState() == SHCollisionEvent::State::INVALID;
|
||||
|
||||
for (auto triggerInfoIter = triggerInfo.begin(); triggerInfoIter != triggerInfo.end();)
|
||||
{
|
||||
if (triggerInfoIter->GetCollisionState() == SHCollisionEvent::State::EXIT
|
||||
|| triggerInfoIter->GetCollisionState() == SHCollisionEvent::State::INVALID)
|
||||
{
|
||||
triggerInfoIter = triggerInfo.erase(triggerInfoIter);
|
||||
if (CLEAR_EVENT)
|
||||
eventIter = container.erase(eventIter);
|
||||
else
|
||||
++eventIter;
|
||||
}
|
||||
else
|
||||
{
|
||||
++triggerInfoIter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SHCollisionEvent SHPhysicsSystem::GenerateCollisionEvent(const rp3d::CollisionCallback::ContactPair& 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;
|
||||
CLEAR(collisionInfo);
|
||||
CLEAR(triggerInfo);
|
||||
}
|
||||
|
||||
SHCollisionEvent SHPhysicsSystem::GenerateCollisionEvent(const rp3d::OverlapCallback::OverlapPair& 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;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Update collision state
|
||||
cInfo.collisionState = static_cast<SHCollisionEvent::State>(cp.getEventType());
|
||||
|
||||
return cInfo;
|
||||
}
|
||||
|
||||
|
||||
SHEventHandle SHPhysicsSystem::AddPhysicsComponent(SHEventPtr addComponentEvent)
|
||||
{
|
||||
const auto& EVENT_DATA = reinterpret_cast<const SHEventSpec<SHComponentAddedEvent>*>(addComponentEvent.get());
|
||||
|
@ -728,14 +627,23 @@ namespace SHADE
|
|||
const EntityID ENTITY_ID = EVENT_DATA->data->eid;
|
||||
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);
|
||||
|
||||
SHASSERT(physicsObject != nullptr, "Physics object " + std::to_string(ENTITY_ID) + " has been lost from the world!")
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
world->destroyRigidBody(reinterpret_cast<rp3d::RigidBody*>(physicsObject->rp3dBody));
|
||||
physicsObject->rp3dBody = nullptr;
|
||||
|
||||
auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(ENTITY_ID);
|
||||
if (colliderComponent != nullptr)
|
||||
{
|
||||
// Preserve colliders as a collision body
|
||||
|
@ -747,13 +655,6 @@ namespace SHADE
|
|||
for (auto& collider : colliderComponent->colliders)
|
||||
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)
|
||||
|
@ -766,6 +667,10 @@ namespace SHADE
|
|||
auto* collider = physicsObject->rp3dBody->getCollider(i);
|
||||
physicsObject->rp3dBody->removeCollider(collider);
|
||||
}
|
||||
|
||||
// Check for a rigidbody component
|
||||
if (rigidBodyComponent == nullptr)
|
||||
physicsObject->rp3dBody = nullptr;
|
||||
}
|
||||
|
||||
if (physicsObject->rp3dBody == nullptr)
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
namespace SHADE
|
||||
{
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -176,22 +177,24 @@ namespace SHADE
|
|||
/* Function Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
SHPhysicsObject* EnsurePhysicsObject (EntityID entityID) noexcept;
|
||||
SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept;
|
||||
void DestroyPhysicsObject (EntityID entityID) noexcept;
|
||||
|
||||
void SyncActiveStates (SHPhysicsObject* physicsObject, bool componentActive) noexcept;
|
||||
static void SyncActiveStates (SHPhysicsObject& physicsObject, bool componentActive) noexcept;
|
||||
void SyncTransforms () noexcept;
|
||||
void ClearInvalidCollisions () noexcept;
|
||||
|
||||
SHCollisionEvent GenerateCollisionEvent (const rp3d::CollisionCallback::ContactPair& cp) noexcept;
|
||||
SHCollisionEvent GenerateCollisionEvent (const rp3d::OverlapCallback::OverlapPair& cp) noexcept;
|
||||
static void UpdateEventContainers (const SHCollisionEvent& collisionEvent, CollisionEvents& container) noexcept;
|
||||
void ClearInvalidCollisions () noexcept;
|
||||
|
||||
SHEventHandle AddPhysicsComponent (SHEventPtr addComponentEvent);
|
||||
SHEventHandle RemovePhysicsComponent (SHEventPtr removeComponentEvent);
|
||||
|
||||
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;
|
||||
};
|
||||
} // 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;
|
||||
};
|
||||
}
|
|
@ -17,9 +17,45 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include "SH_API.h"
|
||||
#include "SHResourceLibrary.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
|
||||
{
|
||||
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>
|
||||
/// Static class responsible for loading and caching runtime resources from their
|
||||
/// serialised Asset IDs.
|
||||
|
@ -124,6 +160,14 @@ namespace SHADE
|
|||
/// <returns>Reference to the AssetHandleMap of the specified type.</returns>
|
||||
template<typename ResourceType>
|
||||
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);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Oct 21, 2022
|
||||
\brief Contains the definition of the function templates of the
|
||||
\brief Contains the definition of the function templates of the
|
||||
SHResourceManager static class.
|
||||
|
||||
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||
|
@ -13,12 +13,17 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#pragma once
|
||||
// Primary Include
|
||||
#include "SHResourceManager.h"
|
||||
// External Dependencies
|
||||
#include <yaml-cpp/yaml.h>
|
||||
// Project Includes
|
||||
#include "Assets/SHAssetManager.h"
|
||||
#include "Assets/Asset Types/SHAssetIncludes.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
#include "Tools/SHLog.h"
|
||||
#include "Graphics/Shaders/SHVkShaderModule.h"
|
||||
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -40,67 +45,19 @@ namespace SHADE
|
|||
return Handle<ResourceType>(typedHandleMap.get()[assetId]);
|
||||
|
||||
/* Otherwise, we need to load it! */
|
||||
// Meshes
|
||||
if constexpr (std::is_same_v<ResourceType, SHMesh>)
|
||||
// Load Asset Data
|
||||
const auto* assetData = SHAssetManager::GetData<SHResourceLoader<ResourceType>::AssetType>(assetId);
|
||||
if (assetData == nullptr)
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
SHLog::Warning("[SHResourceManager] Attempted to load an asset with an invalid Asset ID.");
|
||||
return {};
|
||||
}
|
||||
loadedAssetData.emplace_back(assetId);
|
||||
|
||||
Handle<SHMesh> meshHandle = gfxSystem->AddMesh
|
||||
(
|
||||
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);
|
||||
typedAssetIdMap.get().emplace(genericHandle, assetId);
|
||||
return meshHandle;
|
||||
SHLog::Warning("[SHResourceManager] Attempted to load an asset with an invalid Asset ID.");
|
||||
return {};
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
auto handle = load<ResourceType>(assetId, *assetData);
|
||||
Handle genericHandle = Handle();
|
||||
typedHandleMap.get().emplace(assetId, genericHandle);
|
||||
typedAssetIdMap.get().emplace(genericHandle, assetId);
|
||||
return handle;
|
||||
}
|
||||
|
||||
template<typename ResourceType>
|
||||
|
@ -152,7 +109,7 @@ namespace SHADE
|
|||
template<typename ResourceType>
|
||||
std::pair<SHResourceManager::AssetHandleMapRef, SHResourceManager::HandleAssetMapRef> SHResourceManager::getAssetHandleMap()
|
||||
{
|
||||
const std::type_index TYPE = typeid(ResourceType);
|
||||
const std::type_index TYPE = typeid(ResourceType);
|
||||
|
||||
if (!handlesMap.contains(TYPE))
|
||||
{
|
||||
|
@ -160,7 +117,7 @@ namespace SHADE
|
|||
assetIdMap.emplace(TYPE, HandleAssetMap{});
|
||||
typedFreeFuncMap.emplace
|
||||
(
|
||||
TYPE,
|
||||
TYPE,
|
||||
[TYPE](AssetID assetId)
|
||||
{
|
||||
static_cast<Handle<ResourceType>>(SHResourceManager::handlesMap[TYPE][assetId]).Free();
|
||||
|
@ -169,4 +126,129 @@ namespace SHADE
|
|||
}
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
void SHScriptEngine::ExecuteCollisionFunctions()
|
||||
{
|
||||
csScriptsExecutePhysicsEvents();
|
||||
}
|
||||
void SHScriptEngine::Exit()
|
||||
{
|
||||
// Do not allow deinitialization if not initialised
|
||||
|
@ -377,6 +380,12 @@ namespace SHADE
|
|||
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
||||
"ExecuteLateUpdate"
|
||||
);
|
||||
csScriptsExecutePhysicsEvents = dotNet.GetFunctionPtr<CsFuncPtr>
|
||||
(
|
||||
DEFAULT_CSHARP_LIB_NAME,
|
||||
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
||||
"ExecuteCollisionFunctions"
|
||||
);
|
||||
csScriptsFrameCleanUp = dotNet.GetFunctionPtr<CsFuncPtr>
|
||||
(
|
||||
DEFAULT_CSHARP_LIB_NAME,
|
||||
|
|
|
@ -98,6 +98,11 @@ namespace SHADE
|
|||
/// </summary>
|
||||
void ExecuteFixedUpdates();
|
||||
/// <summary>
|
||||
/// Executes the OnCollision*()s and OnTrigger*()s of the Scripts that are attached
|
||||
/// to Entities.
|
||||
/// </summary>
|
||||
void ExecuteCollisionFunctions();
|
||||
/// <summary>
|
||||
/// Shuts down the DotNetRuntime.
|
||||
/// </summary>
|
||||
void Exit() override;
|
||||
|
@ -245,6 +250,7 @@ namespace SHADE
|
|||
CsFuncPtr csScriptsExecuteFixedUpdate = nullptr;
|
||||
CsFuncPtr csScriptsExecuteUpdate = nullptr;
|
||||
CsFuncPtr csScriptsExecuteLateUpdate = nullptr;
|
||||
CsFuncPtr csScriptsExecutePhysicsEvents = nullptr;
|
||||
CsFuncPtr csScriptsFrameCleanUp = nullptr;
|
||||
CsScriptManipFuncPtr csScriptsAdd = nullptr;
|
||||
CsScriptBasicFuncPtr csScriptsRemoveAll = nullptr;
|
||||
|
|
|
@ -12,8 +12,11 @@
|
|||
#include "Resource/SHResourceManager.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHMaterial.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
|
||||
#include "SHSerializationTools.h"
|
||||
#include "Physics/Components/SHColliderComponent.h"
|
||||
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
||||
#include "Tools/SHLog.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
|
@ -303,104 +306,45 @@ namespace YAML
|
|||
// Write Material
|
||||
YAML::Node node;
|
||||
|
||||
node[VERT_SHADER_YAML_TAG.data()] = 0; // SHResourceManager::GetAssetID<SHVkShaderModule>(vertexShader).value_or(0);
|
||||
node[FRAG_SHADER_YAML_TAG.data()] = 0; // SHResourceManager::GetAssetID<SHVkShaderModule>(fragShader).value_or(0);
|
||||
node[SUBPASS_YAML_TAG.data()] = rhs.GetPipeline()->GetPipelineState().GetSubpass()->GetName();
|
||||
node[VERT_SHADER_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHVkShaderModule>(vertexShader).value_or(0);
|
||||
node[FRAG_SHADER_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHVkShaderModule>(fragShader).value_or(0);
|
||||
node[SUBPASS_YAML_TAG.data()] = rhs.GetPipeline()->GetPipelineState().GetSubpass()->GetName();
|
||||
node[PROPS_YAML_TAG.data()] = propertiesNode;
|
||||
|
||||
return node;
|
||||
}
|
||||
static bool decode(YAML::Node const& node, SHMaterial& rhs)
|
||||
{
|
||||
/*
|
||||
// Retrieve Shader Asset IDs
|
||||
AssetID vertShaderId = 0;
|
||||
AssetID fragShaderId = 0;
|
||||
if (node[VERT_SHADER_YAML_TAG.data()])
|
||||
vertShaderId = node[VERT_SHADER_YAML_TAG.data()].as<AssetID>();
|
||||
if (node[FRAG_SHADER_YAML_TAG.data()])
|
||||
fragShaderId = node[FRAG_SHADER_YAML_TAG.data()].as<AssetID>();
|
||||
};
|
||||
|
||||
// Ensure that both shaders are present
|
||||
if (vertShaderId == 0 || fragShaderId == 0)
|
||||
return false; // No pipeline
|
||||
template<>
|
||||
struct convert<SHMaterialSpec>
|
||||
{
|
||||
static constexpr std::string_view VERT_SHADER_YAML_TAG = "VertexShader";
|
||||
static constexpr std::string_view FRAG_SHADER_YAML_TAG = "FragmentShader";
|
||||
static constexpr std::string_view SUBPASS_YAML_TAG = "SubPass";
|
||||
static constexpr std::string_view PROPS_YAML_TAG = "Properties";
|
||||
|
||||
// Get Shader Modules
|
||||
Handle<SHVkShaderModule> vertexShader, fragShader;
|
||||
vertexShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(vertShaderId);
|
||||
fragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(fragShaderId);
|
||||
static bool decode(YAML::Node const& node, SHMaterialSpec& rhs)
|
||||
{
|
||||
// Retrieve Shader Asset IDs
|
||||
if (!node[VERT_SHADER_YAML_TAG.data()])
|
||||
return false;
|
||||
rhs.vertexShader = node[VERT_SHADER_YAML_TAG.data()].as<AssetID>();
|
||||
if (!node[FRAG_SHADER_YAML_TAG.data()])
|
||||
return false;
|
||||
rhs.fragShader = node[FRAG_SHADER_YAML_TAG.data()].as<AssetID>();
|
||||
|
||||
// Get Pipeline Library
|
||||
if (node[SUBPASS_YAML_TAG.data()])
|
||||
{
|
||||
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||
if (!gfxSystem)
|
||||
return false;
|
||||
// Retrieve Subpass
|
||||
if (!node[SUBPASS_YAML_TAG.data()])
|
||||
return false;
|
||||
rhs.subpassName = node[SUBPASS_YAML_TAG.data()].as<std::string>();
|
||||
|
||||
// Grab subpass from worldRenderer
|
||||
auto renderPass = gfxSystem->GetPrimaryRenderpass();
|
||||
if (!renderPass)
|
||||
return false;
|
||||
auto subPass = renderPass->GetSubpass(node[SUBPASS_YAML_TAG.data()].as<std::string>());
|
||||
if (!subPass)
|
||||
return false;
|
||||
// Retrieve
|
||||
if (!node[PROPS_YAML_TAG.data()])
|
||||
return false;
|
||||
rhs.properties = node[PROPS_YAML_TAG.data()];
|
||||
|
||||
// Set Pipeline
|
||||
rhs.SetPipeline(renderPass->GetOrCreatePipeline
|
||||
(
|
||||
std::make_pair(vertexShader, fragShader),
|
||||
subPass
|
||||
));
|
||||
}
|
||||
*/
|
||||
|
||||
// TODO: Load Proper Material!
|
||||
// Set default material
|
||||
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||
if (!gfxSystem)
|
||||
return false;
|
||||
rhs.SetPipeline(gfxSystem->GetDefaultMaterial()->GetPipeline());
|
||||
|
||||
if (node[PROPS_YAML_TAG.data()].IsDefined())
|
||||
{
|
||||
// Loop through all properties
|
||||
Handle<SHShaderBlockInterface> pipelineProperties = rhs.GetShaderBlockInterface();
|
||||
const YAML::Node& PROPS_NODE = node[PROPS_YAML_TAG.data()];
|
||||
for (int i = 0; i < static_cast<int>(pipelineProperties->GetVariableCount()); ++i)
|
||||
{
|
||||
const std::string& PROP_NAME = pipelineProperties->GetVariableName(i);
|
||||
const auto& PROP_NODE = PROPS_NODE[PROP_NAME.data()];
|
||||
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:
|
||||
rhs.SetProperty(VARIABLE->offset, PROP_NODE.as<float>());
|
||||
break;
|
||||
case SHADE::SHShaderBlockInterface::Variable::Type::INT:
|
||||
rhs.SetProperty(VARIABLE->offset, PROP_NODE.as<int>());
|
||||
break;
|
||||
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR2:
|
||||
rhs.SetProperty(VARIABLE->offset, SHSerializationTools::YAMLToVec2(PROP_NODE));
|
||||
break;
|
||||
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR3:
|
||||
rhs.SetProperty(VARIABLE->offset, SHSerializationTools::YAMLToVec3(PROP_NODE));
|
||||
break;
|
||||
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR4:
|
||||
rhs.SetProperty(VARIABLE->offset, SHSerializationTools::YAMLToVec4(PROP_NODE));
|
||||
break;
|
||||
case SHADE::SHShaderBlockInterface::Variable::Type::OTHER:
|
||||
default:
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
|
@ -413,7 +357,7 @@ namespace YAML
|
|||
{
|
||||
YAML::Node node;
|
||||
node[MESH_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHMesh>(rhs.GetMesh()).value_or(0);
|
||||
node[MAT_YAML_TAG.data()] = 0; // TODO: Asset ID
|
||||
node[MAT_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHMaterial>(rhs.GetMaterial()->GetBaseMaterial()).value_or(0);
|
||||
return node;
|
||||
}
|
||||
static bool decode(YAML::Node const& node, SHRenderable& rhs)
|
||||
|
@ -424,12 +368,17 @@ namespace YAML
|
|||
}
|
||||
if (node[MAT_YAML_TAG.data()].IsDefined())
|
||||
{
|
||||
// TODO: Convert Asset ID To Material HAndle
|
||||
// Temporarily, use default material
|
||||
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||
if (!gfxSystem)
|
||||
return false;
|
||||
rhs.SetMaterial(gfxSystem->AddOrGetBaseMaterialInstance(gfxSystem->GetDefaultMaterial()));
|
||||
Handle<SHMaterial> baseMat = SHResourceManager::LoadOrGet<SHMaterial>(node[MAT_YAML_TAG.data()].as<AssetID>());
|
||||
if (!baseMat)
|
||||
{
|
||||
baseMat = gfxSystem->GetDefaultMaterial();
|
||||
SHLog::Warning("[SHSerializationHelper] Unable to load specified material. Falling back to default material.");
|
||||
}
|
||||
rhs.SetMaterial(gfxSystem->AddOrGetBaseMaterialInstance(baseMat));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,9 @@ of DigiPen Institute of Technology is prohibited.
|
|||
*//*************************************************************************************/
|
||||
// Precompiled Headers
|
||||
#include "SHpch.h"
|
||||
// External Dependencies
|
||||
#include "FRC/SHFramerateController.h"
|
||||
#include "Physics/SHPhysicsSystemInterface.h"
|
||||
// Primary Header
|
||||
#include "Time.hxx"
|
||||
|
||||
|
@ -26,4 +29,8 @@ namespace SHADE
|
|||
{
|
||||
return SHFrameRateController::GetRawDeltaTime();
|
||||
}
|
||||
double Time::FixedDeltaTime::get()
|
||||
{
|
||||
return SHPhysicsSystemInterface::GetFixedDT();
|
||||
}
|
||||
}
|
|
@ -14,8 +14,6 @@ of DigiPen Institute of Technology is prohibited.
|
|||
*//*************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include "FRC/SHFramerateController.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -29,13 +27,18 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Time taken to process the previous frame.
|
||||
/// Note, is affected by TimeScale. Use UnscaledDeltaTime if you wish to retrieve
|
||||
/// real world time. This is also affected by MaxDeltaTime clamping that
|
||||
/// UnscaledDeltaTime is subject to.
|
||||
/// </summary>
|
||||
static property double DeltaTime
|
||||
{
|
||||
double get();
|
||||
}
|
||||
/// <summary>
|
||||
/// Time taken for Physics simulations. You should use this for operations
|
||||
/// within Script.FixedUpdate()
|
||||
/// </summary>
|
||||
static property double FixedDeltaTime
|
||||
{
|
||||
double get();
|
||||
}
|
||||
};
|
||||
}
|
|
@ -31,10 +31,159 @@ namespace SHADE
|
|||
/// <summary>
|
||||
/// Represents the available supported keycodes that can be passed into the
|
||||
/// key-based Input functions.
|
||||
///
|
||||
/// Attempting to follow https://docs.unity3d.com/ScriptReference/KeyCode.html
|
||||
/// Win32 keycodes are shift-insensitive, i.e. 'A' and 'a' are the same keycode and '1' and '!' are the same keycode
|
||||
/// </summary>
|
||||
enum class KeyCode : int
|
||||
{
|
||||
Backspace = static_cast<int>(SHInputManager::SH_KEYCODE::BACKSPACE),
|
||||
Delete = static_cast<int>(SHInputManager::SH_KEYCODE::DEL),
|
||||
Tab = static_cast<int>(SHInputManager::SH_KEYCODE::TAB),
|
||||
Clear = static_cast<int>(SHInputManager::SH_KEYCODE::CLEAR),
|
||||
Return = static_cast<int>(SHInputManager::SH_KEYCODE::ENTER),
|
||||
Pause = static_cast<int>(SHInputManager::SH_KEYCODE::PAUSE),
|
||||
Escape = static_cast<int>(SHInputManager::SH_KEYCODE::ESCAPE),
|
||||
Space = static_cast<int>(SHInputManager::SH_KEYCODE::SPACE),
|
||||
Keypad0 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_0),
|
||||
Keypad1 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_1),
|
||||
Keypad2 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_2),
|
||||
Keypad3 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_3),
|
||||
Keypad4 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_4),
|
||||
Keypad5 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_5),
|
||||
Keypad6 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_6),
|
||||
Keypad7 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_7),
|
||||
Keypad8 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_8),
|
||||
Keypad9 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_9),
|
||||
KeypadPeriod = static_cast<int>(SHInputManager::SH_KEYCODE::DECIMAL),
|
||||
KeypadDivide = static_cast<int>(SHInputManager::SH_KEYCODE::DIVIDE),
|
||||
KeypadMultiply = static_cast<int>(SHInputManager::SH_KEYCODE::MULTIPLY),
|
||||
KeypadMinus = static_cast<int>(SHInputManager::SH_KEYCODE::SUBTRACT),
|
||||
KeypadPlus = static_cast<int>(SHInputManager::SH_KEYCODE::ADD),
|
||||
KeypadEnter = static_cast<int>(SHInputManager::SH_KEYCODE::ENTER),
|
||||
//KeypadEquals
|
||||
UpArrow = static_cast<int>(SHInputManager::SH_KEYCODE::UP_ARROW),
|
||||
DownArrow = static_cast<int>(SHInputManager::SH_KEYCODE::DOWN_ARROW),
|
||||
RightArrow = static_cast<int>(SHInputManager::SH_KEYCODE::RIGHT_ARROW),
|
||||
LeftArrow = static_cast<int>(SHInputManager::SH_KEYCODE::LEFT_ARROW),
|
||||
Insert = static_cast<int>(SHInputManager::SH_KEYCODE::INSERT),
|
||||
Home = static_cast<int>(SHInputManager::SH_KEYCODE::HOME),
|
||||
End = static_cast<int>(SHInputManager::SH_KEYCODE::END),
|
||||
PageUp = static_cast<int>(SHInputManager::SH_KEYCODE::PAGE_UP),
|
||||
PageDown = static_cast<int>(SHInputManager::SH_KEYCODE::PAGE_DOWN),
|
||||
F1 = static_cast<int>(SHInputManager::SH_KEYCODE::F1),
|
||||
F2 = static_cast<int>(SHInputManager::SH_KEYCODE::F2),
|
||||
F3 = static_cast<int>(SHInputManager::SH_KEYCODE::F3),
|
||||
F4 = static_cast<int>(SHInputManager::SH_KEYCODE::F4),
|
||||
F5 = static_cast<int>(SHInputManager::SH_KEYCODE::F5),
|
||||
F6 = static_cast<int>(SHInputManager::SH_KEYCODE::F6),
|
||||
F7 = static_cast<int>(SHInputManager::SH_KEYCODE::F7),
|
||||
F8 = static_cast<int>(SHInputManager::SH_KEYCODE::F8),
|
||||
F9 = static_cast<int>(SHInputManager::SH_KEYCODE::F9),
|
||||
F10 = static_cast<int>(SHInputManager::SH_KEYCODE::F10),
|
||||
F11 = static_cast<int>(SHInputManager::SH_KEYCODE::F11),
|
||||
F12 = static_cast<int>(SHInputManager::SH_KEYCODE::F12),
|
||||
F13 = static_cast<int>(SHInputManager::SH_KEYCODE::F13),
|
||||
F14 = static_cast<int>(SHInputManager::SH_KEYCODE::F14),
|
||||
F15 = static_cast<int>(SHInputManager::SH_KEYCODE::F15),
|
||||
F16 = static_cast<int>(SHInputManager::SH_KEYCODE::F16),
|
||||
F17 = static_cast<int>(SHInputManager::SH_KEYCODE::F17),
|
||||
F18 = static_cast<int>(SHInputManager::SH_KEYCODE::F18),
|
||||
F19 = static_cast<int>(SHInputManager::SH_KEYCODE::F19),
|
||||
F20 = static_cast<int>(SHInputManager::SH_KEYCODE::F20),
|
||||
F21 = static_cast<int>(SHInputManager::SH_KEYCODE::F21),
|
||||
F22 = static_cast<int>(SHInputManager::SH_KEYCODE::F22),
|
||||
F23 = static_cast<int>(SHInputManager::SH_KEYCODE::F23),
|
||||
F24 = static_cast<int>(SHInputManager::SH_KEYCODE::F24),
|
||||
Alpha0 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_0),
|
||||
Alpha1 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_1),
|
||||
Alpha2 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_2),
|
||||
Alpha3 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_3),
|
||||
Alpha4 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_4),
|
||||
Alpha5 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_5),
|
||||
Alpha6 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_6),
|
||||
Alpha7 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_7),
|
||||
Alpha8 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_8),
|
||||
Alpha9 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_9),
|
||||
//Exclaim
|
||||
//DoubleQuote
|
||||
//Hash
|
||||
//Dollar
|
||||
//Percent
|
||||
//Ampersand
|
||||
Quote = static_cast<int>(SHInputManager::SH_KEYCODE::OEM_7),
|
||||
//LeftParen
|
||||
//RightParen
|
||||
//Asterisk
|
||||
//Plus
|
||||
Comma = static_cast<int>(SHInputManager::SH_KEYCODE::OEM_COMMA),
|
||||
Minus = static_cast<int>(SHInputManager::SH_KEYCODE::OEM_MINUS),
|
||||
Period = static_cast<int>(SHInputManager::SH_KEYCODE::OEM_PERIOD),
|
||||
Slash = static_cast<int>(SHInputManager::SH_KEYCODE::OEM_2),
|
||||
//Colon
|
||||
Semicolon = static_cast<int>(SHInputManager::SH_KEYCODE::OEM_1),
|
||||
//Less
|
||||
Equals = static_cast<int>(SHInputManager::SH_KEYCODE::OEM_PLUS),
|
||||
//Greater
|
||||
//Question
|
||||
//At
|
||||
LeftBracket = static_cast<int>(SHInputManager::SH_KEYCODE::OEM_4),
|
||||
Backslash = static_cast<int>(SHInputManager::SH_KEYCODE::OEM_5),
|
||||
RightBracket = static_cast<int>(SHInputManager::SH_KEYCODE::OEM_6),
|
||||
//Caret
|
||||
//Underscore
|
||||
BackQuote = static_cast<int>(SHInputManager::SH_KEYCODE::OEM_3),
|
||||
A = static_cast<int>(SHInputManager::SH_KEYCODE::A),
|
||||
B = static_cast<int>(SHInputManager::SH_KEYCODE::B),
|
||||
C = static_cast<int>(SHInputManager::SH_KEYCODE::C),
|
||||
D = static_cast<int>(SHInputManager::SH_KEYCODE::D),
|
||||
E = static_cast<int>(SHInputManager::SH_KEYCODE::E),
|
||||
F = static_cast<int>(SHInputManager::SH_KEYCODE::F),
|
||||
G = static_cast<int>(SHInputManager::SH_KEYCODE::G),
|
||||
H = static_cast<int>(SHInputManager::SH_KEYCODE::H),
|
||||
I = static_cast<int>(SHInputManager::SH_KEYCODE::I),
|
||||
J = static_cast<int>(SHInputManager::SH_KEYCODE::J),
|
||||
K = static_cast<int>(SHInputManager::SH_KEYCODE::K),
|
||||
L = static_cast<int>(SHInputManager::SH_KEYCODE::L),
|
||||
M = static_cast<int>(SHInputManager::SH_KEYCODE::M),
|
||||
N = static_cast<int>(SHInputManager::SH_KEYCODE::N),
|
||||
O = static_cast<int>(SHInputManager::SH_KEYCODE::O),
|
||||
P = static_cast<int>(SHInputManager::SH_KEYCODE::P),
|
||||
Q = static_cast<int>(SHInputManager::SH_KEYCODE::Q),
|
||||
R = static_cast<int>(SHInputManager::SH_KEYCODE::R),
|
||||
S = static_cast<int>(SHInputManager::SH_KEYCODE::S),
|
||||
T = static_cast<int>(SHInputManager::SH_KEYCODE::T),
|
||||
U = static_cast<int>(SHInputManager::SH_KEYCODE::U),
|
||||
V = static_cast<int>(SHInputManager::SH_KEYCODE::V),
|
||||
W = static_cast<int>(SHInputManager::SH_KEYCODE::W),
|
||||
X = static_cast<int>(SHInputManager::SH_KEYCODE::X),
|
||||
Y = static_cast<int>(SHInputManager::SH_KEYCODE::Y),
|
||||
Z = static_cast<int>(SHInputManager::SH_KEYCODE::Z),
|
||||
//LeftCurlyBracket
|
||||
//Pipe
|
||||
//RightCurlyBracket
|
||||
//Tilde
|
||||
NumLock = static_cast<int>(SHInputManager::SH_KEYCODE::NUM_LOCK),
|
||||
CapsLock = static_cast<int>(SHInputManager::SH_KEYCODE::CAPS_LOCK),
|
||||
ScrollLock = static_cast<int>(SHInputManager::SH_KEYCODE::SCROLL_LOCK),
|
||||
RightShift = static_cast<int>(SHInputManager::SH_KEYCODE::RIGHT_SHIFT),
|
||||
LeftShift = static_cast<int>(SHInputManager::SH_KEYCODE::LEFT_SHIFT),
|
||||
RightControl = static_cast<int>(SHInputManager::SH_KEYCODE::RIGHT_CTRL),
|
||||
LeftControl = static_cast<int>(SHInputManager::SH_KEYCODE::LEFT_CTRL),
|
||||
RightAlt = static_cast<int>(SHInputManager::SH_KEYCODE::RIGHT_ALT),
|
||||
LeftAlt = static_cast<int>(SHInputManager::SH_KEYCODE::LEFT_ALT),
|
||||
LeftWindows = static_cast<int>(SHInputManager::SH_KEYCODE::LEFT_WINDOWS),
|
||||
RightWindows = static_cast<int>(SHInputManager::SH_KEYCODE::RIGHT_WINDOWS),
|
||||
//AltGr
|
||||
Help = static_cast<int>(SHInputManager::SH_KEYCODE::HELP),
|
||||
Print = static_cast<int>(SHInputManager::SH_KEYCODE::PRINT),
|
||||
SysReq = static_cast<int>(SHInputManager::SH_KEYCODE::PRINT_SCREEN),
|
||||
//Break
|
||||
//Menu
|
||||
//Mouse buttons use mouse codes, which are enums declared later
|
||||
//TODO Controller input
|
||||
#if 0
|
||||
Space = static_cast<int>(SHInputManager::SH_KEYCODE::SPACE),
|
||||
//Apostrophe = static_cast<int>(SHInputManager::SH_KEYCODE::APOSTROPHE),
|
||||
Comma = static_cast<int>(SHInputManager::SH_KEYCODE::OEM_COMMA),
|
||||
Minus = static_cast<int>(SHInputManager::SH_KEYCODE::OEM_MINUS),
|
||||
|
@ -190,7 +339,8 @@ namespace SHADE
|
|||
JoystickButton6 = JoystickView,
|
||||
JoystickButton7 = JoystickMenu,
|
||||
JoystickButton8 = JoystickLeftStick,
|
||||
JoystickButton9 = JoystickRightStick
|
||||
JoystickButton9 = JoystickRightStick
|
||||
#endif
|
||||
|
||||
};
|
||||
/// <summary>
|
||||
|
|
|
@ -236,6 +236,22 @@ namespace SHADE
|
|||
lhs.y * rhs.y
|
||||
);
|
||||
}
|
||||
Vector2 Vector2::operator*(Vector2 lhs, double rhs)
|
||||
{
|
||||
return Vector2
|
||||
(
|
||||
lhs.x * static_cast<float>(rhs),
|
||||
lhs.y * static_cast<float>(rhs)
|
||||
);
|
||||
}
|
||||
Vector2 Vector2::operator/(Vector2 lhs, double rhs)
|
||||
{
|
||||
return Vector2
|
||||
(
|
||||
lhs.x / static_cast<float>(rhs),
|
||||
lhs.y / static_cast<float>(rhs)
|
||||
);
|
||||
}
|
||||
Vector2 Vector2::operator*(Vector2 lhs, float rhs)
|
||||
{
|
||||
return Vector2
|
||||
|
|
|
@ -361,6 +361,22 @@ namespace SHADE
|
|||
/// <param name="lhs">Vector2 to multiply with.</param>
|
||||
/// <param name="rhs">Scalar to multiply with.</param>
|
||||
/// <returns>The result of the scalar multiplication.</returns>
|
||||
static Vector2 operator*(Vector2 lhs, double rhs);
|
||||
/// <summary>
|
||||
/// Calculates the division of a Vector2 with a scalar value and returns
|
||||
/// the result.
|
||||
/// </summary>
|
||||
/// <param name="lhs">Scalar to divide with.</param>
|
||||
/// <param name="rhs">Vector2 to divide with.</param>
|
||||
/// <returns>The result of the scalar division.</returns>
|
||||
static Vector2 operator/(Vector2 lhs, double rhs);
|
||||
/// <summary>
|
||||
/// Calculates the multiplication of a Vector2 with a scalar value and returns
|
||||
/// the result.
|
||||
/// </summary>
|
||||
/// <param name="lhs">Vector2 to multiply with.</param>
|
||||
/// <param name="rhs">Scalar to multiply with.</param>
|
||||
/// <returns>The result of the scalar multiplication.</returns>
|
||||
static Vector2 operator*(Vector2 lhs, float rhs);
|
||||
/// <summary>
|
||||
/// Calculates the division of a Vector2 with a scalar value and returns
|
||||
|
|
|
@ -237,6 +237,24 @@ namespace SHADE
|
|||
lhs.z * rhs.z
|
||||
);
|
||||
}
|
||||
Vector3 Vector3::operator*(Vector3 lhs, double rhs)
|
||||
{
|
||||
return Vector3
|
||||
(
|
||||
lhs.x * static_cast<float>(rhs),
|
||||
lhs.y * static_cast<float>(rhs),
|
||||
lhs.z * static_cast<float>(rhs)
|
||||
);
|
||||
}
|
||||
Vector3 Vector3::operator/(Vector3 lhs, double rhs)
|
||||
{
|
||||
return Vector3
|
||||
(
|
||||
lhs.x / static_cast<float>(rhs),
|
||||
lhs.y / static_cast<float>(rhs),
|
||||
lhs.z / static_cast<float>(rhs)
|
||||
);
|
||||
}
|
||||
Vector3 Vector3::operator*(Vector3 lhs, float rhs)
|
||||
{
|
||||
return Vector3
|
||||
|
|
|
@ -375,6 +375,22 @@ namespace SHADE
|
|||
/// <param name="lhs">Vector3 to multiply with.</param>
|
||||
/// <param name="rhs">Scalar to multiply with.</param>
|
||||
/// <returns>The result of the scalar multiplication.</returns>
|
||||
static Vector3 operator*(Vector3 lhs, double rhs);
|
||||
/// <summary>
|
||||
/// Calculates the division of a Vector3 with a scalar value and returns
|
||||
/// the result.
|
||||
/// </summary>
|
||||
/// <param name="lhs">Scalar to divide with.</param>
|
||||
/// <param name="rhs">Vector3 to divide with.</param>
|
||||
/// <returns>The result of the scalar division.</returns>
|
||||
static Vector3 operator/(Vector3 lhs, double rhs);
|
||||
/// <summary>
|
||||
/// Calculates the multiplication of a Vector3 with a scalar value and returns
|
||||
/// the result.
|
||||
/// </summary>
|
||||
/// <param name="lhs">Vector3 to multiply with.</param>
|
||||
/// <param name="rhs">Scalar to multiply with.</param>
|
||||
/// <returns>The result of the scalar multiplication.</returns>
|
||||
static Vector3 operator*(Vector3 lhs, float rhs);
|
||||
/// <summary>
|
||||
/// Calculates the division of a Vector3 with a scalar value and returns
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/************************************************************************************//*!
|
||||
\file CollisionInfo.cxx
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Oct 31, 2022
|
||||
\brief Contains the definition of the functions of the managed CollisionInfo
|
||||
struct.
|
||||
|
||||
Note: This file is written in C++17/CLI.
|
||||
|
||||
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||
of DigiPen Institute of Technology is prohibited.
|
||||
*//*************************************************************************************/
|
||||
#include "SHpch.h"
|
||||
#include "CollisionInfo.hxx"
|
||||
#include "Components/RigidBody.hxx"
|
||||
#include "Components/Collider.hxx"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
Collider^ CollisionInfo::Collider::get()
|
||||
{
|
||||
return GameObject.GetComponent<SHADE::Collider^>();
|
||||
}
|
||||
|
||||
CollisionShape^ CollisionInfo::CollisionShape::get()
|
||||
{
|
||||
throw gcnew System::NotImplementedException();
|
||||
}
|
||||
|
||||
RigidBody^ CollisionInfo::RigidBody::get()
|
||||
{
|
||||
return GameObject.GetComponent<SHADE::RigidBody^>();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/************************************************************************************//*!
|
||||
\file CollisionInfo.hxx
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Oct 31, 2022
|
||||
\brief Contains the definition of the managed CollisionInfo struct with the
|
||||
definition of its properties and declaration of functions.
|
||||
|
||||
Note: This file is written in C++17/CLI.
|
||||
|
||||
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||
of DigiPen Institute of Technology is prohibited.
|
||||
*//*************************************************************************************/
|
||||
#pragma once
|
||||
// Project Includes
|
||||
#include "Engine/GameObject.hxx"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Forward Declarations */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
ref class RigidBody;
|
||||
ref class Collider;
|
||||
ref class CollisionShape;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Struct that describes a collision
|
||||
/// </summary>
|
||||
public value struct CollisionInfo
|
||||
{
|
||||
public:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Properties */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// The GameObject whose collider you are colliding with.
|
||||
/// </summary>
|
||||
property GameObject GameObject;
|
||||
/// <summary>
|
||||
/// The Collider that you are colliding with.
|
||||
/// </summary>
|
||||
property Collider^ Collider
|
||||
{
|
||||
SHADE::Collider^ get();
|
||||
}
|
||||
/// <summary>
|
||||
/// The CollisionShape of the Collider that you are colliding with.
|
||||
/// </summary>
|
||||
property CollisionShape^ CollisionShape
|
||||
{
|
||||
SHADE::CollisionShape^ get();
|
||||
}
|
||||
/// <summary>
|
||||
/// The RigidBody that you are colliding with.
|
||||
/// </summary>
|
||||
property RigidBody^ RigidBody
|
||||
{
|
||||
SHADE::RigidBody^ get();
|
||||
}
|
||||
};
|
||||
}
|
|
@ -147,6 +147,48 @@ namespace SHADE
|
|||
SAFE_NATIVE_CALL_END(this)
|
||||
}
|
||||
|
||||
void Script::OnCollisionEnter(CollisionInfo collision)
|
||||
{
|
||||
SAFE_NATIVE_CALL_BEGIN
|
||||
onCollisionEnter(collision);
|
||||
SAFE_NATIVE_CALL_END(this)
|
||||
}
|
||||
|
||||
void Script::OnCollisionStay(CollisionInfo collision)
|
||||
{
|
||||
SAFE_NATIVE_CALL_BEGIN
|
||||
onCollisionStay(collision);
|
||||
SAFE_NATIVE_CALL_END(this)
|
||||
}
|
||||
|
||||
void Script::OnCollisionExit(CollisionInfo collision)
|
||||
{
|
||||
SAFE_NATIVE_CALL_BEGIN
|
||||
onCollisionExit(collision);
|
||||
SAFE_NATIVE_CALL_END(this)
|
||||
}
|
||||
|
||||
void Script::OnTriggerEnter(CollisionInfo collision)
|
||||
{
|
||||
SAFE_NATIVE_CALL_BEGIN
|
||||
onTriggerEnter(collision);
|
||||
SAFE_NATIVE_CALL_END(this)
|
||||
}
|
||||
|
||||
void Script::OnTriggerStay(CollisionInfo collision)
|
||||
{
|
||||
SAFE_NATIVE_CALL_BEGIN
|
||||
onTriggerStay(collision);
|
||||
SAFE_NATIVE_CALL_END(this)
|
||||
}
|
||||
|
||||
void Script::OnTriggerExit(CollisionInfo collision)
|
||||
{
|
||||
SAFE_NATIVE_CALL_BEGIN
|
||||
onTriggerExit(collision);
|
||||
SAFE_NATIVE_CALL_END(this)
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constructors */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -169,4 +211,14 @@ namespace SHADE
|
|||
void Script::update() {}
|
||||
void Script::lateUpdate() {}
|
||||
void Script::onDestroy() {}
|
||||
}// namespace PlushieAPI
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Virtual Event Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
void Script::onTriggerEnter(CollisionInfo) {}
|
||||
void Script::onTriggerStay(CollisionInfo) {}
|
||||
void Script::onTriggerExit(CollisionInfo) {}
|
||||
void Script::onCollisionEnter(CollisionInfo) {}
|
||||
void Script::onCollisionStay(CollisionInfo) {}
|
||||
void Script::onCollisionExit(CollisionInfo) {}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ of DigiPen Institute of Technology is prohibited.
|
|||
|
||||
// Project Includes
|
||||
#include "Engine/GameObject.hxx"
|
||||
#include "Physics/CollisionInfo.hxx"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -213,6 +214,46 @@ namespace SHADE
|
|||
/// </summary>
|
||||
void OnDestroy();
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Event Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Used to call onCollisionEnter(). This should be called when a collision is
|
||||
/// detected between the attached GameObject and another GameObject.
|
||||
/// </summary>
|
||||
/// <param name="collision">Information on the collision event.</param>
|
||||
void OnCollisionEnter(CollisionInfo collision);
|
||||
/// <summary>
|
||||
/// Used to call onCollisionStay(). This should be called when a collision is
|
||||
/// persistent between the attached GameObject and another GameObject.
|
||||
/// </summary>
|
||||
/// <param name="collision">Information on the collision event.</param>
|
||||
void OnCollisionStay(CollisionInfo collision);
|
||||
/// <summary>
|
||||
/// Used to call onCollisionExit(). This should be called when a collision ends
|
||||
/// between the attached GameObject and another GameObject.
|
||||
/// </summary>
|
||||
/// <param name="collision">Information on the collision event.</param>
|
||||
void OnCollisionExit(CollisionInfo collision);
|
||||
/// <summary>
|
||||
/// Used to call onTriggerEnter(). This should be called when a trigger-type
|
||||
/// collision is detected between the attached GameObject and another GameObject.
|
||||
/// </summary>
|
||||
/// <param name="collision">Information on the collision event.</param>
|
||||
void OnTriggerEnter(CollisionInfo collision);
|
||||
/// <summary>
|
||||
/// Used to call onTriggerStay(). This should be called when a trigger-type
|
||||
/// collision is detected between the attached GameObject and another GameObject.
|
||||
/// </summary>
|
||||
/// <param name="collision">Information on the collision event.</param>
|
||||
void OnTriggerStay(CollisionInfo collision);
|
||||
/// <summary>
|
||||
/// Used to call onTriggerExit(). This should be called when a trigger-type
|
||||
/// collision is detected between the attached GameObject and another GameObject.
|
||||
/// </summary>
|
||||
/// <param name="collision">Information on the collision event.</param>
|
||||
void OnTriggerExit(CollisionInfo collision);
|
||||
|
||||
protected:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Constructors */
|
||||
|
@ -273,6 +314,46 @@ namespace SHADE
|
|||
/// </summary>
|
||||
virtual void onDestroy();
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Virtual Event Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Called when the attached GameObject has a trigger Collider and collides with
|
||||
/// another GameObject with a Collider in the first frame of collision.
|
||||
/// </summary>
|
||||
/// <param name="info">Information on the collision event.</param>
|
||||
virtual void onTriggerEnter(CollisionInfo info);
|
||||
/// <summary>
|
||||
/// Called when the attached GameObject has a trigger Collider and collides with
|
||||
/// another GameObject with a Collider in subsequent frames of collision.
|
||||
/// </summary>
|
||||
/// <param name="info">Information on the collision event.</param>
|
||||
virtual void onTriggerStay(CollisionInfo info);
|
||||
/// <summary>
|
||||
/// Called when the attached GameObject has a trigger Collider and leaves a
|
||||
/// collision with another GameObject with a Collider2D.
|
||||
/// </summary>
|
||||
/// <param name="info">Information on the collision event.</param>
|
||||
virtual void onTriggerExit(CollisionInfo info);
|
||||
/// <summary>
|
||||
/// Called when the attached GameObject has a Collider and collides with
|
||||
/// another GameObject with a Collider in the first frame of collision.
|
||||
/// </summary>
|
||||
/// <param name="info">Information on the collision event.</param>
|
||||
virtual void onCollisionEnter(CollisionInfo info);
|
||||
/// <summary>
|
||||
/// Called when the attached GameObject has a Collider and collides with
|
||||
/// another GameObject with a Collider in subsequent frames of collision.
|
||||
/// </summary>
|
||||
/// <param name="info">Information on the collision event.</param>
|
||||
virtual void onCollisionStay(CollisionInfo info);
|
||||
/// <summary>
|
||||
/// Called when the attached GameObject has a Collider and leaves a
|
||||
/// collision with another GameObject with a Collider2D.
|
||||
/// </summary>
|
||||
/// <param name="info">Information on the collision event.</param>
|
||||
virtual void onCollisionExit(CollisionInfo info);
|
||||
|
||||
private:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
|
@ -280,4 +361,4 @@ namespace SHADE
|
|||
GameObject owner;
|
||||
};
|
||||
|
||||
} // namespace PlushieAPI
|
||||
}
|
||||
|
|
|
@ -28,6 +28,8 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include "Engine/Entity.hxx"
|
||||
#include "Serialisation/ReflectionUtilities.hxx"
|
||||
#include "Engine/Application.hxx"
|
||||
#include "Physics/SHPhysicsSystemInterface.h"
|
||||
#include "Physics/SHPhysicsUtils.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -71,7 +73,7 @@ namespace SHADE
|
|||
SAFE_NATIVE_CALL_BEGIN
|
||||
Script^ script;
|
||||
return AddScriptViaNameWithRef(entity, scriptName, script);
|
||||
SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore")
|
||||
SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -301,7 +303,7 @@ namespace SHADE
|
|||
removeScript(script);
|
||||
}
|
||||
scriptList->Clear();
|
||||
SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore")
|
||||
SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
|
||||
}
|
||||
void ScriptStore::RemoveAllScriptsImmediately(Entity entity, bool callOnDestroy)
|
||||
{
|
||||
|
@ -326,7 +328,7 @@ namespace SHADE
|
|||
startList.Remove(script);
|
||||
}
|
||||
scriptList->Clear();
|
||||
SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore")
|
||||
SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -365,7 +367,7 @@ namespace SHADE
|
|||
startList.AddRange(%inactiveStartList);
|
||||
inactiveStartList.Clear();
|
||||
|
||||
SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore")
|
||||
SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
|
||||
}
|
||||
void ScriptStore::FrameCleanUp()
|
||||
{
|
||||
|
@ -386,7 +388,7 @@ namespace SHADE
|
|||
scripts.Remove(entity);
|
||||
}
|
||||
}
|
||||
SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore")
|
||||
SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
|
||||
}
|
||||
void ScriptStore::Exit()
|
||||
{
|
||||
|
@ -410,7 +412,7 @@ namespace SHADE
|
|||
startList.Clear();
|
||||
disposalQueue.Clear();
|
||||
scriptTypeList = nullptr;
|
||||
SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore")
|
||||
SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -439,7 +441,7 @@ namespace SHADE
|
|||
script->FixedUpdate();
|
||||
}
|
||||
}
|
||||
SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore")
|
||||
SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
|
||||
}
|
||||
void ScriptStore::ExecuteUpdate()
|
||||
{
|
||||
|
@ -456,7 +458,7 @@ namespace SHADE
|
|||
script->Update();
|
||||
}
|
||||
}
|
||||
SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore")
|
||||
SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
|
||||
}
|
||||
void ScriptStore::ExecuteLateUpdate()
|
||||
{
|
||||
|
@ -473,7 +475,95 @@ namespace SHADE
|
|||
script->LateUpdate();
|
||||
}
|
||||
}
|
||||
SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore")
|
||||
SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
|
||||
}
|
||||
|
||||
void ScriptStore::ExecuteCollisionFunctions()
|
||||
{
|
||||
SAFE_NATIVE_CALL_BEGIN
|
||||
/* Collisions */
|
||||
const auto& collisions = SHPhysicsSystemInterface::GetCollisionInfo();
|
||||
for (const auto& collisionInfo : collisions)
|
||||
{
|
||||
auto entities =
|
||||
{
|
||||
std::make_pair(collisionInfo.GetEntityA(), collisionInfo.GetEntityB()),
|
||||
std::make_pair(collisionInfo.GetEntityB(), collisionInfo.GetEntityA())
|
||||
};
|
||||
for (auto entity : entities)
|
||||
{
|
||||
// Don't bother if this object has no scripts or is inactive
|
||||
if (!isEntityActive(entity.first) || !scripts.ContainsKey(entity.first))
|
||||
continue;
|
||||
|
||||
// Construct the collision state object
|
||||
CollisionInfo info;
|
||||
info.GameObject = GameObject(entity.second);
|
||||
|
||||
// Call all of the script's functions
|
||||
auto entityScripts = scripts[entity.first];
|
||||
if (entityScripts->Count > 0)
|
||||
{
|
||||
for each (Script ^ script in entityScripts)
|
||||
{
|
||||
switch (collisionInfo.GetCollisionState())
|
||||
{
|
||||
case SHCollisionEvent::State::ENTER:
|
||||
script->OnCollisionEnter(info);
|
||||
break;
|
||||
case SHCollisionEvent::State::STAY:
|
||||
script->OnCollisionStay(info);
|
||||
break;
|
||||
case SHCollisionEvent::State::EXIT:
|
||||
script->OnCollisionExit(info);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Triggers */
|
||||
const auto& triggers = SHPhysicsSystemInterface::GetTriggerInfo();
|
||||
for (const auto& triggerInfo : triggers)
|
||||
{
|
||||
auto entities =
|
||||
{
|
||||
std::make_pair(triggerInfo.GetEntityA(), triggerInfo.GetEntityB()),
|
||||
std::make_pair(triggerInfo.GetEntityB(), triggerInfo.GetEntityA())
|
||||
};
|
||||
for (auto entity : entities)
|
||||
{
|
||||
// Don't bother if this object has no scripts or is inactive
|
||||
if (!isEntityActive(entity.first) || !scripts.ContainsKey(entity.first))
|
||||
continue;
|
||||
|
||||
// Construct the collision state object
|
||||
CollisionInfo info;
|
||||
info.GameObject = GameObject(entity.second);
|
||||
|
||||
// Call all of the script's functions
|
||||
auto entityScripts = scripts[entity.first];
|
||||
if (entityScripts->Count > 0)
|
||||
{
|
||||
for each (Script ^ script in entityScripts)
|
||||
{
|
||||
switch (triggerInfo.GetCollisionState())
|
||||
{
|
||||
case SHCollisionEvent::State::ENTER:
|
||||
script->OnTriggerEnter(info);
|
||||
break;
|
||||
case SHCollisionEvent::State::STAY:
|
||||
script->OnTriggerStay(info);
|
||||
break;
|
||||
case SHCollisionEvent::State::EXIT:
|
||||
script->OnTriggerExit(info);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
|
||||
}
|
||||
|
||||
bool ScriptStore::SerialiseScripts(Entity entity, System::IntPtr yamlNodePtr)
|
||||
|
@ -509,7 +599,7 @@ namespace SHADE
|
|||
}
|
||||
|
||||
return true;
|
||||
SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore")
|
||||
SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -559,7 +649,7 @@ namespace SHADE
|
|||
}
|
||||
return true;
|
||||
|
||||
SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore")
|
||||
SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -233,6 +233,10 @@ namespace SHADE
|
|||
/// Executes LateUpdate() for all scripts.
|
||||
/// </summary>
|
||||
static void ExecuteLateUpdate();
|
||||
/// <summary>
|
||||
/// Executes OnCollision*() and OnTrigger*() for all scripts.
|
||||
/// </summary>
|
||||
static void ExecuteCollisionFunctions();
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Serialisation Functions */
|
||||
|
|
|
@ -40,4 +40,34 @@ public class PhysicsTest : Script
|
|||
}
|
||||
Debug.Log($"{Transform.LocalPosition.y}");
|
||||
}
|
||||
|
||||
protected override void fixedUpdate()
|
||||
{
|
||||
Debug.Log("Fixed Update");
|
||||
}
|
||||
|
||||
protected override void onCollisionEnter(CollisionInfo info)
|
||||
{
|
||||
Debug.Log($"Collision Enter: {info.GameObject.Name}");
|
||||
}
|
||||
protected override void onCollisionStay(CollisionInfo info)
|
||||
{
|
||||
Debug.Log($"Collision Stay: {info.GameObject.Name}");
|
||||
}
|
||||
protected override void onCollisionExit(CollisionInfo info)
|
||||
{
|
||||
Debug.Log($"Collision Exit: {info.GameObject.Name}");
|
||||
}
|
||||
protected override void onTriggerEnter(CollisionInfo info)
|
||||
{
|
||||
Debug.Log($"Trigger Enter: {info.GameObject.Name}");
|
||||
}
|
||||
protected override void onTriggerStay(CollisionInfo info)
|
||||
{
|
||||
Debug.Log($"Trigger Stay: {info.GameObject.Name}");
|
||||
}
|
||||
protected override void onTriggerExit(CollisionInfo info)
|
||||
{
|
||||
Debug.Log($"Trigger Exit: {info.GameObject.Name}");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue