Merge branch 'main' into SP3-141-Camera-System

This commit is contained in:
maverickdgg 2022-11-01 15:31:11 +08:00
commit d917159f67
49 changed files with 1439 additions and 723 deletions

View File

@ -1,3 +1,3 @@
Name: DeferredComposite_CS Name: DeferredComposite_CS
ID: 42814284 ID: 45072428
Type: 2 Type: 2

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,3 +1,3 @@
Name: TestCube_FS Name: TestCube_FS
ID: 37450402 ID: 46377769
Type: 2 Type: 2

Binary file not shown.

View File

@ -1,3 +1,3 @@
Name: TestCube_VS Name: TestCube_VS
ID: 41688429 ID: 39210065
Type: 2 Type: 2

View File

@ -128,7 +128,6 @@ namespace Sandbox
floorRigidBody.SetType(SHRigidBodyComponent::Type::STATIC); floorRigidBody.SetType(SHRigidBodyComponent::Type::STATIC);
auto* floorBox = floorCollider.AddBoundingBox(); auto* floorBox = floorCollider.AddBoundingBox();
floorBox->SetHalfExtents(floorTransform.GetWorldScale() * 0.5f);
// Create blank entity with a script // Create blank entity with a script
//testObj = SHADE::SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>(); //testObj = SHADE::SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();

View File

@ -10,6 +10,7 @@
*****************************************************************************/ *****************************************************************************/
#pragma once #pragma once
#include <vulkan/vulkan.hpp>
#include "SHAssetData.h" #include "SHAssetData.h"
#include "SH_API.h" #include "SH_API.h"
#include <vector> #include <vector>
@ -17,12 +18,14 @@
namespace SHADE namespace SHADE
{ {
//! Tighter control over types of shaders. Maps directly to their
//! equivalent vk::ShaderStageFlagBits.
enum class SH_SHADER_TYPE : uint8_t enum class SH_SHADER_TYPE : uint8_t
{ {
VERTEX, VERTEX = static_cast<uint8_t>(vk::ShaderStageFlagBits::eVertex),
FRAGMENT, FRAGMENT = static_cast<uint8_t>(vk::ShaderStageFlagBits::eFragment),
COMPUTE, COMPUTE = static_cast<uint8_t>(vk::ShaderStageFlagBits::eCompute),
INAVLID_TYPE INAVLID_TYPE = std::numeric_limits<uint8_t>::max()
}; };
struct SH_API SHShaderAsset : SHAssetData struct SH_API SHShaderAsset : SHAssetData

View File

@ -101,9 +101,10 @@ namespace SHADE
{ {
for (auto i { 0 }; i < SHADER_TYPE_MAX_COUNT; ++i) for (auto i { 0 }; i < SHADER_TYPE_MAX_COUNT; ++i)
{ {
if (name.find(SHADER_IDENTIFIERS[i].data()) != std::string::npos) const auto& [SHADER_SUFFIX, SHADER_TYPE] = SHADER_IDENTIFIERS[i];
if (name.find(SHADER_SUFFIX.data()) != std::string::npos)
{ {
return static_cast<SH_SHADER_TYPE>(i); return SHADER_TYPE;
} }
} }

View File

@ -11,6 +11,10 @@
#pragma once #pragma once
#include "SHAssetLoader.h" #include "SHAssetLoader.h"
#include "Assets/Asset Types/SHPrefabAsset.h"
#include "Assets/Asset Types/SHSceneAsset.h"
#include "Assets/Asset Types/SHMaterialAsset.h"
namespace SHADE namespace SHADE
{ {
struct SHTextBasedLoader : SHAssetLoader struct SHTextBasedLoader : SHAssetLoader

View File

@ -13,6 +13,7 @@
#include <cstdint> #include <cstdint>
#include <string> #include <string>
#include <filesystem> #include <filesystem>
#include "Asset Types/SHShaderAsset.h"
// FMOD Fwd Declare // FMOD Fwd Declare
namespace FMOD namespace FMOD
@ -113,10 +114,10 @@ constexpr std::string_view VERTEX_SHADER{ "_VS" };
constexpr std::string_view FRAGMENT_SHADER{ "_FS" }; constexpr std::string_view FRAGMENT_SHADER{ "_FS" };
constexpr std::string_view COMPUTER_SHADER{ "_CS" }; constexpr std::string_view COMPUTER_SHADER{ "_CS" };
constexpr std::string_view SHADER_IDENTIFIERS[] = { constexpr std::pair<std::string_view, SHADE::SH_SHADER_TYPE> SHADER_IDENTIFIERS[] = {
VERTEX_SHADER, std::make_pair(VERTEX_SHADER, SHADE::SH_SHADER_TYPE::VERTEX),
FRAGMENT_SHADER, std::make_pair(FRAGMENT_SHADER, SHADE::SH_SHADER_TYPE::FRAGMENT),
COMPUTER_SHADER std::make_pair(COMPUTER_SHADER, SHADE::SH_SHADER_TYPE::COMPUTE)
}; };
constexpr size_t SHADER_TYPE_MAX_COUNT{ 3 }; constexpr size_t SHADER_TYPE_MAX_COUNT{ 3 };

View File

@ -151,19 +151,23 @@ namespace SHADE
****************************************************************************/ ****************************************************************************/
AssetID SHAssetManager::CreateNewAsset(AssetType type, AssetName name) noexcept AssetID SHAssetManager::CreateNewAsset(AssetType type, AssetName name) noexcept
{ {
SHAssetData* data = nullptr;
std::string newPath{ ASSET_ROOT }; std::string newPath{ ASSET_ROOT };
switch (type) switch (type)
{ {
case AssetType::PREFAB: case AssetType::PREFAB:
newPath += PREFAB_FOLDER; newPath += PREFAB_FOLDER;
data = new SHPrefabAsset();
break; break;
case AssetType::SCENE: case AssetType::SCENE:
newPath += SCENE_FOLDER; newPath += SCENE_FOLDER;
data = new SHSceneAsset();
break; break;
case AssetType::MATERIAL: case AssetType::MATERIAL:
newPath += MATERIAL_FOLDER; newPath += MATERIAL_FOLDER;
data = new SHMaterialAsset();
break; break;
default: default:
@ -189,6 +193,8 @@ namespace SHADE
) )
}); });
assetData.emplace(id, data);
return id; return id;
} }

View File

@ -33,19 +33,19 @@ namespace SHADE
return; return;
} }
std::vector<SHComponentRemovedEvent> eventVec;
for (uint32_t i = 0; i < componentSet.Size(); ++i) for (uint32_t i = 0; i < componentSet.Size(); ++i)
{ {
SHComponent* comp = (SHComponent*) componentSet.GetElement(i, EntityHandleGenerator::GetIndex(entityID)); SHComponent* comp = (SHComponent*) componentSet.GetElement(i, EntityHandleGenerator::GetIndex(entityID));
if (comp) if (comp)
{ {
comp->OnDestroy(); comp->OnDestroy();
}
SHComponentRemovedEvent eventData; SHComponentRemovedEvent eventData;
eventData.eid = entityID; eventData.eid = entityID;
eventData.removedComponentType = i; eventData.removedComponentType = i;
eventVec.push_back(eventData);
SHEventManager::BroadcastEvent<SHComponentRemovedEvent>(eventData, SH_COMPONENT_REMOVED_EVENT); }
} }
@ -57,6 +57,12 @@ namespace SHADE
componentSet.RemoveElements(EntityHandleGenerator::GetIndex(entityID)); componentSet.RemoveElements(EntityHandleGenerator::GetIndex(entityID));
for (auto& eventData : eventVec)
{
SHEventManager::BroadcastEvent<SHComponentRemovedEvent>(eventData, SH_COMPONENT_REMOVED_EVENT);
}
//entityHandle.RemoveHandle(entityID); //entityHandle.RemoveHandle(entityID);

View File

@ -251,7 +251,7 @@ namespace SHADE
SHEditorWidgets::DragVec3 SHEditorWidgets::DragVec3
( (
"Half Extents", { "X", "Y", "Z" }, "Half Extents", { "X", "Y", "Z" },
[box, transformComponent] { return (transformComponent->GetWorldScale() * 2.0f) * box->GetHalfExtents(); }, [box, transformComponent] { return (box->GetHalfExtents() * 2.0f) / transformComponent->GetWorldScale(); },
[collider](SHVec3 const& vec) { collider->SetBoundingBox(vec); }); [collider](SHVec3 const& vec) { collider->SetBoundingBox(vec); });
} }
else if (collider->GetType() == SHCollider::Type::SPHERE) else if (collider->GetType() == SHCollider::Type::SPHERE)

View File

@ -37,6 +37,8 @@ of DigiPen Institute of Technology is prohibited.
#include "Assets/Asset Types/SHTextureAsset.h" #include "Assets/Asset Types/SHTextureAsset.h"
#include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h" #include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h"
#include "Graphics/MiddleEnd/Lights/SHLightingSubSystem.h" #include "Graphics/MiddleEnd/Lights/SHLightingSubSystem.h"
#include "Assets/SHAssetManager.h"
#include "Resource/SHResourceManager.h"
namespace SHADE namespace SHADE
{ {
@ -109,9 +111,10 @@ namespace SHADE
transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
// Load Built In Shaders
shaderModuleLibrary.ImportAllShaderSource(device); static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEFAULT);
shaderModuleLibrary.ReflectAllShaderModules(); 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 void SHGraphicsSystem::InitSceneRenderGraph(void) noexcept
@ -180,16 +183,7 @@ namespace SHADE
gBufferSubpass->AddColorOutput("Albedo"); gBufferSubpass->AddColorOutput("Albedo");
gBufferSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL); 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 // deferred composite
auto deferredCompositeShader = shaderModuleLibrary.GetBuiltInShaderModule("DeferredComposite_CS");
gBufferNode->AddNodeCompute(deferredCompositeShader, { "Position", "Normals", "Albedo", "Light Layer Indices", "Scene" }); gBufferNode->AddNodeCompute(deferredCompositeShader, { "Position", "Normals", "Albedo", "Light Layer Indices", "Scene" });
@ -207,10 +201,7 @@ namespace SHADE
worldRenderer->SetCameraDirector(cameraSystem->CreateDirector()); worldRenderer->SetCameraDirector(cameraSystem->CreateDirector());
auto cubeVS = shaderModuleLibrary.GetBuiltInShaderModule("TestCube_VS"); defaultMaterial = AddMaterial(defaultVertShader, defaultFragShader, gBufferSubpass);
auto cubeFS = shaderModuleLibrary.GetBuiltInShaderModule("TestCube_FS");
defaultMaterial = AddMaterial(cubeVS, cubeFS, gBufferSubpass);
} }
void SHGraphicsSystem::InitMiddleEnd(void) noexcept void SHGraphicsSystem::InitMiddleEnd(void) noexcept

View File

@ -25,7 +25,6 @@ of DigiPen Institute of Technology is prohibited.
#include "ECS_Base/System/SHSystemRoutine.h" #include "ECS_Base/System/SHSystemRoutine.h"
#include "Graphics/Descriptors/SHVkDescriptorPool.h" #include "Graphics/Descriptors/SHVkDescriptorPool.h"
#include "Graphics/RenderGraph/SHRenderGraph.h" #include "Graphics/RenderGraph/SHRenderGraph.h"
#include "Graphics/MiddleEnd/Shaders/SHShaderModuleLibrary.h"
#include "SHMeshLibrary.h" #include "SHMeshLibrary.h"
#include "Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.h" #include "Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.h"
#include "../Textures/SHTextureLibrary.h" #include "../Textures/SHTextureLibrary.h"
@ -329,6 +328,7 @@ namespace SHADE
SHTextureLibrary texLibrary; SHTextureLibrary texLibrary;
SHSamplerCache samplerCache; SHSamplerCache samplerCache;
SHMaterialInstanceCache materialInstanceCache; SHMaterialInstanceCache materialInstanceCache;
// Viewports // Viewports
#ifdef SHEDITOR #ifdef SHEDITOR
Handle<SHViewport> editorViewport; Handle<SHViewport> editorViewport;
@ -350,9 +350,12 @@ namespace SHADE
Handle<SHCamera> worldCamera; Handle<SHCamera> worldCamera;
Handle<SHCamera> screenCamera; Handle<SHCamera> screenCamera;
SHShaderModuleLibrary shaderModuleLibrary; // Built-In Shaders
Handle<SHVkShaderModule> defaultVertShader;
Handle<SHVkShaderModule> defaultFragShader;
Handle<SHVkShaderModule> deferredCompositeShader;
// Temp Materials // Built-In Materials
Handle<SHMaterial> defaultMaterial; Handle<SHMaterial> defaultMaterial;
Handle<SHRenderGraph> worldRenderGraph; Handle<SHRenderGraph> worldRenderGraph;

View File

@ -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;
};
}

View File

@ -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();
}
}
}

View File

@ -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

View File

@ -18,6 +18,7 @@
// Project Headers // Project Headers
#include "ECS_Base/Managers/SHSystemManager.h" #include "ECS_Base/Managers/SHSystemManager.h"
#include "Math/SHMathHelpers.h"
#include "Physics/SHPhysicsSystem.h" #include "Physics/SHPhysicsSystem.h"
namespace SHADE namespace SHADE
@ -28,21 +29,9 @@ namespace SHADE
SHRigidBodyComponent::SHRigidBodyComponent() noexcept SHRigidBodyComponent::SHRigidBodyComponent() noexcept
: type { Type::DYNAMIC } : type { Type::DYNAMIC }
, flags { 0 }
, dirtyFlags { 0 }
, interpolate { true } , interpolate { true }
, rp3dBody { nullptr } , rp3dBody { nullptr }
, mass { 1.0f } {}
, drag { 0.01f }
, angularDrag { 0.01f }
{
// Set default flags: Gravity & Sleeping enabled
flags |= 1U << 0;
flags |= 1U << 1;
// Set all dirty flags to true
dirtyFlags = 1023;
}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Getter Function Definitions */ /* Getter Function Definitions */
@ -50,12 +39,24 @@ namespace SHADE
bool SHRigidBodyComponent::IsGravityEnabled() const noexcept bool SHRigidBodyComponent::IsGravityEnabled() const noexcept
{ {
return flags & (1U << 0); if (rp3dBody == nullptr)
{
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return false;
}
return rp3dBody->isGravityEnabled();
} }
bool SHRigidBodyComponent::IsAllowedToSleep() const noexcept bool SHRigidBodyComponent::IsAllowedToSleep() const noexcept
{ {
return flags & (1U << 1); if (rp3dBody == nullptr)
{
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return false;
}
return rp3dBody->isAllowedToSleep();
} }
bool SHRigidBodyComponent::IsInterpolating() const noexcept bool SHRigidBodyComponent::IsInterpolating() const noexcept
@ -70,67 +71,151 @@ namespace SHADE
float SHRigidBodyComponent::GetMass() const noexcept float SHRigidBodyComponent::GetMass() const noexcept
{ {
return mass; if (rp3dBody == nullptr)
{
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return 0.0f;
}
return rp3dBody->getMass();
} }
float SHRigidBodyComponent::GetDrag() const noexcept float SHRigidBodyComponent::GetDrag() const noexcept
{ {
return drag; if (rp3dBody == nullptr)
{
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return 0.0f;
}
return rp3dBody->getLinearDamping();
} }
float SHRigidBodyComponent::GetAngularDrag() const noexcept float SHRigidBodyComponent::GetAngularDrag() const noexcept
{ {
return angularDrag; if (rp3dBody == nullptr)
{
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return 0.0f;
}
return rp3dBody->getAngularDamping();
} }
bool SHRigidBodyComponent::GetFreezePositionX() const noexcept bool SHRigidBodyComponent::GetFreezePositionX() const noexcept
{ {
return flags & (1U << 2); if (rp3dBody == nullptr)
{
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return false;
}
const auto& LINEAR_CONSTRAINTS = rp3dBody->getLinearLockAxisFactor();
return SHMath::CompareFloat(LINEAR_CONSTRAINTS.x, 0.0f);
} }
bool SHRigidBodyComponent::GetFreezePositionY() const noexcept bool SHRigidBodyComponent::GetFreezePositionY() const noexcept
{ {
return flags & (1U << 3); if (rp3dBody == nullptr)
{
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return false;
}
const auto& LINEAR_CONSTRAINTS = rp3dBody->getLinearLockAxisFactor();
return SHMath::CompareFloat(LINEAR_CONSTRAINTS.y, 0.0f);
} }
bool SHRigidBodyComponent::GetFreezePositionZ() const noexcept bool SHRigidBodyComponent::GetFreezePositionZ() const noexcept
{ {
return flags & (1U << 4); if (rp3dBody == nullptr)
{
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return false;
}
const auto& LINEAR_CONSTRAINTS = rp3dBody->getLinearLockAxisFactor();
return SHMath::CompareFloat(LINEAR_CONSTRAINTS.z, 0.0f);
} }
bool SHRigidBodyComponent::GetFreezeRotationX() const noexcept bool SHRigidBodyComponent::GetFreezeRotationX() const noexcept
{ {
return flags & (1U << 5); if (rp3dBody == nullptr)
{
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return false;
}
const auto& ANGULAR_CONSTRAINTS = rp3dBody->getAngularLockAxisFactor();
return SHMath::CompareFloat(ANGULAR_CONSTRAINTS.x, 0.0f);
} }
bool SHRigidBodyComponent::GetFreezeRotationY() const noexcept bool SHRigidBodyComponent::GetFreezeRotationY() const noexcept
{ {
return flags & (1U << 6); if (rp3dBody == nullptr)
{
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return false;
}
const auto& ANGULAR_CONSTRAINTS = rp3dBody->getAngularLockAxisFactor();
return SHMath::CompareFloat(ANGULAR_CONSTRAINTS.y, 0.0f);
} }
bool SHRigidBodyComponent::GetFreezeRotationZ() const noexcept bool SHRigidBodyComponent::GetFreezeRotationZ() const noexcept
{ {
return flags & (1U << 7); if (rp3dBody == nullptr)
{
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return false;
} }
const SHVec3& SHRigidBodyComponent::GetForce() const noexcept const auto& ANGULAR_CONSTRAINTS = rp3dBody->getAngularLockAxisFactor();
{ return SHMath::CompareFloat(ANGULAR_CONSTRAINTS.z, 0.0f);
return force;
} }
const SHVec3& SHRigidBodyComponent::GetTorque() const noexcept SHVec3 SHRigidBodyComponent::GetForce() const noexcept
{ {
return torque; if (rp3dBody == nullptr)
{
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return false;
} }
const SHVec3& SHRigidBodyComponent::GetLinearVelocity() const noexcept return rp3dBody->getForce();
{
return linearVelocity;
} }
const SHVec3& SHRigidBodyComponent::GetAngularVelocity() const noexcept SHVec3 SHRigidBodyComponent::GetTorque() const noexcept
{ {
return angularVelocity; if (rp3dBody == nullptr)
{
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return SHVec3::Zero;
}
return rp3dBody->getTorque();
}
SHVec3 SHRigidBodyComponent::GetLinearVelocity() const noexcept
{
if (rp3dBody == nullptr)
{
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return SHVec3::Zero;
}
return rp3dBody->getLinearVelocity();
}
SHVec3 SHRigidBodyComponent::GetAngularVelocity() const noexcept
{
if (rp3dBody == nullptr)
{
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return SHVec3::Zero;
}
return rp3dBody->getAngularVelocity();
} }
const SHVec3& SHRigidBodyComponent::GetPosition() const noexcept const SHVec3& SHRigidBodyComponent::GetPosition() const noexcept
@ -157,8 +242,15 @@ namespace SHADE
if (type == newType) if (type == newType)
return; return;
dirtyFlags |= 1U << 4;
type = newType; type = newType;
if (rp3dBody == nullptr)
{
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return;
}
rp3dBody->setType(static_cast<rp3d::BodyType>(type));
} }
void SHRigidBodyComponent::SetGravityEnabled(bool enableGravity) noexcept void SHRigidBodyComponent::SetGravityEnabled(bool enableGravity) noexcept
@ -171,8 +263,13 @@ namespace SHADE
return; return;
} }
dirtyFlags |= 1U << FLAG_POS; if (rp3dBody == nullptr)
enableGravity ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); {
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return;
}
rp3dBody->enableGravity(enableGravity);
} }
void SHRigidBodyComponent::SetIsAllowedToSleep(bool isAllowedToSleep) noexcept void SHRigidBodyComponent::SetIsAllowedToSleep(bool isAllowedToSleep) noexcept
@ -185,92 +282,127 @@ namespace SHADE
return; return;
} }
dirtyFlags |= 1U << 1; if (rp3dBody == nullptr)
isAllowedToSleep ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); {
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return;
}
rp3dBody->setIsAllowedToSleep(isAllowedToSleep);
} }
void SHRigidBodyComponent::SetFreezePositionX(bool freezePositionX) noexcept void SHRigidBodyComponent::SetFreezePositionX(bool freezePositionX) noexcept
{ {
static constexpr int FLAG_POS = 2;
if (type == Type::STATIC) if (type == Type::STATIC)
{ {
SHLOG_WARNING("Cannot set linear constraints of a static object {}", GetEID()) SHLOG_WARNING("Cannot set linear constraints of a static object {}", GetEID())
return; return;
} }
dirtyFlags |= 1U << 2; if (rp3dBody == nullptr)
freezePositionX ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); {
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return;
}
auto linearConstraints = rp3dBody->getLinearLockAxisFactor();
linearConstraints.x = freezePositionX ? 0.0f : 1.0f;
rp3dBody->setLinearLockAxisFactor(linearConstraints);
} }
void SHRigidBodyComponent::SetFreezePositionY(bool freezePositionY) noexcept void SHRigidBodyComponent::SetFreezePositionY(bool freezePositionY) noexcept
{ {
static constexpr int FLAG_POS = 3;
if (type == Type::STATIC) if (type == Type::STATIC)
{ {
SHLOG_WARNING("Cannot set linear constraints of a static object {}", GetEID()) SHLOG_WARNING("Cannot set linear constraints of a static object {}", GetEID())
return; return;
} }
dirtyFlags |= 1U << 2; if (rp3dBody == nullptr)
freezePositionY ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); {
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return;
}
auto linearConstraints = rp3dBody->getLinearLockAxisFactor();
linearConstraints.y = freezePositionY ? 0.0f : 1.0f;
rp3dBody->setLinearLockAxisFactor(linearConstraints);
} }
void SHRigidBodyComponent::SetFreezePositionZ(bool freezePositionZ) noexcept void SHRigidBodyComponent::SetFreezePositionZ(bool freezePositionZ) noexcept
{ {
static constexpr int FLAG_POS = 4;
if (type == Type::STATIC) if (type == Type::STATIC)
{ {
SHLOG_WARNING("Cannot set linear constraints of a static object {}", GetEID()) SHLOG_WARNING("Cannot set linear constraints of a static object {}", GetEID())
return; return;
} }
dirtyFlags |= 1U << 2; if (rp3dBody == nullptr)
freezePositionZ ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); {
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return;
}
auto linearConstraints = rp3dBody->getLinearLockAxisFactor();
linearConstraints.z = freezePositionZ ? 0.0f : 1.0f;
rp3dBody->setLinearLockAxisFactor(linearConstraints);
} }
void SHRigidBodyComponent::SetFreezeRotationX(bool freezeRotationX) noexcept void SHRigidBodyComponent::SetFreezeRotationX(bool freezeRotationX) noexcept
{ {
static constexpr int FLAG_POS = 5;
if (type == Type::STATIC) if (type == Type::STATIC)
{ {
SHLOG_WARNING("Cannot set angular constraints of a static object {}", GetEID()) SHLOG_WARNING("Cannot set angular constraints of a static object {}", GetEID())
return; return;
} }
dirtyFlags |= 1U << 3; if (rp3dBody == nullptr)
freezeRotationX ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); {
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return;
}
auto angularConstraints = rp3dBody->getAngularLockAxisFactor();
angularConstraints.x = freezeRotationX ? 0.0f : 1.0f;
rp3dBody->setAngularLockAxisFactor(angularConstraints);
} }
void SHRigidBodyComponent::SetFreezeRotationY(bool freezeRotationY) noexcept void SHRigidBodyComponent::SetFreezeRotationY(bool freezeRotationY) noexcept
{ {
static constexpr int FLAG_POS = 6;
if (type == Type::STATIC) if (type == Type::STATIC)
{ {
SHLOG_WARNING("Cannot set angular constraints of a static object {}", GetEID()) SHLOG_WARNING("Cannot set angular constraints of a static object {}", GetEID())
return; return;
} }
dirtyFlags |= 1U << 3; if (rp3dBody == nullptr)
freezeRotationY ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); {
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return;
}
auto angularConstraints = rp3dBody->getAngularLockAxisFactor();
angularConstraints.y = freezeRotationY ? 0.0f : 1.0f;
rp3dBody->setAngularLockAxisFactor(angularConstraints);
} }
void SHRigidBodyComponent::SetFreezeRotationZ(bool freezeRotationZ) noexcept void SHRigidBodyComponent::SetFreezeRotationZ(bool freezeRotationZ) noexcept
{ {
static constexpr int FLAG_POS = 7;
if (type == Type::STATIC) if (type == Type::STATIC)
{ {
SHLOG_WARNING("Cannot set angular constraints of a static object {}", GetEID()) SHLOG_WARNING("Cannot set angular constraints of a static object {}", GetEID())
return; return;
} }
dirtyFlags |= 1U << 3; if (rp3dBody == nullptr)
freezeRotationZ ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); {
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return;
}
auto angularConstraints = rp3dBody->getAngularLockAxisFactor();
angularConstraints.z = freezeRotationZ ? 0.0f : 1.0f;
rp3dBody->setAngularLockAxisFactor(angularConstraints);
} }
void SHRigidBodyComponent::SetInterpolate(bool allowInterpolation) noexcept void SHRigidBodyComponent::SetInterpolate(bool allowInterpolation) noexcept
@ -286,8 +418,13 @@ namespace SHADE
return; return;
} }
dirtyFlags |= 1U << 5; if (rp3dBody == nullptr)
mass = newMass; {
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return;
}
rp3dBody->setMass(newMass);
} }
void SHRigidBodyComponent::SetDrag(float newDrag) noexcept void SHRigidBodyComponent::SetDrag(float newDrag) noexcept
@ -298,8 +435,13 @@ namespace SHADE
return; return;
} }
dirtyFlags |= 1U << 6; if (rp3dBody == nullptr)
drag = newDrag; {
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return;
}
rp3dBody->setLinearDamping(newDrag);
} }
void SHRigidBodyComponent::SetAngularDrag(float newAngularDrag) noexcept void SHRigidBodyComponent::SetAngularDrag(float newAngularDrag) noexcept
@ -310,8 +452,13 @@ namespace SHADE
return; return;
} }
dirtyFlags |= 1U << 7; if (rp3dBody == nullptr)
angularDrag = newAngularDrag; {
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return;
}
rp3dBody->setLinearDamping(newAngularDrag);
} }
void SHRigidBodyComponent::SetLinearVelocity(const SHVec3& newLinearVelocity) noexcept void SHRigidBodyComponent::SetLinearVelocity(const SHVec3& newLinearVelocity) noexcept
@ -322,8 +469,13 @@ namespace SHADE
return; return;
} }
dirtyFlags |= 1U << 8; if (rp3dBody == nullptr)
linearVelocity = newLinearVelocity; {
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return;
}
rp3dBody->setLinearVelocity(newLinearVelocity);
} }
void SHRigidBodyComponent::SetAngularVelocity(const SHVec3& newAngularVelocity) noexcept void SHRigidBodyComponent::SetAngularVelocity(const SHVec3& newAngularVelocity) noexcept
@ -334,8 +486,13 @@ namespace SHADE
return; return;
} }
dirtyFlags |= 1U << 9; if (rp3dBody == nullptr)
angularVelocity = newAngularVelocity; {
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return;
}
rp3dBody->setAngularVelocity(newAngularVelocity);
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -346,7 +503,7 @@ namespace SHADE
{ {
if (rp3dBody == nullptr) if (rp3dBody == nullptr)
{ {
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID()) SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return; return;
} }
@ -357,7 +514,7 @@ namespace SHADE
{ {
if (rp3dBody == nullptr) if (rp3dBody == nullptr)
{ {
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID()) SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return; return;
} }
@ -368,7 +525,7 @@ namespace SHADE
{ {
if (rp3dBody == nullptr) if (rp3dBody == nullptr)
{ {
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID()) SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return; return;
} }
@ -379,7 +536,7 @@ namespace SHADE
{ {
if (rp3dBody == nullptr) if (rp3dBody == nullptr)
{ {
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID()) SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return; return;
} }
@ -390,7 +547,7 @@ namespace SHADE
{ {
if (rp3dBody == nullptr) if (rp3dBody == nullptr)
{ {
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID()) SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return; return;
} }
@ -401,7 +558,7 @@ namespace SHADE
{ {
if (rp3dBody == nullptr) if (rp3dBody == nullptr)
{ {
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID()) SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return; return;
} }
@ -412,7 +569,7 @@ namespace SHADE
{ {
if (rp3dBody == nullptr) if (rp3dBody == nullptr)
{ {
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID()) SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return; return;
} }
@ -423,7 +580,7 @@ namespace SHADE
{ {
if (rp3dBody == nullptr) if (rp3dBody == nullptr)
{ {
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID()) SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return; return;
} }

View File

@ -94,10 +94,10 @@ namespace SHADE
[[nodiscard]] bool GetFreezeRotationY () const noexcept; [[nodiscard]] bool GetFreezeRotationY () const noexcept;
[[nodiscard]] bool GetFreezeRotationZ () const noexcept; [[nodiscard]] bool GetFreezeRotationZ () const noexcept;
[[nodiscard]] const SHVec3& GetForce () const noexcept; [[nodiscard]] SHVec3 GetForce () const noexcept;
[[nodiscard]] const SHVec3& GetTorque () const noexcept; [[nodiscard]] SHVec3 GetTorque () const noexcept;
[[nodiscard]] const SHVec3& GetLinearVelocity () const noexcept; [[nodiscard]] SHVec3 GetLinearVelocity () const noexcept;
[[nodiscard]] const SHVec3& GetAngularVelocity () const noexcept; [[nodiscard]] SHVec3 GetAngularVelocity () const noexcept;
[[nodiscard]] const SHVec3& GetPosition () const noexcept; [[nodiscard]] const SHVec3& GetPosition () const noexcept;
[[nodiscard]] const SHQuaternion& GetOrientation () const noexcept; [[nodiscard]] const SHQuaternion& GetOrientation () const noexcept;
@ -150,25 +150,10 @@ namespace SHADE
static constexpr size_t NUM_DIRTY_FLAGS = 16; static constexpr size_t NUM_DIRTY_FLAGS = 16;
Type type; Type type;
// rX rY rZ pX pY pZ slp g
uint8_t flags;
// 0 0 0 0 0 0 aV lV aD d m t ag lc slp g
uint16_t dirtyFlags;
bool interpolate; bool interpolate;
reactphysics3d::RigidBody* rp3dBody; reactphysics3d::RigidBody* rp3dBody;
float mass;
float drag;
float angularDrag;
SHVec3 force;
SHVec3 linearVelocity;
SHVec3 torque;
SHVec3 angularVelocity;
SHVec3 position; SHVec3 position;
SHQuaternion orientation; SHQuaternion orientation;

View File

@ -168,100 +168,6 @@ namespace SHADE
rp3dBody->removeCollider(collider); 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);
if (rb->dirtyFlags != 0)
{
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;
}
else
{
rb->linearVelocity = rigidBody->getLinearVelocity();
rb->angularVelocity = rigidBody->getAngularVelocity();
}
}
void SHPhysicsObject::SyncColliders(SHColliderComponent* c) const noexcept void SHPhysicsObject::SyncColliders(SHColliderComponent* c) const noexcept
{ {
int index = 0; int index = 0;

View File

@ -72,7 +72,6 @@ namespace SHADE
int AddCollider (SHCollider* collider); int AddCollider (SHCollider* collider);
void RemoveCollider (int index); void RemoveCollider (int index);
void SyncRigidBody (SHRigidBodyComponent* rb) const noexcept;
void SyncColliders (SHColliderComponent* c) const noexcept; void SyncColliders (SHColliderComponent* c) const noexcept;
private: private:

View File

@ -19,8 +19,9 @@
#include "ECS_Base/Managers/SHSystemManager.h" #include "ECS_Base/Managers/SHSystemManager.h"
#include "Editor/SHEditor.h" #include "Editor/SHEditor.h"
#include "Math/SHMathHelpers.h" #include "Math/SHMathHelpers.h"
#include "Scene/SHSceneManager.h"
#include "Math/Transform/SHTransformComponent.h" #include "Math/Transform/SHTransformComponent.h"
#include "Scene/SHSceneManager.h"
#include "Scripting/SHScriptEngine.h"
namespace SHADE namespace SHADE
{ {
@ -304,8 +305,6 @@ namespace SHADE
if (!COMPONENT_ACTIVE) if (!COMPONENT_ACTIVE)
continue; continue;
physicsObject.SyncRigidBody(rigidBodyComponent);
} }
// Sync colliders // Sync colliders
@ -325,37 +324,56 @@ namespace SHADE
void SHPhysicsSystem::PhysicsFixedUpdate::Execute(double dt) noexcept void SHPhysicsSystem::PhysicsFixedUpdate::Execute(double dt) noexcept
{ {
auto* system = reinterpret_cast<SHPhysicsSystem*>(GetSystem()); auto* physicsSystem = reinterpret_cast<SHPhysicsSystem*>(GetSystem());
fixedTimeStep = 1.0 / system->fixedDT; auto 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; accumulatedTime += dt;
int count = 0; int count = 0;
while (accumulatedTime > fixedTimeStep) 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; accumulatedTime -= fixedTimeStep;
++count; ++count;
} }
stats.numSteps = count; stats.numSteps = count;
system->worldUpdated = count > 0; physicsSystem->worldUpdated = count > 0;
system->interpolationFactor = accumulatedTime / fixedTimeStep; physicsSystem->interpolationFactor = accumulatedTime / fixedTimeStep;
} }
void SHPhysicsSystem::PhysicsPostUpdate::Execute(double) noexcept void SHPhysicsSystem::PhysicsPostUpdate::Execute(double) noexcept
{ {
auto* system = reinterpret_cast<SHPhysicsSystem*>(GetSystem()); auto* physicsSystem = reinterpret_cast<SHPhysicsSystem*>(GetSystem());
// Interpolate transforms for rendering // 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();
} }
} }
@ -612,10 +630,17 @@ namespace SHADE
auto* rigidBodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(ENTITY_ID); auto* rigidBodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(ENTITY_ID);
auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(ENTITY_ID); auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(ENTITY_ID);
SHASSERT(physicsObject != nullptr, "Physics object has been lost from the world!") SHASSERT(physicsObject != nullptr, "Physics object " + std::to_string(ENTITY_ID) + " has been lost from the world!")
if (REMOVED_ID == RIGID_BODY_ID) if (REMOVED_ID == RIGID_BODY_ID)
{ {
// Wake up all physics objects
for (auto& [entityID, object] : map)
{
if (SHComponentManager::HasComponent<SHRigidBodyComponent>(entityID))
reinterpret_cast<rp3d::RigidBody*>(object.rp3dBody)->setIsSleeping(false);
}
world->destroyRigidBody(reinterpret_cast<rp3d::RigidBody*>(physicsObject->rp3dBody)); world->destroyRigidBody(reinterpret_cast<rp3d::RigidBody*>(physicsObject->rp3dBody));
physicsObject->rp3dBody = nullptr; physicsObject->rp3dBody = nullptr;
@ -630,13 +655,6 @@ namespace SHADE
for (auto& collider : colliderComponent->colliders) for (auto& collider : colliderComponent->colliders)
physicsObject->AddCollider(&collider); physicsObject->AddCollider(&collider);
} }
// Wake up all physics objects
for (auto& [entityID, object] : map)
{
if (SHComponentManager::HasComponent<SHRigidBodyComponent>(entityID))
reinterpret_cast<rp3d::RigidBody*>(object.rp3dBody)->setIsSleeping(false);
}
} }
if (REMOVED_ID == COLLIDER_ID) if (REMOVED_ID == COLLIDER_ID)

View File

@ -28,11 +28,6 @@
namespace SHADE namespace SHADE
{ {
/*-----------------------------------------------------------------------------------*/
/* Concepts */
/*-----------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Type Definitions */ /* Type Definitions */

View File

@ -42,6 +42,9 @@ namespace SHADE
SHCollisionEvent cInfo; SHCollisionEvent cInfo;
// Update collision state
cInfo.collisionState = static_cast<SHCollisionEvent::State>(cp.getEventType());
// Match body and collider for collision event // Match body and collider for collision event
const rp3d::Entity body1 = cp.getBody1()->getEntity(); const rp3d::Entity body1 = cp.getBody1()->getEntity();
const rp3d::Entity body2 = cp.getBody2()->getEntity(); const rp3d::Entity body2 = cp.getBody2()->getEntity();
@ -76,9 +79,6 @@ namespace SHADE
return cInfo; return cInfo;
} }
// Update collision state
cInfo.collisionState = static_cast<SHCollisionEvent::State>(cp.getEventType());
return cInfo; return cInfo;
} }
} // namespace SHADE } // namespace SHADE

View File

@ -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;
}
}

View File

@ -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;
};
}

View File

@ -17,9 +17,45 @@ of DigiPen Institute of Technology is prohibited.
#include "SH_API.h" #include "SH_API.h"
#include "SHResourceLibrary.h" #include "SHResourceLibrary.h"
#include "Assets/SHAssetMacros.h" #include "Assets/SHAssetMacros.h"
#include "Assets/Asset Types/SHMeshAsset.h"
#include "Assets/Asset Types/SHTextureAsset.h"
#include "Assets/Asset Types/SHShaderAsset.h"
#include "Graphics/Shaders/SHVkShaderModule.h"
#include "Graphics/MiddleEnd/Textures/SHTextureLibrary.h"
#include "Graphics/MiddleEnd/Interface/SHMeshLibrary.h"
#include "Graphics/MiddleEnd/Interface/SHMaterial.h"
#include "Assets/Asset Types/SHMaterialAsset.h"
namespace SHADE namespace SHADE
{ {
template<typename T = void>
struct SHResourceLoader
{
using AssetType = void;
};
template<>
struct SHResourceLoader<SHMesh>
{
using AssetType = SHMeshAsset;
};
template<>
struct SHResourceLoader<SHTexture>
{
using AssetType = SHTextureAsset;
};
template<>
struct SHResourceLoader<SHVkShaderModule>
{
using AssetType = SHShaderAsset;
};
template<>
struct SHResourceLoader<SHMaterial>
{
using AssetType = SHMaterialAsset;
};
/// <summary> /// <summary>
/// Static class responsible for loading and caching runtime resources from their /// Static class responsible for loading and caching runtime resources from their
/// serialised Asset IDs. /// serialised Asset IDs.
@ -124,6 +160,14 @@ namespace SHADE
/// <returns>Reference to the AssetHandleMap of the specified type.</returns> /// <returns>Reference to the AssetHandleMap of the specified type.</returns>
template<typename ResourceType> template<typename ResourceType>
static std::pair<AssetHandleMapRef, HandleAssetMapRef> getAssetHandleMap(); static std::pair<AssetHandleMapRef, HandleAssetMapRef> getAssetHandleMap();
/// <summary>
///
/// </summary>
/// <typeparam name="ResourceType"></typeparam>
/// <param name="assetData"></param>
/// <returns></returns>
template<typename ResourceType>
static Handle<ResourceType> load(AssetID assetId, const typename SHResourceLoader<ResourceType>::AssetType& assetData);
}; };
} }

View File

@ -13,12 +13,17 @@ of DigiPen Institute of Technology is prohibited.
#pragma once #pragma once
// Primary Include // Primary Include
#include "SHResourceManager.h" #include "SHResourceManager.h"
// External Dependencies
#include <yaml-cpp/yaml.h>
// Project Includes // Project Includes
#include "Assets/SHAssetManager.h" #include "Assets/SHAssetManager.h"
#include "Assets/Asset Types/SHAssetIncludes.h" #include "Assets/Asset Types/SHAssetIncludes.h"
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
#include "ECS_Base/Managers/SHSystemManager.h" #include "ECS_Base/Managers/SHSystemManager.h"
#include "Tools/SHLog.h" #include "Tools/SHLog.h"
#include "Graphics/Shaders/SHVkShaderModule.h"
#include "Graphics/Devices/SHVkLogicalDevice.h"
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
namespace SHADE namespace SHADE
{ {
@ -40,67 +45,19 @@ namespace SHADE
return Handle<ResourceType>(typedHandleMap.get()[assetId]); return Handle<ResourceType>(typedHandleMap.get()[assetId]);
/* Otherwise, we need to load it! */ /* Otherwise, we need to load it! */
// Meshes // Load Asset Data
if constexpr (std::is_same_v<ResourceType, SHMesh>) const auto* assetData = SHAssetManager::GetData<SHResourceLoader<ResourceType>::AssetType>(assetId);
{
// Get system
SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
if (gfxSystem == nullptr)
throw std::runtime_error("[SHResourceManager] Attempted to load graphics resource without a SHGraphicsSystem installed.");
// Load
const SHMeshAsset* assetData = SHAssetManager::GetData<SHMeshAsset>(assetId);
if (assetData == nullptr) if (assetData == nullptr)
{ {
SHLog::Warning("[SHResourceManager] Attempted to load an asset with an invalid Asset ID."); SHLog::Warning("[SHResourceManager] Attempted to load an asset with an invalid Asset ID.");
return {}; return {};
} }
loadedAssetData.emplace_back(assetId);
Handle<SHMesh> meshHandle = gfxSystem->AddMesh auto handle = load<ResourceType>(assetId, *assetData);
( Handle genericHandle = Handle();
assetData->vertexPosition.size(),
assetData->vertexPosition.data(),
assetData->texCoords.data(),
assetData->vertexTangent.data(),
assetData->vertexNormal.data(),
assetData->indices.size(),
assetData->indices.data()
);
Handle genericHandle = Handle(meshHandle);
typedHandleMap.get().emplace(assetId, genericHandle); typedHandleMap.get().emplace(assetId, genericHandle);
typedAssetIdMap.get().emplace(genericHandle, assetId); typedAssetIdMap.get().emplace(genericHandle, assetId);
return meshHandle; return handle;
}
// Textures
else if constexpr (std::is_same_v<ResourceType, SHTexture>)
{
// Get system
SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
if (gfxSystem == nullptr)
throw std::runtime_error("[SHResourceManager] Attempted to load graphics resource without a SHGraphicsSystem installed.");
// Load
const SHTextureAsset* assetData = SHAssetManager::GetData<SHTextureAsset>(assetId);
if (assetData == nullptr)
{
SHLog::Warning("[SHResourceManager] Attempted to load an asset with an invalid Asset ID.");
return {};
}
loadedAssetData.emplace_back(assetId);
Handle<SHTexture> texHandle = gfxSystem->AddTexture
(
assetData->numBytes,
assetData->pixelData,
assetData->width,
assetData->height,
assetData->format,
assetData->mipOffsets
);
typedHandleMap.get().emplace(assetId, Handle(texHandle));
return texHandle;
}
} }
template<typename ResourceType> template<typename ResourceType>
@ -169,4 +126,129 @@ namespace SHADE
} }
return std::make_pair(std::ref(handlesMap[TYPE]), std::ref(assetIdMap[TYPE])); return std::make_pair(std::ref(handlesMap[TYPE]), std::ref(assetIdMap[TYPE]));
} }
template<typename ResourceType>
Handle<ResourceType> SHResourceManager::load(AssetID assetId, const typename SHResourceLoader<ResourceType>::AssetType& assetData)
{
// Get system
SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
if (gfxSystem == nullptr)
throw std::runtime_error("[SHResourceManager] Attempted to load graphics resource without a SHGraphicsSystem installed.");
// Meshes
if constexpr (std::is_same_v<ResourceType, SHMesh>)
{
loadedAssetData.emplace_back(assetId);
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;
}
}
} }

View File

@ -80,7 +80,10 @@ namespace SHADE
{ {
csScriptsExecuteFixedUpdate(); csScriptsExecuteFixedUpdate();
} }
void SHScriptEngine::ExecuteCollisionFunctions()
{
csScriptsExecutePhysicsEvents();
}
void SHScriptEngine::Exit() void SHScriptEngine::Exit()
{ {
// Do not allow deinitialization if not initialised // Do not allow deinitialization if not initialised
@ -377,6 +380,12 @@ namespace SHADE
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore", DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
"ExecuteLateUpdate" "ExecuteLateUpdate"
); );
csScriptsExecutePhysicsEvents = dotNet.GetFunctionPtr<CsFuncPtr>
(
DEFAULT_CSHARP_LIB_NAME,
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
"ExecuteCollisionFunctions"
);
csScriptsFrameCleanUp = dotNet.GetFunctionPtr<CsFuncPtr> csScriptsFrameCleanUp = dotNet.GetFunctionPtr<CsFuncPtr>
( (
DEFAULT_CSHARP_LIB_NAME, DEFAULT_CSHARP_LIB_NAME,

View File

@ -98,6 +98,11 @@ namespace SHADE
/// </summary> /// </summary>
void ExecuteFixedUpdates(); void ExecuteFixedUpdates();
/// <summary> /// <summary>
/// Executes the OnCollision*()s and OnTrigger*()s of the Scripts that are attached
/// to Entities.
/// </summary>
void ExecuteCollisionFunctions();
/// <summary>
/// Shuts down the DotNetRuntime. /// Shuts down the DotNetRuntime.
/// </summary> /// </summary>
void Exit() override; void Exit() override;
@ -245,6 +250,7 @@ namespace SHADE
CsFuncPtr csScriptsExecuteFixedUpdate = nullptr; CsFuncPtr csScriptsExecuteFixedUpdate = nullptr;
CsFuncPtr csScriptsExecuteUpdate = nullptr; CsFuncPtr csScriptsExecuteUpdate = nullptr;
CsFuncPtr csScriptsExecuteLateUpdate = nullptr; CsFuncPtr csScriptsExecuteLateUpdate = nullptr;
CsFuncPtr csScriptsExecutePhysicsEvents = nullptr;
CsFuncPtr csScriptsFrameCleanUp = nullptr; CsFuncPtr csScriptsFrameCleanUp = nullptr;
CsScriptManipFuncPtr csScriptsAdd = nullptr; CsScriptManipFuncPtr csScriptsAdd = nullptr;
CsScriptBasicFuncPtr csScriptsRemoveAll = nullptr; CsScriptBasicFuncPtr csScriptsRemoveAll = nullptr;

View File

@ -12,8 +12,11 @@
#include "Resource/SHResourceManager.h" #include "Resource/SHResourceManager.h"
#include "Graphics/MiddleEnd/Interface/SHRenderable.h" #include "Graphics/MiddleEnd/Interface/SHRenderable.h"
#include "Graphics/MiddleEnd/Interface/SHMaterial.h" #include "Graphics/MiddleEnd/Interface/SHMaterial.h"
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
#include "SHSerializationTools.h" #include "SHSerializationTools.h"
#include "Physics/Components/SHColliderComponent.h" #include "Physics/Components/SHColliderComponent.h"
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
#include "Tools/SHLog.h"
namespace YAML namespace YAML
{ {
@ -303,102 +306,43 @@ namespace YAML
// Write Material // Write Material
YAML::Node node; YAML::Node node;
node[VERT_SHADER_YAML_TAG.data()] = 0; // SHResourceManager::GetAssetID<SHVkShaderModule>(vertexShader).value_or(0); node[VERT_SHADER_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHVkShaderModule>(vertexShader).value_or(0);
node[FRAG_SHADER_YAML_TAG.data()] = 0; // SHResourceManager::GetAssetID<SHVkShaderModule>(fragShader).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[SUBPASS_YAML_TAG.data()] = rhs.GetPipeline()->GetPipelineState().GetSubpass()->GetName();
node[PROPS_YAML_TAG.data()] = propertiesNode; node[PROPS_YAML_TAG.data()] = propertiesNode;
return node; return node;
} }
static bool decode(YAML::Node const& node, SHMaterial& rhs) };
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";
static bool decode(YAML::Node const& node, SHMaterialSpec& rhs)
{ {
/*
// Retrieve Shader Asset IDs // Retrieve Shader Asset IDs
AssetID vertShaderId = 0; if (!node[VERT_SHADER_YAML_TAG.data()])
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
// Get Shader Modules
Handle<SHVkShaderModule> vertexShader, fragShader;
vertexShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(vertShaderId);
fragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(fragShaderId);
// Get Pipeline Library
if (node[SUBPASS_YAML_TAG.data()])
{
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
if (!gfxSystem)
return false; return false;
rhs.vertexShader = node[VERT_SHADER_YAML_TAG.data()].as<AssetID>();
// Grab subpass from worldRenderer if (!node[FRAG_SHADER_YAML_TAG.data()])
auto renderPass = gfxSystem->GetPrimaryRenderpass();
if (!renderPass)
return false; return false;
auto subPass = renderPass->GetSubpass(node[SUBPASS_YAML_TAG.data()].as<std::string>()); rhs.fragShader = node[FRAG_SHADER_YAML_TAG.data()].as<AssetID>();
if (!subPass)
// Retrieve Subpass
if (!node[SUBPASS_YAML_TAG.data()])
return false; return false;
rhs.subpassName = node[SUBPASS_YAML_TAG.data()].as<std::string>();
// Set Pipeline // Retrieve
rhs.SetPipeline(renderPass->GetOrCreatePipeline if (!node[PROPS_YAML_TAG.data()])
(
std::make_pair(vertexShader, fragShader),
subPass
));
}
*/
// TODO: Load Proper Material!
// Set default material
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
if (!gfxSystem)
return false; return false;
rhs.SetPipeline(gfxSystem->GetDefaultMaterial()->GetPipeline()); rhs.properties = node[PROPS_YAML_TAG.data()];
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;
} }
}; };
@ -413,7 +357,7 @@ namespace YAML
{ {
YAML::Node node; YAML::Node node;
node[MESH_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHMesh>(rhs.GetMesh()).value_or(0); 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; return node;
} }
static bool decode(YAML::Node const& node, SHRenderable& rhs) static bool decode(YAML::Node const& node, SHRenderable& rhs)
@ -424,12 +368,17 @@ namespace YAML
} }
if (node[MAT_YAML_TAG.data()].IsDefined()) if (node[MAT_YAML_TAG.data()].IsDefined())
{ {
// TODO: Convert Asset ID To Material HAndle
// Temporarily, use default material // Temporarily, use default material
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>(); auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
if (!gfxSystem) if (!gfxSystem)
return false; 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; return true;
} }

View File

@ -14,6 +14,9 @@ of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/ *//*************************************************************************************/
// Precompiled Headers // Precompiled Headers
#include "SHpch.h" #include "SHpch.h"
// External Dependencies
#include "FRC/SHFramerateController.h"
#include "Physics/SHPhysicsSystemInterface.h"
// Primary Header // Primary Header
#include "Time.hxx" #include "Time.hxx"
@ -31,5 +34,8 @@ namespace SHADE
float Time::DeltaTimeF::get() float Time::DeltaTimeF::get()
{ {
return static_cast<float>(SHFrameRateController::GetRawDeltaTime()); return static_cast<float>(SHFrameRateController::GetRawDeltaTime());
double Time::FixedDeltaTime::get()
{
return SHPhysicsSystemInterface::GetFixedDT();
} }
} }

View File

@ -14,8 +14,6 @@ of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/ *//*************************************************************************************/
#pragma once #pragma once
#include "FRC/SHFramerateController.h"
namespace SHADE namespace SHADE
{ {
/// <summary> /// <summary>
@ -29,18 +27,27 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/// <summary> /// <summary>
/// Time taken to process the previous frame. /// 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> /// </summary>
static property double DeltaTime static property double DeltaTime
{ {
double get(); double get();
} }
/*-----------------------------------------------------------------------------*/
/* Properties */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Time taken to process the previous frame.
/// </summary>
static property float DeltaTimeF static property float DeltaTimeF
{ {
float get(); float get();
/// <summary>
/// Time taken for Physics simulations. You should use this for operations
/// within Script.FixedUpdate()
/// </summary>
static property double FixedDeltaTime
{
double get();
} }
}; };
} }

View File

@ -31,9 +31,158 @@ namespace SHADE
/// <summary> /// <summary>
/// Represents the available supported keycodes that can be passed into the /// Represents the available supported keycodes that can be passed into the
/// key-based Input functions. /// 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> /// </summary>
enum class KeyCode : int 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), Space = static_cast<int>(SHInputManager::SH_KEYCODE::SPACE),
//Apostrophe = static_cast<int>(SHInputManager::SH_KEYCODE::APOSTROPHE), //Apostrophe = static_cast<int>(SHInputManager::SH_KEYCODE::APOSTROPHE),
Comma = static_cast<int>(SHInputManager::SH_KEYCODE::OEM_COMMA), Comma = static_cast<int>(SHInputManager::SH_KEYCODE::OEM_COMMA),
@ -191,6 +340,7 @@ namespace SHADE
JoystickButton7 = JoystickMenu, JoystickButton7 = JoystickMenu,
JoystickButton8 = JoystickLeftStick, JoystickButton8 = JoystickLeftStick,
JoystickButton9 = JoystickRightStick JoystickButton9 = JoystickRightStick
#endif
}; };
/// <summary> /// <summary>

View File

@ -236,6 +236,22 @@ namespace SHADE
lhs.y * rhs.y 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) Vector2 Vector2::operator*(Vector2 lhs, float rhs)
{ {
return Vector2 return Vector2

View File

@ -361,6 +361,22 @@ namespace SHADE
/// <param name="lhs">Vector2 to multiply with.</param> /// <param name="lhs">Vector2 to multiply with.</param>
/// <param name="rhs">Scalar to multiply with.</param> /// <param name="rhs">Scalar to multiply with.</param>
/// <returns>The result of the scalar multiplication.</returns> /// <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); static Vector2 operator*(Vector2 lhs, float rhs);
/// <summary> /// <summary>
/// Calculates the division of a Vector2 with a scalar value and returns /// Calculates the division of a Vector2 with a scalar value and returns

View File

@ -237,6 +237,24 @@ namespace SHADE
lhs.z * rhs.z 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) Vector3 Vector3::operator*(Vector3 lhs, float rhs)
{ {
return Vector3 return Vector3

View File

@ -375,6 +375,22 @@ namespace SHADE
/// <param name="lhs">Vector3 to multiply with.</param> /// <param name="lhs">Vector3 to multiply with.</param>
/// <param name="rhs">Scalar to multiply with.</param> /// <param name="rhs">Scalar to multiply with.</param>
/// <returns>The result of the scalar multiplication.</returns> /// <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); static Vector3 operator*(Vector3 lhs, float rhs);
/// <summary> /// <summary>
/// Calculates the division of a Vector3 with a scalar value and returns /// Calculates the division of a Vector3 with a scalar value and returns

View File

@ -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^>();
}
}

View File

@ -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();
}
};
}

View File

@ -147,6 +147,48 @@ namespace SHADE
SAFE_NATIVE_CALL_END(this) 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 */ /* Constructors */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -169,4 +211,14 @@ namespace SHADE
void Script::update() {} void Script::update() {}
void Script::lateUpdate() {} void Script::lateUpdate() {}
void Script::onDestroy() {} 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) {}
}

View File

@ -15,6 +15,7 @@ of DigiPen Institute of Technology is prohibited.
// Project Includes // Project Includes
#include "Engine/GameObject.hxx" #include "Engine/GameObject.hxx"
#include "Physics/CollisionInfo.hxx"
namespace SHADE namespace SHADE
{ {
@ -213,6 +214,46 @@ namespace SHADE
/// </summary> /// </summary>
void OnDestroy(); 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: protected:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Constructors */ /* Constructors */
@ -273,6 +314,46 @@ namespace SHADE
/// </summary> /// </summary>
virtual void onDestroy(); 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: private:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Data Members */ /* Data Members */
@ -280,4 +361,4 @@ namespace SHADE
GameObject owner; GameObject owner;
}; };
} // namespace PlushieAPI }

View File

@ -28,6 +28,8 @@ of DigiPen Institute of Technology is prohibited.
#include "Engine/Entity.hxx" #include "Engine/Entity.hxx"
#include "Serialisation/ReflectionUtilities.hxx" #include "Serialisation/ReflectionUtilities.hxx"
#include "Engine/Application.hxx" #include "Engine/Application.hxx"
#include "Physics/SHPhysicsSystemInterface.h"
#include "Physics/SHPhysicsUtils.h"
namespace SHADE namespace SHADE
{ {
@ -71,7 +73,7 @@ namespace SHADE
SAFE_NATIVE_CALL_BEGIN SAFE_NATIVE_CALL_BEGIN
Script^ script; Script^ script;
return AddScriptViaNameWithRef(entity, scriptName, script); return AddScriptViaNameWithRef(entity, scriptName, script);
SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore") SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
return false; return false;
} }
@ -301,7 +303,7 @@ namespace SHADE
removeScript(script); removeScript(script);
} }
scriptList->Clear(); scriptList->Clear();
SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore") SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
} }
void ScriptStore::RemoveAllScriptsImmediately(Entity entity, bool callOnDestroy) void ScriptStore::RemoveAllScriptsImmediately(Entity entity, bool callOnDestroy)
{ {
@ -326,7 +328,7 @@ namespace SHADE
startList.Remove(script); startList.Remove(script);
} }
scriptList->Clear(); 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); startList.AddRange(%inactiveStartList);
inactiveStartList.Clear(); inactiveStartList.Clear();
SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore") SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
} }
void ScriptStore::FrameCleanUp() void ScriptStore::FrameCleanUp()
{ {
@ -386,7 +388,7 @@ namespace SHADE
scripts.Remove(entity); scripts.Remove(entity);
} }
} }
SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore") SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
} }
void ScriptStore::Exit() void ScriptStore::Exit()
{ {
@ -410,7 +412,7 @@ namespace SHADE
startList.Clear(); startList.Clear();
disposalQueue.Clear(); disposalQueue.Clear();
scriptTypeList = nullptr; 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(); script->FixedUpdate();
} }
} }
SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore") SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
} }
void ScriptStore::ExecuteUpdate() void ScriptStore::ExecuteUpdate()
{ {
@ -456,7 +458,7 @@ namespace SHADE
script->Update(); script->Update();
} }
} }
SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore") SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
} }
void ScriptStore::ExecuteLateUpdate() void ScriptStore::ExecuteLateUpdate()
{ {
@ -473,7 +475,95 @@ namespace SHADE
script->LateUpdate(); 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) bool ScriptStore::SerialiseScripts(Entity entity, System::IntPtr yamlNodePtr)
@ -509,7 +599,7 @@ namespace SHADE
} }
return true; return true;
SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore") SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
return false; return false;
} }
@ -559,7 +649,7 @@ namespace SHADE
} }
return true; return true;
SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore") SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
return false; return false;
} }

View File

@ -233,6 +233,10 @@ namespace SHADE
/// Executes LateUpdate() for all scripts. /// Executes LateUpdate() for all scripts.
/// </summary> /// </summary>
static void ExecuteLateUpdate(); static void ExecuteLateUpdate();
/// <summary>
/// Executes OnCollision*() and OnTrigger*() for all scripts.
/// </summary>
static void ExecuteCollisionFunctions();
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Serialisation Functions */ /* Serialisation Functions */

View File

@ -40,4 +40,34 @@ public class PhysicsTest : Script
} }
Debug.Log($"{Transform.LocalPosition.y}"); 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}");
}
} }