Merge branch 'main' into SP3-6-c-scripting

# Conflicts:
#	SHADE_Managed/src/Components/Collider.hxx
This commit is contained in:
Kah Wei 2022-10-29 02:25:21 +08:00
commit dbf1b0b8de
40 changed files with 1098 additions and 229 deletions

View File

@ -84,7 +84,7 @@ namespace Sandbox
auto& collider = *SHComponentManager::GetComponent_s<SHColliderComponent>(entity); auto& collider = *SHComponentManager::GetComponent_s<SHColliderComponent>(entity);
//renderable.Mesh = handles.front(); //renderable.Mesh = handles.front();
renderable.Mesh = CUBE_MESH; renderable.SetMesh(CUBE_MESH);
renderable.SetMaterial(customMat); renderable.SetMaterial(customMat);
if (y == 50) if (y == 50)
@ -96,11 +96,7 @@ namespace Sandbox
transform.SetWorldRotation(SHMath::GenerateRandomNumber(0.0f, 360.0f), SHMath::GenerateRandomNumber(0.0f, 360.0f), SHMath::GenerateRandomNumber(0.0f, 360.0f)); transform.SetWorldRotation(SHMath::GenerateRandomNumber(0.0f, 360.0f), SHMath::GenerateRandomNumber(0.0f, 360.0f), SHMath::GenerateRandomNumber(0.0f, 360.0f));
transform.SetWorldScale(TEST_OBJ_SCALE); transform.SetWorldScale(TEST_OBJ_SCALE);
//if (const bool IS_EVEN = (y * NUM_ROWS + x) % 2; IS_EVEN) collider.AddBoundingBox(SHVec3::One, SHVec3::Zero);
collider.AddBoundingBox(SHVec3::One * 0.5f, SHVec3::Zero);
//else
// collider.AddBoundingSphere(0.5f, SHVec3::Zero);
stressTestObjects.emplace_back(entity); stressTestObjects.emplace_back(entity);
} }
@ -108,7 +104,7 @@ namespace Sandbox
auto& renderable = *SHComponentManager::GetComponent_s<SHRenderable>(raccoonSpin); auto& renderable = *SHComponentManager::GetComponent_s<SHRenderable>(raccoonSpin);
auto& transform = *SHComponentManager::GetComponent_s<SHTransformComponent>(raccoonSpin); auto& transform = *SHComponentManager::GetComponent_s<SHTransformComponent>(raccoonSpin);
renderable.Mesh = handles.front(); renderable.SetMesh(handles.front());
renderable.SetMaterial(customMat); renderable.SetMaterial(customMat);
renderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f)); renderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f));
renderable.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f); renderable.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f);
@ -123,9 +119,8 @@ namespace Sandbox
auto& floorRigidBody = *SHComponentManager::GetComponent_s<SHRigidBodyComponent>(floor); auto& floorRigidBody = *SHComponentManager::GetComponent_s<SHRigidBodyComponent>(floor);
auto& floorCollider = *SHComponentManager::GetComponent_s<SHColliderComponent>(floor); auto& floorCollider = *SHComponentManager::GetComponent_s<SHColliderComponent>(floor);
floorRenderable.Mesh = CUBE_MESH; floorRenderable.SetMesh(CUBE_MESH);
floorRenderable.SetMaterial(customMat); floorRenderable.SetMaterial(graphicsSystem->GetDefaultMaterialInstance());
floorRenderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(1.0f, 1.0f, 1.0f, 1.0f));
floorTransform.SetWorldScale({ 7.5f, 0.5f, 7.5 }); floorTransform.SetWorldScale({ 7.5f, 0.5f, 7.5 });
floorTransform.SetWorldPosition({ 0.0f, -3.0f, -5.0f }); floorTransform.SetWorldPosition({ 0.0f, -3.0f, -5.0f });
@ -149,7 +144,7 @@ namespace Sandbox
auto& renderableShowcase = *SHComponentManager::GetComponent_s<SHRenderable>(raccoonShowcase); auto& renderableShowcase = *SHComponentManager::GetComponent_s<SHRenderable>(raccoonShowcase);
auto& transformShowcase = *SHComponentManager::GetComponent_s<SHTransformComponent>(raccoonShowcase); auto& transformShowcase = *SHComponentManager::GetComponent_s<SHTransformComponent>(raccoonShowcase);
renderableShowcase.Mesh = handles.front(); renderableShowcase.SetMesh(handles.front());
renderableShowcase.SetMaterial(customMat); renderableShowcase.SetMaterial(customMat);
renderableShowcase.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f)); renderableShowcase.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f));
renderableShowcase.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f); renderableShowcase.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f);

View File

@ -207,6 +207,10 @@ namespace SHADE
{ {
if (!component) if (!component)
return; return;
// Get transform component for extrapolating relative sizes
auto* transformComponent = SHComponentManager::GetComponent<SHTransformComponent>(component->GetEID());
const auto componentType = rttr::type::get(*component); const auto componentType = rttr::type::get(*component);
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }); SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; });
ImGui::SameLine(); ImGui::SameLine();
@ -221,28 +225,41 @@ namespace SHADE
for (int i{}; i < size; ++i) for (int i{}; i < size; ++i)
{ {
ImGui::PushID(i); ImGui::PushID(i);
SHCollider& collider = component->GetCollider(i); SHCollider* collider = &component->GetCollider(i);
auto cursorPos = ImGui::GetCursorPos(); auto cursorPos = ImGui::GetCursorPos();
if (collider.GetType() == SHCollider::Type::BOX) if (collider->GetType() == SHCollider::Type::BOX)
{ {
SHEditorWidgets::BeginPanel( std::format("{} Box Collider #{}", ICON_FA_CUBE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y }); SHEditorWidgets::BeginPanel( std::format("{} Box Collider #{}", ICON_FA_CUBE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
auto box = reinterpret_cast<SHBoundingBox*>(collider.GetShape()); auto box = reinterpret_cast<SHBoundingBox*>(collider->GetShape());
SHEditorWidgets::DragVec3("Half Extents", { "X", "Y", "Z" }, [box] {return box->GetHalfExtents(); }, [box](SHVec3 const& vec) {box->SetHalfExtents(vec);}); SHEditorWidgets::DragVec3
(
"Half Extents", { "X", "Y", "Z" },
[box, transformComponent] { return (transformComponent->GetWorldScale() * 2.0f) * box->GetHalfExtents(); },
[collider](SHVec3 const& vec) { collider->SetBoundingBox(vec); });
} }
else if (collider.GetType() == SHCollider::Type::SPHERE) else if (collider->GetType() == SHCollider::Type::SPHERE)
{ {
SHEditorWidgets::BeginPanel(std::format("{} Sphere Collider #{}", ICON_MD_CIRCLE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y }); SHEditorWidgets::BeginPanel(std::format("{} Sphere Collider #{}", ICON_MD_CIRCLE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
auto sphere = reinterpret_cast<SHBoundingSphere*>(collider.GetShape()); auto sphere = reinterpret_cast<SHBoundingSphere*>(collider->GetShape());
SHEditorWidgets::DragFloat("Radius", [sphere] {return sphere->GetRadius(); }, [sphere](float const& value) {sphere->SetRadius(value);}); SHEditorWidgets::DragFloat
(
"Radius",
[sphere, transformComponent]
{
const SHVec3& TF_WORLD_SCALE = transformComponent->GetWorldScale();
const float MAX_SCALE = SHMath::Max({ TF_WORLD_SCALE.x, TF_WORLD_SCALE.y, TF_WORLD_SCALE.z });
return sphere->GetRadius() / MAX_SCALE;
},
[collider](float const& value) { collider->SetBoundingSphere(value);});
} }
else if (collider.GetType() == SHCollider::Type::CAPSULE) else if (collider->GetType() == SHCollider::Type::CAPSULE)
{ {
} }
{ {
SHEditorWidgets::BeginPanel("Offset", { ImGui::GetContentRegionAvail().x, 30.0f }); SHEditorWidgets::BeginPanel("Offset", { ImGui::GetContentRegionAvail().x, 30.0f });
SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [&collider] {return collider.GetPositionOffset(); }, [&collider](SHVec3 const& vec) {collider.SetPositionOffset(vec); }); SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [&collider] {return collider->GetPositionOffset(); }, [&collider](SHVec3 const& vec) {collider->SetPositionOffset(vec); });
SHEditorWidgets::EndPanel(); SHEditorWidgets::EndPanel();
} }
if(ImGui::Button(std::format("{} Remove Collider #{}", ICON_MD_REMOVE, i).data())) if(ImGui::Button(std::format("{} Remove Collider #{}", ICON_MD_REMOVE, i).data()))

View File

@ -45,16 +45,20 @@ namespace SHADE
void SHBatch::Add(const SHRenderable* renderable) void SHBatch::Add(const SHRenderable* renderable)
{ {
// Ignore if null
if (!renderable->GetMesh())
return;
// Check if we have a SubBatch with the same mesh yet // Check if we have a SubBatch with the same mesh yet
auto subBatch = std::find_if(subBatches.begin(), subBatches.end(), [&](const SHSubBatch& batch) auto subBatch = std::find_if(subBatches.begin(), subBatches.end(), [&](const SHSubBatch& batch)
{ {
return batch.Mesh == renderable->Mesh; return batch.Mesh == renderable->GetMesh();
}); });
// Create one if not found // Create one if not found
if (subBatch == subBatches.end()) if (subBatch == subBatches.end())
{ {
subBatches.emplace_back(renderable->Mesh); subBatches.emplace_back(renderable->GetMesh());
subBatch = subBatches.end() - 1; subBatch = subBatches.end() - 1;
} }
@ -73,7 +77,7 @@ namespace SHADE
// Check if we have a SubBatch with the same mesh yet // Check if we have a SubBatch with the same mesh yet
auto subBatch = std::find_if(subBatches.begin(), subBatches.end(), [&](const SHSubBatch& batch) auto subBatch = std::find_if(subBatches.begin(), subBatches.end(), [&](const SHSubBatch& batch)
{ {
return batch.Mesh == renderable->Mesh; return batch.Mesh == renderable->GetMesh();
}); });
// Attempt to remove if it exists // Attempt to remove if it exists
@ -84,13 +88,18 @@ namespace SHADE
// Check if other renderables in subBatches contain the same material instance // Check if other renderables in subBatches contain the same material instance
bool matUnused = true; bool matUnused = true;
Handle<SHMaterialInstance> matToCheck = renderable->HasMaterialChanged() ? renderable->GetPrevMaterial() : renderable->GetMaterial();
for (const auto& sb : subBatches) for (const auto& sb : subBatches)
{
// Check material usage
for (const auto& rendId : sb.Renderables) for (const auto& rendId : sb.Renderables)
{ {
auto rend = SHComponentManager::GetComponent<SHRenderable>(rendId); auto rend = SHComponentManager::GetComponent<SHRenderable>(rendId);
if (rend) if (rend)
{ {
if (rend->GetMaterial() == renderable->GetMaterial()) if (rend->GetMaterial() == matToCheck)
{ {
matUnused = false; matUnused = false;
break; break;
@ -101,10 +110,15 @@ namespace SHADE
SHLOG_WARNING("[SHBatch] Entity with a missing SHRenderable found!"); SHLOG_WARNING("[SHBatch] Entity with a missing SHRenderable found!");
} }
} }
}
// Material is no longer in this library, so we remove it // Material is no longer in this library, so we remove it
if (matUnused) if (matUnused)
referencedMatInstances.erase(renderable->WasMaterialChanged() ? renderable->GetPrevMaterial() : renderable->GetMaterial()); referencedMatInstances.erase(renderable->HasChanged() ? renderable->GetPrevMaterial() : renderable->GetMaterial());
// Mesh is no longer in this batch, so we remove the associated sub batch
if (subBatch->Renderables.empty())
subBatches.erase(subBatch);
// Mark all as dirty // Mark all as dirty
setAllDirtyFlags(); setAllDirtyFlags();

View File

@ -200,7 +200,6 @@ namespace SHADE
auto cubeFS = shaderModuleLibrary.GetBuiltInShaderModule("TestCube_FS"); auto cubeFS = shaderModuleLibrary.GetBuiltInShaderModule("TestCube_FS");
defaultMaterial = AddMaterial(cubeVS, cubeFS, gBufferSubpass); defaultMaterial = AddMaterial(cubeVS, cubeFS, gBufferSubpass);
} }
void SHGraphicsSystem::InitMiddleEnd(void) noexcept void SHGraphicsSystem::InitMiddleEnd(void) noexcept
@ -680,7 +679,7 @@ namespace SHADE
auto& renderables = SHComponentManager::GetDense<SHRenderable>(); auto& renderables = SHComponentManager::GetDense<SHRenderable>();
for (auto& renderable : renderables) for (auto& renderable : renderables)
{ {
if (!renderable.WasMaterialChanged()) if (!renderable.HasChanged())
continue; continue;
// Remove from old material's SuperBatch // Remove from old material's SuperBatch
@ -768,5 +767,10 @@ namespace SHADE
} }
Handle<SHRenderGraphNode> SHGraphicsSystem::GetPrimaryRenderpass() const noexcept
{
return worldRenderGraph->GetNode(G_BUFFER_RENDER_GRAPH_NODE_NAME.data());
}
#pragma endregion MISC #pragma endregion MISC
} }

View File

@ -135,7 +135,7 @@ namespace SHADE
void RemoveViewport(Handle<SHViewport> viewport); void RemoveViewport(Handle<SHViewport> viewport);
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Material Creation Functions */ /* Material Functions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
Handle<SHMaterial> AddMaterial(Handle<SHVkShaderModule> vertShader, Handle<SHVkShaderModule> fragShader, Handle<SHSubpass> subpass); Handle<SHMaterial> AddMaterial(Handle<SHVkShaderModule> vertShader, Handle<SHVkShaderModule> fragShader, Handle<SHSubpass> subpass);
void RemoveMaterial(Handle<SHMaterial> material); void RemoveMaterial(Handle<SHMaterial> material);
@ -143,6 +143,8 @@ namespace SHADE
Handle<SHMaterialInstance> AddOrGetBaseMaterialInstance(Handle<SHMaterial> material); Handle<SHMaterialInstance> AddOrGetBaseMaterialInstance(Handle<SHMaterial> material);
Handle<SHMaterialInstance> AddMaterialInstanceCopy(Handle<SHMaterialInstance> materialInst); Handle<SHMaterialInstance> AddMaterialInstanceCopy(Handle<SHMaterialInstance> materialInst);
void RemoveMaterialInstance(Handle<SHMaterialInstance> materialInstance); void RemoveMaterialInstance(Handle<SHMaterialInstance> materialInstance);
Handle<SHMaterial> GetDefaultMaterial() { return defaultMaterial; }
Handle<SHMaterialInstance> GetDefaultMaterialInstance() { return AddOrGetBaseMaterialInstance(defaultMaterial); }
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Mesh Registration Functions */ /* Mesh Registration Functions */
@ -286,12 +288,17 @@ namespace SHADE
#endif #endif
Handle<SHMousePickSystem> GetMousePickSystem(void) const noexcept {return mousePickSystem;}; Handle<SHMousePickSystem> GetMousePickSystem(void) const noexcept {return mousePickSystem;};
Handle<SHPostOffscreenRenderSystem> GetPostOffscreenRenderSystem(void) const noexcept {return postOffscreenRender;}; Handle<SHPostOffscreenRenderSystem> GetPostOffscreenRenderSystem(void) const noexcept {return postOffscreenRender;};
Handle<SHRenderGraphNode> GetPrimaryRenderpass() const noexcept;
//SHRenderGraph const& GetRenderGraph(void) const noexcept; //SHRenderGraph const& GetRenderGraph(void) const noexcept;
//Handle<SHVkRenderpass> GetRenderPass() const { return renderPass; } //Handle<SHVkRenderpass> GetRenderPass() const { return renderPass; }
private: private:
/*-----------------------------------------------------------------------------*/
/* Constants */
/*-----------------------------------------------------------------------------*/
static constexpr std::string_view G_BUFFER_RENDER_GRAPH_NODE_NAME = "G-Buffer";
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Data Members */ /* Data Members */
@ -318,7 +325,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;
Handle<SHRenderer> editorRenderer; Handle<SHRenderer> editorRenderer;

View File

@ -4,6 +4,8 @@
#include "Graphics/Pipeline/SHVkPipeline.h" #include "Graphics/Pipeline/SHVkPipeline.h"
#include "SHGraphicsConstants.h" #include "SHGraphicsConstants.h"
#include "Graphics/Shaders/BlockInterface/SHShaderBlockInterface.h" #include "Graphics/Shaders/BlockInterface/SHShaderBlockInterface.h"
#include "Math/Vector/SHVec3.h"
#include "Math/Vector/SHVec4.h"
namespace SHADE namespace SHADE
{ {
@ -23,7 +25,7 @@ namespace SHADE
} }
// Allocate memory for properties // Allocate memory for properties
const Handle<SHShaderBlockInterface> SHADER_INFO = getShaderBlockInterface(); const Handle<SHShaderBlockInterface> SHADER_INFO = GetShaderBlockInterface();
propMemorySize = SHADER_INFO ? SHADER_INFO->GetBytesRequired() : 0; propMemorySize = SHADER_INFO ? SHADER_INFO->GetBytesRequired() : 0;
if (propMemorySize <= 0) if (propMemorySize <= 0)
{ {
@ -49,6 +51,22 @@ namespace SHADE
// Reset all the properties to default values // Reset all the properties to default values
if (propMemory) if (propMemory)
memset(propMemory.get(), 0, propMemorySize); memset(propMemory.get(), 0, propMemorySize);
// Initialize Vectors to all 1.0 by default
const Handle<SHShaderBlockInterface> SHADER_INFO = GetShaderBlockInterface();
for (int i = 0; i < SHADER_INFO->GetVariableCount(); ++i)
{
const auto& VAR = SHADER_INFO->GetVariable(i);
switch (VAR->type)
{
case SHShaderBlockInterface::Variable::Type::VECTOR3:
setPropertyUnsafe(VAR->offset, SHVec3::One);
break;
case SHShaderBlockInterface::Variable::Type::VECTOR4:
setPropertyUnsafe(VAR->offset, SHVec4::One);
break;
}
}
} }
void SHMaterial::ExportProperties(void* dest) const noexcept void SHMaterial::ExportProperties(void* dest) const noexcept
@ -59,14 +77,14 @@ namespace SHADE
size_t SHMaterial::GetPropertiesMemorySize() const noexcept size_t SHMaterial::GetPropertiesMemorySize() const noexcept
{ {
const Handle<SHShaderBlockInterface> SHADER_INFO = getShaderBlockInterface(); const Handle<SHShaderBlockInterface> SHADER_INFO = GetShaderBlockInterface();
return SHADER_INFO ? SHADER_INFO->GetBytesRequired() : 0; return SHADER_INFO ? SHADER_INFO->GetBytesRequired() : 0;
} }
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Helper Functions */ /* Helper Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
Handle<SHShaderBlockInterface> SHMaterial::getShaderBlockInterface() const noexcept Handle<SHShaderBlockInterface> SHMaterial::GetShaderBlockInterface() const noexcept
{ {
return pipeline->GetPipelineLayout()->GetShaderBlockInterface return pipeline->GetPipelineLayout()->GetShaderBlockInterface
( (

View File

@ -50,13 +50,24 @@ namespace SHADE
template<typename T> template<typename T>
void SetProperty(const std::string& key, const T& value); void SetProperty(const std::string& key, const T& value);
template<typename T> template<typename T>
void SetProperty(uint32_t memOffset, const T& value);
template<typename T>
T& GetProperty(const std::string& key); T& GetProperty(const std::string& key);
template<typename T> template<typename T>
const T& GetProperty(const std::string& key) const; const T& GetProperty(const std::string& key) const;
template<typename T>
T& GetProperty(uint32_t memOffset);
template<typename T>
const T& GetProperty(uint32_t memOffset) const;
void ResetProperties(); void ResetProperties();
void ExportProperties(void* dest) const noexcept; void ExportProperties(void* dest) const noexcept;
Byte GetPropertiesMemorySize() const noexcept; Byte GetPropertiesMemorySize() const noexcept;
/*-----------------------------------------------------------------------------*/
/* Query Functions */
/*-----------------------------------------------------------------------------*/
Handle<SHShaderBlockInterface> GetShaderBlockInterface() const noexcept;
private: private:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Data Members */ /* Data Members */
@ -68,7 +79,8 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Helper Functions */ /* Helper Functions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
Handle<SHShaderBlockInterface> getShaderBlockInterface() const noexcept; template<typename T>
inline void setPropertyUnsafe(uint32_t memOffset, const T& value); // SetProperty() but without checks
}; };
} }

View File

@ -25,7 +25,7 @@ namespace SHADE
template<typename T> template<typename T>
void SHMaterial::SetProperty(const std::string& key, const T& value) void SHMaterial::SetProperty(const std::string& key, const T& value)
{ {
const auto SHADER_INFO = getShaderBlockInterface(); const auto SHADER_INFO = GetShaderBlockInterface();
const auto PROP_INFO = SHADER_INFO->GetVariable(key); const auto PROP_INFO = SHADER_INFO->GetVariable(key);
if (PROP_INFO == nullptr) if (PROP_INFO == nullptr)
{ {
@ -36,14 +36,25 @@ namespace SHADE
T* dataPtr = reinterpret_cast<T*>(propMemory.get() + PROP_INFO->offset); T* dataPtr = reinterpret_cast<T*>(propMemory.get() + PROP_INFO->offset);
*dataPtr = value; *dataPtr = value;
} }
template<typename T>
void SHMaterial::SetProperty(uint32_t memOffset, const T& value)
{
// Check if out of bounds
if (memOffset + sizeof(T) > propMemorySize)
throw std::invalid_argument("Attempted to set an invalid property!");
// Set
setPropertyUnsafe(memOffset, value);
}
template<typename T> template<typename T>
T& SHMaterial::GetProperty(const std::string& key) T& SHMaterial::GetProperty(const std::string& key)
{ {
const auto SHADER_INFO = getShaderBlockInterface(); const auto SHADER_INFO = GetShaderBlockInterface();
const auto PROP_INFO = SHADER_INFO->GetVariable(key); const auto PROP_INFO = SHADER_INFO->GetVariable(key);
if (PROP_INFO == nullptr) if (PROP_INFO == nullptr)
{ {
throw std::invalid_argument("Attempted to set an invalid property!"); throw std::invalid_argument("Attempted to retrieve an invalid property!");
} }
// Get offset and return the memory directly // Get offset and return the memory directly
@ -55,5 +66,25 @@ namespace SHADE
{ {
return const_cast<const T&>(const_cast<SHMaterial*>(this)->GetProperty(key)); return const_cast<const T&>(const_cast<SHMaterial*>(this)->GetProperty(key));
} }
template<typename T>
const T& SHMaterial::GetProperty(uint32_t memOffset) const
{
// Check if out of bounds
if (memOffset + sizeof(T) > propMemorySize)
throw std::invalid_argument("Attempted to retrieve an invalid property!");
return *(reinterpret_cast<T*>(propMemory.get() + memOffset));
}
template<typename T>
T& SHMaterial::GetProperty(uint32_t memOffset)
{
return const_cast<const T&>(const_cast<SHMaterial*>(this)->GetProperty(memOffset));
}
template<typename T>
void SHMaterial::setPropertyUnsafe(uint32_t memOffset, const T& value)
{
(*reinterpret_cast<T*>(propMemory.get() + memOffset)) = value;
}
} }

View File

@ -23,7 +23,7 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void SHRenderable::OnCreate() void SHRenderable::OnCreate()
{ {
materialChanged = true; matChanged = true;
sharedMaterial = {}; sharedMaterial = {};
material = {}; material = {};
oldMaterial = {}; oldMaterial = {};
@ -55,7 +55,7 @@ namespace SHADE
return; return;
// Flag that material was changed // Flag that material was changed
materialChanged = true; matChanged = true;
// Free copies of materials if any // Free copies of materials if any
if (material) if (material)
@ -92,15 +92,41 @@ namespace SHADE
return material; return material;
} }
/*-----------------------------------------------------------------------------------*/
/* Mesh Functions */
/*-----------------------------------------------------------------------------------*/
void SHRenderable::SetMesh(Handle<SHMesh> newMesh)
{
oldMesh = mesh;
mesh = newMesh;
meshChanged = true;
}
/*-----------------------------------------------------------------------------------*/
/* Light Functions */
/*-----------------------------------------------------------------------------------*/
uint8_t SHRenderable::GetLightLayer(void) const noexcept uint8_t SHRenderable::GetLightLayer(void) const noexcept
{ {
return lightLayer; return lightLayer;
} }
/*-----------------------------------------------------------------------------------*/
/* Batcher Dispatcher Functions */
/*-----------------------------------------------------------------------------------*/
void SHRenderable::ResetChangedFlag() void SHRenderable::ResetChangedFlag()
{ {
materialChanged = false; matChanged = false;
oldMaterial = {}; meshChanged = false;
oldMaterial = {};
oldMesh = {};
} }
} }
RTTR_REGISTRATION
{
using namespace SHADE;
using namespace rttr;
registration::class_<SHRenderable>("Renderable Component");
}

View File

@ -11,9 +11,10 @@ of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/ *//*************************************************************************************/
#pragma once #pragma once
// External Dependencies
#include <rttr/registration>
// Project Includes // Project Includes
#include "Resource/SHHandle.h" #include "Resource/SHHandle.h"
//#include "SHTransform.h"
#include "ECS_Base/Components/SHComponent.h" #include "ECS_Base/Components/SHComponent.h"
#include "Math/SHMatrix.h" #include "Math/SHMatrix.h"
#include "SH_API.h" #include "SH_API.h"
@ -50,33 +51,42 @@ namespace SHADE
void SetMaterial(Handle<SHMaterialInstance> materialInstance); void SetMaterial(Handle<SHMaterialInstance> materialInstance);
Handle<SHMaterialInstance> GetMaterial() const; Handle<SHMaterialInstance> GetMaterial() const;
Handle<SHMaterialInstance> GetModifiableMaterial(); Handle<SHMaterialInstance> GetModifiableMaterial();
Handle<SHMaterialInstance> GetPrevMaterial() const noexcept { return oldMaterial; }
bool HasMaterialChanged() const noexcept { return matChanged; }
/*-------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------*/
/* Getter Functions */ /* Mesh Functions */
/*-------------------------------------------------------------------------------*/
void SetMesh(Handle<SHMesh> newMesh);
Handle<SHMesh> GetMesh() const noexcept { return mesh; }
Handle<SHMesh> GetPrevMesh() const noexcept { return oldMesh; }
bool HasMeshChanged() const noexcept { return meshChanged; }
/*-------------------------------------------------------------------------------*/
/* Light Functions */
/*-------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------*/
bool WasMaterialChanged() const noexcept { return materialChanged; }
Handle<SHMaterialInstance> GetPrevMaterial() const noexcept { return oldMaterial; }
uint8_t GetLightLayer (void) const noexcept; uint8_t GetLightLayer (void) const noexcept;
/*-------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------*/
/* Batcher Dispatcher Functions */ /* Batcher Dispatcher Functions */
/*-------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------*/
bool HasChanged() const noexcept { return matChanged || meshChanged; } // Whether or not the mesh or material has changed
void ResetChangedFlag(); // TODO: Lock it so that only SHBatcherDispatcher can access this void ResetChangedFlag(); // TODO: Lock it so that only SHBatcherDispatcher can access this
/*-------------------------------------------------------------------------------*/
/* Data Members */
/*-------------------------------------------------------------------------------*/
Handle<SHMesh> Mesh;
private: private:
/*-------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------*/
/* Data Members */ /* Data Members */
/*-------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------*/
Handle<SHMesh> mesh;
Handle<SHMesh> oldMesh;
bool meshChanged = true;
Handle<SHMaterialInstance> sharedMaterial; Handle<SHMaterialInstance> sharedMaterial;
Handle<SHMaterialInstance> material; Handle<SHMaterialInstance> material;
bool materialChanged = true; bool matChanged = true;
Handle<SHMaterialInstance> oldMaterial; Handle<SHMaterialInstance> oldMaterial;
uint8_t lightLayer; uint8_t lightLayer;
RTTR_ENABLE()
}; };
} }

View File

@ -244,7 +244,15 @@ namespace SHADE
} }
// Add subpass to container and create mapping for it // Add subpass to container and create mapping for it
subpasses.emplace_back(graphStorage->resourceManager->Create<SHSubpass>(graphStorage, GetHandle(), static_cast<uint32_t>(subpasses.size()), &resourceAttachmentMapping)); subpasses.emplace_back
(
graphStorage->resourceManager->Create<SHSubpass>
(
subpassName,
graphStorage, GetHandle(), static_cast<uint32_t>(subpasses.size()),
&resourceAttachmentMapping
)
);
subpassIndexing.try_emplace(subpassName, static_cast<uint32_t>(subpasses.size()) - 1u); subpassIndexing.try_emplace(subpassName, static_cast<uint32_t>(subpasses.size()) - 1u);
Handle<SHSubpass> subpass = subpasses.back(); Handle<SHSubpass> subpass = subpasses.back();
subpass->Init(*graphStorage->resourceManager); subpass->Init(*graphStorage->resourceManager);

View File

@ -30,7 +30,7 @@ namespace SHADE
*/ */
/***************************************************************************/ /***************************************************************************/
SHSubpass::SHSubpass(Handle<SHRenderGraphStorage> renderGraphStorage, Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping) noexcept SHSubpass::SHSubpass(const std::string& name, Handle<SHRenderGraphStorage> renderGraphStorage, Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping) noexcept
: resourceAttachmentMapping{ mapping } : resourceAttachmentMapping{ mapping }
, parentNode{ parent } , parentNode{ parent }
, subpassIndex{ index } , subpassIndex{ index }
@ -38,6 +38,7 @@ namespace SHADE
, colorReferences{} , colorReferences{}
, depthReferences{} , depthReferences{}
, inputReferences{} , inputReferences{}
, name { name }
, graphStorage{ renderGraphStorage } , graphStorage{ renderGraphStorage }
, inputImageDescriptors {SHGraphicsConstants::NUM_FRAME_BUFFERS} , inputImageDescriptors {SHGraphicsConstants::NUM_FRAME_BUFFERS}
{ {
@ -411,4 +412,8 @@ namespace SHADE
return parentNode->GetResource(attachmentReference)->GetResourceFormat(); return parentNode->GetResource(attachmentReference)->GetResourceFormat();
} }
const std::string& SHSubpass::GetName() const
{
return name;
}
} }

View File

@ -77,13 +77,15 @@ namespace SHADE
//! are always the last things drawn, so DO NOT USE THIS FUNCTIONALITY FOR ANYTHING //! are always the last things drawn, so DO NOT USE THIS FUNCTIONALITY FOR ANYTHING
//! COMPLEX. //! COMPLEX.
std::vector<std::function<void(Handle<SHVkCommandBuffer>&)>> exteriorDrawCalls; std::vector<std::function<void(Handle<SHVkCommandBuffer>&)>> exteriorDrawCalls;
/// For identifying subpasses
std::string name;
public: public:
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* CTORS AND DTORS */ /* CTORS AND DTORS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
SHSubpass(Handle<SHRenderGraphStorage> renderGraphStorage, Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping) noexcept; SHSubpass(const std::string& name, Handle<SHRenderGraphStorage> renderGraphStorage, Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping) noexcept;
SHSubpass(SHSubpass&& rhs) noexcept; SHSubpass(SHSubpass&& rhs) noexcept;
SHSubpass& operator=(SHSubpass&& rhs) noexcept; SHSubpass& operator=(SHSubpass&& rhs) noexcept;
@ -117,6 +119,7 @@ namespace SHADE
Handle<SHSuperBatch> GetSuperBatch(void) const noexcept; Handle<SHSuperBatch> GetSuperBatch(void) const noexcept;
std::vector<vk::AttachmentReference> const& GetColorAttachmentReferences (void) const noexcept; std::vector<vk::AttachmentReference> const& GetColorAttachmentReferences (void) const noexcept;
vk::Format GetFormatFromAttachmentReference (uint32_t attachmentReference) const noexcept; vk::Format GetFormatFromAttachmentReference (uint32_t attachmentReference) const noexcept;
const std::string& GetName() const;
friend class SHRenderGraphNode; friend class SHRenderGraphNode;
friend class SHRenderGraph; friend class SHRenderGraph;

View File

@ -14,6 +14,7 @@ namespace SHADE
return; return;
} }
variables.emplace_back(std::move(newVariable)); variables.emplace_back(std::move(newVariable));
variableNames.emplace_back(name);
variableIndexing.try_emplace(std::move(name), static_cast<uint32_t>(variables.size() - 1)); variableIndexing.try_emplace(std::move(name), static_cast<uint32_t>(variables.size() - 1));
} }
@ -41,6 +42,19 @@ namespace SHADE
return variableIndexing.at(variableName); return variableIndexing.at(variableName);
} }
const std::string& SHShaderBlockInterface::GetVariableName(uint32_t index) const noexcept
{
if (index < variableNames.size())
return variableNames.at(index);
return {};
}
size_t SHShaderBlockInterface::GetVariableCount() const noexcept
{
return variables.size();
}
SHShaderBlockInterface::SHShaderBlockInterface(void) noexcept SHShaderBlockInterface::SHShaderBlockInterface(void) noexcept
: bytesRequired{ 0 } : bytesRequired{ 0 }
{} {}

View File

@ -12,13 +12,24 @@ namespace SHADE
public: public:
struct Variable struct Variable
{ {
enum class Type
{
OTHER,
FLOAT,
INT,
VECTOR2,
VECTOR3,
VECTOR4
};
//! Offset of the variable in the block //! Offset of the variable in the block
uint32_t offset; uint32_t offset;
Type type;
}; };
private: private:
//! containers of variable information //! containers of variable information
std::vector<Variable> variables; std::vector<Variable> variables;
std::vector<std::string> variableNames;
std::unordered_map<std::string, uint32_t> variableIndexing; std::unordered_map<std::string, uint32_t> variableIndexing;
//! bytes required by the block (includes padding). This variable is required //! bytes required by the block (includes padding). This variable is required
@ -29,6 +40,8 @@ namespace SHADE
Variable const* const GetVariable (std::string const& variableName) const noexcept; Variable const* const GetVariable (std::string const& variableName) const noexcept;
Variable const* const GetVariable(uint32_t index) const noexcept; Variable const* const GetVariable(uint32_t index) const noexcept;
uint32_t GetVariableIndex(std::string const& variableName) const; uint32_t GetVariableIndex(std::string const& variableName) const;
const std::string& GetVariableName(uint32_t index) const noexcept;
size_t GetVariableCount() const noexcept;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* CTORS AND DTORS */ /* CTORS AND DTORS */

View File

@ -97,17 +97,45 @@ namespace SHADE
switch (member.type_description->op) switch (member.type_description->op)
{ {
case SpvOp::SpvOpTypeFloat: case SpvOp::SpvOpTypeFloat:
interfaceHdl->AddVariable(parentVarName + std::string(member.name), SHShaderBlockInterface::Variable(parentOffset + member.offset)); interfaceHdl->AddVariable
(
parentVarName + std::string(member.name),
SHShaderBlockInterface::Variable
(
parentOffset + member.offset,
SHShaderBlockInterface::Variable::Type::FLOAT
)
);
biggestAlignment = std::max (biggestAlignment, 4u); biggestAlignment = std::max (biggestAlignment, 4u);
break; break;
case SpvOp::SpvOpTypeVector: case SpvOp::SpvOpTypeVector:
interfaceHdl->AddVariable(parentVarName + std::string(member.name), SHShaderBlockInterface::Variable(parentOffset + member.offset)); SHShaderBlockInterface::Variable::Type varType;
switch (dim)
{
case 2: varType = SHShaderBlockInterface::Variable::Type::VECTOR2; break;
case 3: varType = SHShaderBlockInterface::Variable::Type::VECTOR3; break;
case 4: varType = SHShaderBlockInterface::Variable::Type::VECTOR4; break;
default: varType = SHShaderBlockInterface::Variable::Type::OTHER; break;
}
interfaceHdl->AddVariable
(
parentVarName + std::string(member.name),
SHShaderBlockInterface::Variable(parentOffset + member.offset, varType)
);
if (dim == 3) if (dim == 3)
dim = 4; dim = 4;
biggestAlignment = std::max (biggestAlignment, dim * member.type_description->traits.numeric.scalar.width / 8); biggestAlignment = std::max (biggestAlignment, dim * member.type_description->traits.numeric.scalar.width / 8);
break; break;
case SpvOp::SpvOpTypeInt: case SpvOp::SpvOpTypeInt:
interfaceHdl->AddVariable(parentVarName + std::string(member.name), SHShaderBlockInterface::Variable(parentOffset + member.offset)); interfaceHdl->AddVariable
(
parentVarName + std::string(member.name),
SHShaderBlockInterface::Variable
(
parentOffset + member.offset,
SHShaderBlockInterface::Variable::Type::INT
)
);
biggestAlignment = std::max(biggestAlignment, 4u); biggestAlignment = std::max(biggestAlignment, 4u);
break; break;
case SpvOp::SpvOpTypeStruct: case SpvOp::SpvOpTypeStruct:

View File

@ -27,10 +27,9 @@ namespace SHADE
/* Getter Function Definitions */ /* Getter Function Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHShape::Type SHShape::GetType() const SHShape::Type SHShape::GetType() const noexcept
{ {
return type; return type;
} }
} // namespace SHADE } // namespace SHADE

View File

@ -63,7 +63,7 @@ namespace SHADE
/* Getter Functions */ /* Getter Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
[[nodiscard]] Type GetType() const; [[nodiscard]] Type GetType () const noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Function Members */ /* Function Members */
@ -77,6 +77,6 @@ namespace SHADE
/* Data Members */ /* Data Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
Type type; Type type;
}; };
} // namespace SHADE } // namespace SHADE

View File

@ -58,7 +58,7 @@ namespace SHADE
if (index < 0 || static_cast<size_t>(index) >= colliders.size()) if (index < 0 || static_cast<size_t>(index) >= colliders.size())
throw std::invalid_argument("Out-of-range access!"); throw std::invalid_argument("Out-of-range access!");
return colliders[index].first; return colliders[index];
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -85,13 +85,11 @@ namespace SHADE
static constexpr auto TYPE = SHCollider::Type::BOX; static constexpr auto TYPE = SHCollider::Type::BOX;
auto boxPair = std::make_pair(SHCollider{ TYPE }, true); auto& collider = colliders.emplace_back(SHCollider{ GetEID(), TYPE });
auto& collider = colliders.emplace_back(boxPair).first;
const auto* tf = SHComponentManager::GetComponent<SHTransformComponent>(GetEID());
collider.entityID = GetEID();
collider.SetPositionOffset(posOffset); collider.SetPositionOffset(posOffset);
collider.SetAsBoundingBox(tf->GetWorldScale() * halfExtents); collider.SetBoundingBox(halfExtents);
// Notify Physics System // Notify Physics System
system->AddCollisionShape(GetEID(), &collider); system->AddCollisionShape(GetEID(), &collider);
@ -109,16 +107,11 @@ namespace SHADE
static constexpr auto TYPE = SHCollider::Type::SPHERE; static constexpr auto TYPE = SHCollider::Type::SPHERE;
auto spherePair = std::make_pair(SHCollider{ TYPE }, true); auto& collider = colliders.emplace_back(SHCollider{ GetEID(), TYPE });
auto& collider = colliders.emplace_back(spherePair).first;
const auto* tf = SHComponentManager::GetComponent<SHTransformComponent>(GetEID());
collider.entityID = GetEID();
collider.SetPositionOffset(posOffset); collider.SetPositionOffset(posOffset);
collider.SetBoundingSphere(radius);
const SHVec3 TF_WORLD_SCALE = tf->GetWorldScale();
const float MAX_SCALE = SHMath::Max({ TF_WORLD_SCALE.x, TF_WORLD_SCALE.y, TF_WORLD_SCALE.z });
collider.SetAsBoundingSphere(MAX_SCALE * 0.5f * radius);
// Notify Physics System // Notify Physics System
system->AddCollisionShape(GetEID(), &collider); system->AddCollisionShape(GetEID(), &collider);

View File

@ -43,8 +43,7 @@ namespace SHADE
/* Type Definitions */ /* Type Definitions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
using ColliderDirtyPair = std::pair<SHCollider, bool>; using Colliders = std::vector<SHCollider>;
using Colliders = std::vector<ColliderDirtyPair>;
public: public:

View File

@ -15,6 +15,8 @@
// Project Headers // Project Headers
#include "Math/Geometry/SHBoundingBox.h" #include "Math/Geometry/SHBoundingBox.h"
#include "Math/Geometry/SHBoundingSphere.h" #include "Math/Geometry/SHBoundingSphere.h"
#include "Math/Transform/SHTransformComponent.h"
#include "Math/SHMathHelpers.h"
namespace SHADE namespace SHADE
{ {
@ -22,22 +24,24 @@ namespace SHADE
/* Constructors & Destructor Definitions */ /* Constructors & Destructor Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHCollider::SHCollider(Type colliderType) SHCollider::SHCollider(EntityID eid, Type colliderType, const SHPhysicsMaterial& physicsMaterial)
: type { colliderType } : type { colliderType }
, entityID { eid }
, isTrigger { false } , isTrigger { false }
, dirty { true } , dirty { true }
, shape { nullptr } , shape { nullptr }
, material { physicsMaterial }
{ {
switch (type) switch (type)
{ {
case Type::BOX: case Type::BOX:
{ {
SetAsBoundingBox(SHVec3::One); shape = new SHBoundingBox{ SHVec3::Zero, SHVec3::One };
break; break;
} }
case Type::SPHERE: case Type::SPHERE:
{ {
SetAsBoundingSphere(1.0f); shape = new SHBoundingSphere{ SHVec3::Zero, 0.5f };
break; break;
} }
default: break; default: break;
@ -46,19 +50,27 @@ namespace SHADE
SHCollider::SHCollider(const SHCollider& rhs) noexcept SHCollider::SHCollider(const SHCollider& rhs) noexcept
: type { rhs.type} : type { rhs.type}
, entityID { rhs.entityID }
, isTrigger { rhs.isTrigger } , isTrigger { rhs.isTrigger }
, dirty { true } , dirty { true }
, shape { rhs.shape } , shape { nullptr }
, material { rhs.material }
, positionOffset { rhs.positionOffset } , positionOffset { rhs.positionOffset }
{} {
CopyShape(rhs.shape);
}
SHCollider::SHCollider(SHCollider&& rhs) noexcept SHCollider::SHCollider(SHCollider&& rhs) noexcept
: type { rhs.type} : type { rhs.type}
, entityID { rhs.entityID }
, isTrigger { rhs.isTrigger } , isTrigger { rhs.isTrigger }
, dirty { true } , dirty { true }
, shape { rhs.shape } , shape { nullptr }
, material { rhs.material }
, positionOffset { rhs.positionOffset } , positionOffset { rhs.positionOffset }
{} {
CopyShape(rhs.shape);
}
SHCollider::~SHCollider() noexcept SHCollider::~SHCollider() noexcept
{ {
@ -75,22 +87,30 @@ namespace SHADE
return *this; return *this;
type = rhs.type; type = rhs.type;
entityID = rhs.entityID;
isTrigger = rhs.isTrigger; isTrigger = rhs.isTrigger;
dirty = true; dirty = true;
shape = rhs.shape; material = rhs.material;
positionOffset = rhs.positionOffset; positionOffset = rhs.positionOffset;
delete shape;
CopyShape(rhs.shape);
return *this; return *this;
} }
SHCollider& SHCollider::operator=(SHCollider&& rhs) noexcept SHCollider& SHCollider::operator=(SHCollider&& rhs) noexcept
{ {
type = rhs.type; type = rhs.type;
entityID = rhs.entityID;
isTrigger = rhs.isTrigger; isTrigger = rhs.isTrigger;
dirty = true; dirty = true;
shape = rhs.shape; material = rhs.material;
positionOffset = rhs.positionOffset; positionOffset = rhs.positionOffset;
delete shape;
CopyShape(rhs.shape);
return *this; return *this;
} }
@ -115,19 +135,22 @@ namespace SHADE
float SHCollider::GetFriction() const noexcept float SHCollider::GetFriction() const noexcept
{ {
// TODO(Diren): Fix after implementing materials return material.GetFriction();
return 0.0f;
} }
float SHCollider::GetBounciness() const noexcept float SHCollider::GetBounciness() const noexcept
{ {
// TODO(Diren): Fix after implementing materials return material.GetBounciness();
return 0.0f;
} }
float SHCollider::GetDensity() const noexcept float SHCollider::GetDensity() const noexcept
{ {
// TODO(Diren): Fix after implementing materials return material.GetDensity();
return 0.0f; }
const SHPhysicsMaterial& SHCollider::GetMaterial() const noexcept
{
return material;
} }
const SHVec3& SHCollider::GetPositionOffset() const noexcept const SHVec3& SHCollider::GetPositionOffset() const noexcept
@ -145,22 +168,60 @@ namespace SHADE
/* Setter Function Definitions */ /* Setter Function Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void SHCollider::SetAsBoundingBox(const SHVec3& halfExtents) void SHCollider::SetBoundingBox(const SHVec3& halfExtents)
{ {
dirty = true; dirty = true;
type = Type::BOX;
delete shape; // Set the half extents relative to transform
shape = new SHBoundingBox{ positionOffset, halfExtents }; SHVec3 worldHalfExtents = halfExtents;
const auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
if (transformComponent != nullptr)
worldHalfExtents *= (transformComponent->GetWorldScale() * 0.5f);
if (type == Type::BOX)
{
auto* box = reinterpret_cast<SHBoundingBox*>(shape);
box->SetHalfExtents(worldHalfExtents);
}
else
{
type = Type::BOX;
delete shape;
shape = new SHBoundingBox{ positionOffset, worldHalfExtents };
}
} }
void SHCollider::SetAsBoundingSphere(float radius) void SHCollider::SetBoundingSphere(float radius)
{ {
dirty = true; dirty = true;
type = Type::SPHERE;
delete shape; // Set the radius relative to transform
shape = new SHBoundingSphere{ positionOffset, radius }; float worldRadius = radius;
const auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
if (transformComponent != nullptr)
{
const SHVec3 TF_WORLD_SCALE = transformComponent->GetWorldScale();
const float MAX_SCALE = SHMath::Max({ TF_WORLD_SCALE.x, TF_WORLD_SCALE.y, TF_WORLD_SCALE.z });
worldRadius *= MAX_SCALE;
}
if (type == Type::SPHERE)
{
auto* sphere = reinterpret_cast<SHBoundingSphere*>(shape);
sphere->SetRadius(worldRadius);
}
else
{
type = Type::SPHERE;
delete shape;
shape = new SHBoundingSphere{ positionOffset, worldRadius };
}
} }
void SHCollider::SetIsTrigger(bool trigger) noexcept void SHCollider::SetIsTrigger(bool trigger) noexcept
@ -172,23 +233,74 @@ namespace SHADE
void SHCollider::SetFriction(float friction) noexcept void SHCollider::SetFriction(float friction) noexcept
{ {
dirty = true; dirty = true;
material.SetFriction(friction);
} }
void SHCollider::SetBounciness(float bounciness) noexcept void SHCollider::SetBounciness(float bounciness) noexcept
{ {
dirty = true; dirty = true;
material.SetBounciness(bounciness);
} }
void SHCollider::SetDensity(float density) noexcept void SHCollider::SetDensity(float density) noexcept
{ {
dirty = true; dirty = true;
material.SetDensity(density);
}
void SHCollider::SetMaterial(const SHPhysicsMaterial& newMaterial) noexcept
{
dirty = true;
material = newMaterial;
} }
void SHCollider::SetPositionOffset(const SHVec3& posOffset) noexcept void SHCollider::SetPositionOffset(const SHVec3& posOffset) noexcept
{ {
dirty = true; dirty = true;
positionOffset = posOffset; positionOffset = posOffset;
switch (type)
{
case Type::BOX:
{
reinterpret_cast<SHBoundingBox*>(shape)->SetCenter(positionOffset);
break;
}
case Type::SPHERE:
{
reinterpret_cast<SHBoundingSphere*>(shape)->SetCenter(positionOffset);
break;
}
default: break;
}
} }
/*-----------------------------------------------------------------------------------*/
/* Private Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
void SHCollider::CopyShape(const SHShape* rhs)
{
switch (type)
{
case Type::BOX:
{
const auto* RHS_BOX = reinterpret_cast<const SHBoundingBox*>(rhs);
shape = new SHBoundingBox{ positionOffset, RHS_BOX->GetHalfExtents() };
break;
}
case Type::SPHERE:
{
const auto* RHS_SPHERE = reinterpret_cast<const SHBoundingSphere*>(rhs);
shape = new SHBoundingSphere{ positionOffset, RHS_SPHERE->GetRadius() };
break;
}
default: break;
}
}
} // namespace SHADE } // namespace SHADE
RTTR_REGISTRATION RTTR_REGISTRATION
@ -205,5 +317,4 @@ RTTR_REGISTRATION
registration::class_<SHCollider>("Collider") registration::class_<SHCollider>("Collider")
.property("Position Offset", &SHCollider::GetPositionOffset, &SHCollider::SetPositionOffset); .property("Position Offset", &SHCollider::GetPositionOffset, &SHCollider::SetPositionOffset);
// TODO(Diren): Add Physics Materials
} }

View File

@ -13,8 +13,10 @@
#include <rttr/registration> #include <rttr/registration>
// Project Headers // Project Headers
#include "ECS_Base/Entity/SHEntity.h"
#include "Math/Geometry/SHShape.h" #include "Math/Geometry/SHShape.h"
#include "Math/SHQuaternion.h" #include "Math/SHQuaternion.h"
#include "SHPhysicsMaterial.h"
namespace SHADE namespace SHADE
{ {
@ -24,6 +26,15 @@ namespace SHADE
class SH_API SHCollider class SH_API SHCollider
{ {
private:
/*---------------------------------------------------------------------------------*/
/* Friends */
/*---------------------------------------------------------------------------------*/
friend class SHColliderComponent;
friend class SHPhysicsObject;
public: public:
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Type Definitions */ /* Type Definitions */
@ -40,7 +51,7 @@ namespace SHADE
/* Constructors & Destructor */ /* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
SHCollider (Type colliderType = Type::BOX); SHCollider (EntityID eid, Type colliderType = Type::BOX, const SHPhysicsMaterial& physicsMaterial = SHPhysicsMaterial::DEFAULT);
SHCollider (const SHCollider& rhs) noexcept; SHCollider (const SHCollider& rhs) noexcept;
SHCollider (SHCollider&& rhs) noexcept; SHCollider (SHCollider&& rhs) noexcept;
@ -57,31 +68,33 @@ namespace SHADE
/* Getter Functions */ /* Getter Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
[[nodiscard]] bool HasChanged () const noexcept; [[nodiscard]] bool HasChanged () const noexcept;
[[nodiscard]] bool IsTrigger () const noexcept; [[nodiscard]] bool IsTrigger () const noexcept;
[[nodiscard]] Type GetType () const noexcept; [[nodiscard]] Type GetType () const noexcept;
[[nodiscard]] float GetFriction () const noexcept; [[nodiscard]] float GetFriction () const noexcept;
[[nodiscard]] float GetBounciness () const noexcept; [[nodiscard]] float GetBounciness () const noexcept;
[[nodiscard]] float GetDensity () const noexcept; [[nodiscard]] float GetDensity () const noexcept;
[[nodiscard]] const SHPhysicsMaterial& GetMaterial () const noexcept;
[[nodiscard]] const SHVec3& GetPositionOffset () const noexcept; [[nodiscard]] const SHVec3& GetPositionOffset () const noexcept;
[[nodiscard]] SHShape* GetShape () noexcept; [[nodiscard]] SHShape* GetShape () noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Setter Functions */ /* Setter Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void SetAsBoundingBox (const SHVec3& halfExtents); void SetBoundingBox (const SHVec3& halfExtents);
void SetAsBoundingSphere (float radius); void SetBoundingSphere (float radius);
void SetIsTrigger (bool isTrigger) noexcept; void SetIsTrigger (bool isTrigger) noexcept;
void SetFriction (float friction) noexcept; void SetFriction (float friction) noexcept;
void SetBounciness (float bounciness) noexcept; void SetBounciness (float bounciness) noexcept;
void SetDensity (float density) noexcept; void SetDensity (float density) noexcept;
void SetMaterial (const SHPhysicsMaterial& newMaterial) noexcept;
void SetPositionOffset (const SHVec3& positionOffset) noexcept; void SetPositionOffset (const SHVec3& positionOffset) noexcept;
@ -90,11 +103,19 @@ namespace SHADE
/* Data Members */ /* Data Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
Type type; Type type;
bool isTrigger; EntityID entityID; // The entity this collider belongs to
bool dirty; bool isTrigger;
SHShape* shape; bool dirty;
SHVec3 positionOffset; SHShape* shape;
SHPhysicsMaterial material;
SHVec3 positionOffset;
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
void CopyShape(const SHShape* rhs);
RTTR_ENABLE() RTTR_ENABLE()
}; };

View File

@ -0,0 +1,104 @@
/****************************************************************************************
* \file SHPhysicsMaterial.cpp
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Implementation for a Physics Material.
*
* \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
* disclosure of this file or its contents without the prior written consent
* of DigiPen Institute of Technology is prohibited.
****************************************************************************************/
#include <SHpch.h>
// Primary Header
#include "SHPhysicsMaterial.h"
// Project Headers
#include "Math/SHMathHelpers.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Static Data Member Definitions */
/*-----------------------------------------------------------------------------------*/
const SHPhysicsMaterial SHPhysicsMaterial::DEFAULT { 0.4f, 0.0f, 1.0f };
/*-----------------------------------------------------------------------------------*/
/* Constructors & Destructor Definitions */
/*-----------------------------------------------------------------------------------*/
SHPhysicsMaterial::SHPhysicsMaterial(float _friction, float _bounciness, float _density) noexcept
: friction { std::clamp(_friction, 0.0f, 1.0f) }
, bounciness{ std::clamp(_bounciness, 0.0f, 1.0f) }
, density { std::fabs(_density) }
{}
/*-----------------------------------------------------------------------------------*/
/* Operator Overload Definitions */
/*-----------------------------------------------------------------------------------*/
bool SHPhysicsMaterial::operator==(const SHPhysicsMaterial& rhs) const noexcept
{
return SHMath::CompareFloat(friction, rhs.friction)
&& SHMath::CompareFloat(bounciness, rhs.bounciness)
&& SHMath::CompareFloat(density, rhs.density);
}
bool SHPhysicsMaterial::operator!=(const SHPhysicsMaterial& rhs) const noexcept
{
return !SHMath::CompareFloat(friction, rhs.friction)
|| !SHMath::CompareFloat(bounciness, rhs.bounciness)
|| !SHMath::CompareFloat(density, rhs.density);
}
/*-----------------------------------------------------------------------------------*/
/* Getter Function Definitions */
/*-----------------------------------------------------------------------------------*/
float SHPhysicsMaterial::GetFriction() const noexcept
{
return friction;
}
float SHPhysicsMaterial::GetBounciness() const noexcept
{
return bounciness;
}
float SHPhysicsMaterial::GetDensity() const noexcept
{
return density;
}
/*-----------------------------------------------------------------------------------*/
/* Setter Function Definitions */
/*-----------------------------------------------------------------------------------*/
void SHPhysicsMaterial::SetFriction(float newFriction) noexcept
{
if (newFriction < 0.0f || newFriction > 1.0f)
{
SHLOG_WARNING("Clamping friction of Physics Material between [0,1].")
}
friction = std::clamp(newFriction, 0.0f, 1.0f);
}
void SHPhysicsMaterial::SetBounciness(float newBounciness) noexcept
{
if (newBounciness < 0.0f || newBounciness > 1.0f)
{
SHLOG_WARNING("Clamping bounciness of Physics Material between [0,1].")
}
bounciness = std::clamp(newBounciness, 0.0f, 1.0f);
}
void SHPhysicsMaterial::SetDensity(float newDensity) noexcept
{
if (newDensity < 0.0f)
{
SHLOG_WARNING("Setting negative density of Physics Material to positive.")
}
density = std::fabs(newDensity);
}
} // namespace SHADE

View File

@ -0,0 +1,113 @@
/****************************************************************************************
* \file SHPhysicsMaterial.h
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Interface for a Physics Material.
*
* \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
* disclosure of this file or its contents without the prior written consent
* of DigiPen Institute of Technology is prohibited.
****************************************************************************************/
#pragma once
// Project Headers
#include "SH_API.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
class SH_API SHPhysicsMaterial
{
public:
/*---------------------------------------------------------------------------------*/
/* Static Data Members */
/*---------------------------------------------------------------------------------*/
static const SHPhysicsMaterial DEFAULT;
/*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/
SHPhysicsMaterial (const SHPhysicsMaterial&) noexcept = default;
SHPhysicsMaterial (SHPhysicsMaterial&&) noexcept = default;
~SHPhysicsMaterial() = default;
/**
* @brief Default constructor for a physics material.
* @param friction The friction of the material. Clamped between [0,1]. Defaults to 0.4.
* @param bounciness The bounciness of the material. Clamped between [0,1].
* @param density The mass density of the material. Always made positive.
*/
SHPhysicsMaterial (float friction = 0.4f, float bounciness = 0.0f, float density = 1.0f) noexcept;
/*---------------------------------------------------------------------------------*/
/* Operator Overloads */
/*---------------------------------------------------------------------------------*/
SHPhysicsMaterial& operator= (const SHPhysicsMaterial&) noexcept = default;
SHPhysicsMaterial& operator= (SHPhysicsMaterial&&) noexcept = default;
bool operator==(const SHPhysicsMaterial& rhs) const noexcept;
bool operator!=(const SHPhysicsMaterial& rhs) const noexcept;
/*---------------------------------------------------------------------------------*/
/* Getter Functions */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] float GetFriction () const noexcept;
[[nodiscard]] float GetBounciness () const noexcept;
[[nodiscard]] float GetDensity () const noexcept;
/*---------------------------------------------------------------------------------*/
/* Setter Functions */
/*---------------------------------------------------------------------------------*/
/**
* @brief Sets the friction coefficient of the physics material.
* @param newFriction The friction value to set. Clamped between [0,1].
*/
void SetFriction (float newFriction) noexcept;
/**
* @brief Sets the bounciness factor of the physics material.
* @param newBounciness The bounciness value to set. Clamped between [0,1].
*/
void SetBounciness (float newBounciness) noexcept;
/**
* @brief Sets the mass density of the physics material.
* @param newDensity The density value to set. Always made positive.
*/
void SetDensity (float newDensity) noexcept;
private:
/*---------------------------------------------------------------------------------*/
/* Data Members */
/*---------------------------------------------------------------------------------*/
/**
* @brief The friction coefficient of the physics object., clamped between [0,1].<br/>
* 0 means the object will never experience friction.
* 1 means the friction force against the object is equal to the applied force.
*/
float friction;
/**
* @brief The bounciness factor of the physics object., clamped between [0,1].<br/>
* 0 means the object will never bounce.
* 1 means the object never loses energy on a bounce.
*/
float bounciness;
/**
* @brief The density of the collider that determines the mass of the collision shape
* if it is automatically computed. Must be a positive number.
*/
float density;
};
}

View File

@ -261,9 +261,9 @@ namespace SHADE
void SHPhysicsObject::SyncColliders(SHColliderComponent* c) const noexcept void SHPhysicsObject::SyncColliders(SHColliderComponent* c) const noexcept
{ {
int index = 0; int index = 0;
for (auto& [collider, dirty] : c->colliders) for (auto& collider : c->colliders)
{ {
if (!dirty) if (!collider.dirty)
continue; continue;
// Update offsets // Update offsets
@ -293,7 +293,7 @@ namespace SHADE
default: break; default: break;
} }
dirty = false; collider.dirty = false;
++index; ++index;
} }
} }

View File

@ -246,21 +246,6 @@ namespace SHADE
if (physicsObject.rp3dBody == nullptr) if (physicsObject.rp3dBody == nullptr)
continue; continue;
auto* rigidBodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(entityID);
// Clear all forces and velocities if editor is not in play
if (SHSystemManager::GetSystem<SHEditor>()->editorState == SHEditor::State::STOP)
{
if (rigidBodyComponent)
{
auto* rp3dRigidBody = reinterpret_cast<rp3d::RigidBody*>(physicsObject.rp3dBody);
rp3dRigidBody->resetForce();
rp3dRigidBody->resetTorque();
rp3dRigidBody->setLinearVelocity(SHVec3::Zero);
rp3dRigidBody->setAngularVelocity(SHVec3::Zero);
}
}
const auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID); const auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
if (transformComponent && transformComponent->HasChanged()) if (transformComponent && transformComponent->HasChanged())
{ {
@ -270,10 +255,21 @@ namespace SHADE
physicsObject.SetPosition(WORLD_POS); physicsObject.SetPosition(WORLD_POS);
physicsObject.SetOrientation(WORLD_ROT); physicsObject.SetOrientation(WORLD_ROT);
auto* rigidBodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(entityID);
if (rigidBodyComponent) if (rigidBodyComponent)
{ {
rigidBodyComponent->position = WORLD_POS; rigidBodyComponent->position = WORLD_POS;
rigidBodyComponent->orientation = WORLD_ROT; rigidBodyComponent->orientation = WORLD_ROT;
// Clear all forces and velocities if editor is stopped
if (SHSystemManager::GetSystem<SHEditor>()->editorState == SHEditor::State::STOP)
{
auto* rp3dRigidBody = reinterpret_cast<rp3d::RigidBody*>(physicsObject.rp3dBody);
rp3dRigidBody->resetForce();
rp3dRigidBody->resetTorque();
rp3dRigidBody->setLinearVelocity(SHVec3::Zero);
rp3dRigidBody->setAngularVelocity(SHVec3::Zero);
}
} }
auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(entityID); auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(entityID);
@ -517,7 +513,7 @@ namespace SHADE
// Add collision shapes back into the body // Add collision shapes back into the body
if (colliderComponent != nullptr) if (colliderComponent != nullptr)
{ {
for (auto& collider : colliderComponent->colliders | std::views::keys) for (auto& collider : colliderComponent->colliders)
physicsObject->AddCollider(&collider); physicsObject->AddCollider(&collider);
} }
} }
@ -538,7 +534,7 @@ namespace SHADE
} }
// Add Collision Shapes // Add Collision Shapes
for (auto& collider : colliderComponent->colliders | std::views::keys) for (auto& collider : colliderComponent->colliders)
physicsObject->AddCollider(&collider); physicsObject->AddCollider(&collider);
} }
} }
@ -576,7 +572,7 @@ namespace SHADE
rp3d::Transform{ colliderComponent->position, colliderComponent->orientation } rp3d::Transform{ colliderComponent->position, colliderComponent->orientation }
); );
for (auto& collider : colliderComponent->colliders | std::views::keys) for (auto& collider : colliderComponent->colliders)
physicsObject->AddCollider(&collider); physicsObject->AddCollider(&collider);
} }

View File

@ -161,7 +161,6 @@ namespace std
std::size_t hash<pair<SHADE::Handle<T1>, SHADE::Handle<T2>>>::operator()( std::size_t hash<pair<SHADE::Handle<T1>, SHADE::Handle<T2>>>::operator()(
std::pair<SHADE::Handle<T1>, SHADE::Handle<T2>> const& pair) const std::pair<SHADE::Handle<T1>, SHADE::Handle<T2>> const& pair) const
{ {
return std::hash<uint64_t>{}(pair.first.GetId().Raw) ^ std::hash<uint64_t>{}(pair.second.GetId().Raw); return std::hash<uint64_t>{}(pair.first.GetId().Raw) ^ std::hash<uint64_t>{}(pair.second.GetId().Raw);
} }
} }

View File

@ -136,11 +136,11 @@ namespace SHADE
template<typename T> template<typename T>
std::optional<AssetID> SHResourceManager::GetAssetID(Handle<T> handle) std::optional<AssetID> SHResourceManager::GetAssetID(Handle<T> handle)
{ {
const Handle GENERIC_HANDLE = Handle(handle); const Handle<void> GENERIC_HANDLE = Handle<void>(handle);
auto [typedHandleMap, typedAssetIdMap] = getAssetHandleMap<T>(); auto [typedHandleMap, typedAssetIdMap] = getAssetHandleMap<T>();
if (typedAssetIdMap.get().contains(GENERIC_HANDLE)) if (typedAssetIdMap.get().contains(GENERIC_HANDLE))
{ {
return typedAssetIdMap.GetId()[GENERIC_HANDLE]; return typedAssetIdMap.get()[GENERIC_HANDLE];
} }
return {}; return {};

View File

@ -582,9 +582,9 @@ namespace SHADE
ReleaseNode(node); ReleaseNode(node);
} }
void SHSceneGraph::Traverse (const UnaryFunction& predicate) const void SHSceneGraph::Traverse (const UnaryFunction& function) const
{ {
TraverseAndInvokeFunction(root, predicate); TraverseAndInvokeFunction(root, function);
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -621,7 +621,7 @@ namespace SHADE
delete node; delete node;
} }
void SHSceneGraph::TraverseAndInvokeFunction (const SHSceneNode* node, const UnaryFunction& function) void SHSceneGraph::TraverseAndInvokeFunction(const SHSceneNode* node, const UnaryFunction& function)
{ {
for (auto* child : node->children) for (auto* child : node->children)
{ {

View File

@ -142,7 +142,7 @@ namespace SHADE
bool RemoveNode (SHSceneNode* nodeToRemove) noexcept; bool RemoveNode (SHSceneNode* nodeToRemove) noexcept;
void Reset () noexcept; void Reset () noexcept;
void Traverse (const UnaryFunction& predicate) const; void Traverse (const UnaryFunction& function) const;
private: private:
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -417,13 +417,13 @@ namespace SHADE
( (
DEFAULT_CSHARP_LIB_NAME, DEFAULT_CSHARP_LIB_NAME,
DEFAULT_CSHARP_NAMESPACE + ".Collider", DEFAULT_CSHARP_NAMESPACE + ".Collider",
"OnColliderBoundChanged" "OnCollisionShapeChanged"
); );
csColliderOnRemoved = dotNet.GetFunctionPtr<CsEventRelayFuncPtr> csColliderOnRemoved = dotNet.GetFunctionPtr<CsEventRelayFuncPtr>
( (
DEFAULT_CSHARP_LIB_NAME, DEFAULT_CSHARP_LIB_NAME,
DEFAULT_CSHARP_NAMESPACE + ".Collider", DEFAULT_CSHARP_NAMESPACE + ".Collider",
"OnColliderRemoved" "OnCollisionShapeRemoved"
); );
csEditorRenderScripts = dotNet.GetFunctionPtr<CsScriptEditorFuncPtr> csEditorRenderScripts = dotNet.GetFunctionPtr<CsScriptEditorFuncPtr>
( (

View File

@ -1,8 +1,8 @@
#include "SHpch.h" #include "SHpch.h"
#include "SHSerializationHelper.hpp"
#include "SHSerialization.h"
#include <yaml-cpp/yaml.h> #include <yaml-cpp/yaml.h>
#include "SHSerializationHelper.hpp"
#include "SHSerialization.h"
#include "ECS_Base/Managers/SHEntityManager.h" #include "ECS_Base/Managers/SHEntityManager.h"
#include "Scene/SHSceneManager.h" #include "Scene/SHSceneManager.h"
@ -186,7 +186,7 @@ namespace SHADE
} }
if (const auto renderable = SHComponentManager::GetComponent_s<SHRenderable>(eid)) if (const auto renderable = SHComponentManager::GetComponent_s<SHRenderable>(eid))
{ {
components[rttr::type::get<SHRenderable>().get_name().data()] = SHSerializationHelper::SerializeComponentToNode(renderable); components[rttr::type::get<SHRenderable>().get_name().data()] = *renderable;
} }
if (const auto rigidbody = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(eid)) if (const auto rigidbody = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(eid))
{ {
@ -259,5 +259,6 @@ namespace SHADE
if (!componentsNode) if (!componentsNode)
return; return;
SHSerializationHelper::InitializeComponentFromNode<SHTransformComponent>(componentsNode, eid); SHSerializationHelper::InitializeComponentFromNode<SHTransformComponent>(componentsNode, eid);
SHSerializationHelper::ConvertNodeToComponent<SHRenderable>(componentsNode, eid);
} }
} }

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include "ECS_Base/Components/SHComponent.h"
#include <yaml-cpp/yaml.h> #include <yaml-cpp/yaml.h>
#include "ECS_Base/Components/SHComponent.h"
#include <rttr/registration> #include <rttr/registration>
@ -9,6 +9,207 @@
#include "Math/Vector/SHVec2.h" #include "Math/Vector/SHVec2.h"
#include "Math/Vector/SHVec3.h" #include "Math/Vector/SHVec3.h"
#include "Math/Vector/SHVec4.h" #include "Math/Vector/SHVec4.h"
#include "Resource/SHResourceManager.h"
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
#include "Graphics/MiddleEnd/Interface/SHMaterial.h"
#include "SHSerializationTools.h"
namespace YAML
{
using namespace SHADE;
template<>
struct convert<SHMaterial>
{
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 YAML::Node encode(SHMaterial const& rhs)
{
// Write Properties
YAML::Node propertiesNode;
Handle<SHShaderBlockInterface> pipelineProperties = rhs.GetShaderBlockInterface();
for (int i = 0; i < static_cast<int>(pipelineProperties->GetVariableCount()); ++i)
{
const SHShaderBlockInterface::Variable* VARIABLE = pipelineProperties->GetVariable(i);
if (!VARIABLE)
break;
const std::string& VAR_NAME = pipelineProperties->GetVariableName(i);
YAML::Node propNode;
switch (VARIABLE->type)
{
case SHADE::SHShaderBlockInterface::Variable::Type::FLOAT:
propNode = rhs.GetProperty<float>(VARIABLE->offset);
break;
case SHADE::SHShaderBlockInterface::Variable::Type::INT:
propNode = rhs.GetProperty<int>(VARIABLE->offset);
break;
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR2:
propNode = SHSerializationTools::ValToYAML(rhs.GetProperty<SHVec2>(VARIABLE->offset));
break;
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR3:
propNode = SHSerializationTools::ValToYAML(rhs.GetProperty<SHVec3>(VARIABLE->offset));
break;
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR4:
propNode = SHSerializationTools::ValToYAML(rhs.GetProperty<SHVec4>(VARIABLE->offset));
break;
case SHADE::SHShaderBlockInterface::Variable::Type::OTHER:
default:
continue;
break;
}
propertiesNode[VAR_NAME.data()] = propNode;
}
// Get Shader Handles
const auto& SHADERS = rhs.GetPipeline()->GetPipelineLayout()->GetShaderModules();
Handle<SHVkShaderModule> vertexShader, fragShader;
for (const auto& shader : SHADERS)
{
const auto FLAG_BITS = shader->GetShaderStageFlagBits();
if (FLAG_BITS & vk::ShaderStageFlagBits::eVertex)
vertexShader = shader;
else if (FLAG_BITS & vk::ShaderStageFlagBits::eFragment)
fragShader = shader;
}
// Write Material
YAML::Node node;
node[VERT_SHADER_YAML_TAG.data()] = 0; // SHResourceManager::GetAssetID<SHVkShaderModule>(vertexShader).value_or(0);
node[FRAG_SHADER_YAML_TAG.data()] = 0; // SHResourceManager::GetAssetID<SHVkShaderModule>(fragShader).value_or(0);
node[SUBPASS_YAML_TAG.data()] = rhs.GetPipeline()->GetPipelineState().GetSubpass()->GetName();
node[PROPS_YAML_TAG.data()] = propertiesNode;
return node;
}
static bool decode(YAML::Node const& node, SHMaterial& rhs)
{
/*
// Retrieve Shader Asset IDs
AssetID vertShaderId = 0;
AssetID fragShaderId = 0;
if (node[VERT_SHADER_YAML_TAG.data()])
vertShaderId = node[VERT_SHADER_YAML_TAG.data()].as<AssetID>();
if (node[FRAG_SHADER_YAML_TAG.data()])
fragShaderId = node[FRAG_SHADER_YAML_TAG.data()].as<AssetID>();
// Ensure that both shaders are present
if (vertShaderId == 0 || fragShaderId == 0)
return false; // No pipeline
// 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;
// Grab subpass from worldRenderer
auto renderPass = gfxSystem->GetPrimaryRenderpass();
if (!renderPass)
return false;
auto subPass = renderPass->GetSubpass(node[SUBPASS_YAML_TAG.data()].as<std::string>());
if (!subPass)
return false;
// Set Pipeline
rhs.SetPipeline(renderPass->GetOrCreatePipeline
(
std::make_pair(vertexShader, fragShader),
subPass
));
}
*/
// TODO: Load Proper Material!
// Set default material
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
if (!gfxSystem)
return false;
rhs.SetPipeline(gfxSystem->GetDefaultMaterial()->GetPipeline());
if (node[PROPS_YAML_TAG.data()])
{
// 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;
}
};
template<>
struct convert<SHRenderable>
{
static constexpr std::string_view MESH_YAML_TAG = "Mesh";
static constexpr std::string_view MAT_YAML_TAG = "Material";
static YAML::Node encode(SHRenderable const& rhs)
{
YAML::Node node;
node[MESH_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHMesh>(rhs.GetMesh()).value_or(0);
node[MAT_YAML_TAG.data()] = 0; // TODO: Asset ID
return node;
}
static bool decode(YAML::Node const& node, SHRenderable& rhs)
{
if (node[MESH_YAML_TAG.data()])
{
rhs.SetMesh(SHResourceManager::LoadOrGet<SHMesh>(node[MESH_YAML_TAG.data()].as<AssetID>()));
}
if (node[MAT_YAML_TAG.data()])
{
// TODO: Convert Asset ID To Material HAndle
// Temporarily, use default material
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
if (!gfxSystem)
return false;
rhs.SetMaterial(gfxSystem->AddOrGetBaseMaterialInstance(gfxSystem->GetDefaultMaterial()));
}
return true;
}
};
}
namespace SHADE namespace SHADE
{ {
@ -126,18 +327,15 @@ namespace SHADE
auto propType = prop.get_type(); auto propType = prop.get_type();
if (propType == rttr::type::get<SHVec4>()) if (propType == rttr::type::get<SHVec4>())
{ {
SHVec4 vec{ propertyNode["X"].as<float>(), propertyNode["Y"].as<float>(), propertyNode["Z"].as<float>(), propertyNode["W"].as<float>() }; prop.set_value(component, SHSerializationTools::YAMLToVec4(propertyNode));
prop.set_value(component, vec);
} }
else if (propType == rttr::type::get<SHVec3>()) else if (propType == rttr::type::get<SHVec3>())
{ {
SHVec3 vec{ propertyNode["X"].as<float>(), propertyNode["Y"].as<float>(), propertyNode["Z"].as<float>() }; prop.set_value(component, SHSerializationTools::YAMLToVec3(propertyNode));
prop.set_value(component, vec);
} }
else if (propType == rttr::type::get<SHVec2>()) else if (propType == rttr::type::get<SHVec2>())
{ {
SHVec2 vec{ propertyNode["X"].as<float>(), propertyNode["Y"].as<float>() }; prop.set_value(component, SHSerializationTools::YAMLToVec2(propertyNode));
prop.set_value(component, vec);
} }
else if (propType.is_arithmetic()) else if (propType.is_arithmetic())
{ {
@ -200,5 +398,18 @@ namespace SHADE
} }
} }
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
static void ConvertNodeToComponent(YAML::Node const& componentsNode, EntityID const& eid)
{
auto component = SHComponentManager::GetComponent_s<ComponentType>(eid);
if (componentsNode.IsNull() && !component)
return;
auto rttrType = rttr::type::get<ComponentType>();
auto componentNode = componentsNode[rttrType.get_name().data()];
if (componentsNode.IsNull())
return;
YAML::convert<ComponentType>::decode(componentNode, *component);
}
}; };
} }

View File

@ -0,0 +1,67 @@
/************************************************************************************//*!
\file SHSerializationTools.cpp
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 22, 2022
\brief Contains the definition of functions of the SHSerializationTools class.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#include "SHpch.h"
#include "SHSerializationTools.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* YAML Serialization Functions */
/*-----------------------------------------------------------------------------------*/
YAML::Node SHSerializationTools::ValToYAML(const SHVec2& vec)
{
YAML::Node node;
node.SetStyle(YAML::EmitterStyle::Flow);
node["X"] = vec.x;
node["Y"] = vec.y;
return node;
}
YAML::Node SHSerializationTools::ValToYAML(const SHVec3& vec)
{
YAML::Node node;
node.SetStyle(YAML::EmitterStyle::Flow);
node["X"] = vec.x;
node["Y"] = vec.y;
node["Z"] = vec.z;
return node;
}
YAML::Node SHSerializationTools::ValToYAML(const SHVec4& vec)
{
YAML::Node node;
node.SetStyle(YAML::EmitterStyle::Flow);
node["X"] = vec.x;
node["Y"] = vec.y;
node["Z"] = vec.z;
node["W"] = vec.w;
return node;
}
/*-----------------------------------------------------------------------------------*/
/* YAML Deserialization Functions */
/*-----------------------------------------------------------------------------------*/
SHVec2 SHSerializationTools::YAMLToVec2(const YAML::Node& node)
{
return SHVec2 { node["X"].as<float>(), node["Y"].as<float>() };
}
SHVec3 SHSerializationTools::YAMLToVec3(const YAML::Node& node)
{
return SHVec3 { node["X"].as<float>(), node["Y"].as<float>(), node["Z"].as<float>() };
}
SHVec4 SHSerializationTools::YAMLToVec4(const YAML::Node& node)
{
return SHVec4 { node["X"].as<float>(), node["Y"].as<float>(), node["Z"].as<float>(), node["W"].as<float>() };
}
}

View File

@ -0,0 +1,54 @@
/************************************************************************************//*!
\file SHSerializationTools.h
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 22, 2022
\brief Contains the class definition of SHSerializationTools.
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
// External Dependencies
#include <yaml-cpp/yaml.h>
// Project Includes
#include "SH_API.h"
#include "Math/Vector/SHVec2.h"
#include "Math/Vector/SHVec3.h"
#include "Math/Vector/SHVec4.h"
namespace SHADE
{
/*************************************************************************************/
/*!
\brief
Static class that contains useful functions for converting values to YAML Nodes
and vice versa.
*/
/*************************************************************************************/
class SH_API SHSerializationTools
{
public:
/*---------------------------------------------------------------------------------*/
/* Constructors */
/*---------------------------------------------------------------------------------*/
SHSerializationTools() = delete;
/*---------------------------------------------------------------------------------*/
/* YAML Serialization Functions */
/*---------------------------------------------------------------------------------*/
static YAML::Node ValToYAML(const SHVec2& vec);
static YAML::Node ValToYAML(const SHVec3& vec);
static YAML::Node ValToYAML(const SHVec4& vec);
/*---------------------------------------------------------------------------------*/
/* YAML Deserialization Functions */
/*---------------------------------------------------------------------------------*/
static SHVec2 YAMLToVec2(const YAML::Node& node);
static SHVec3 YAMLToVec3(const YAML::Node& node);
static SHVec4 YAMLToVec4(const YAML::Node& node);
};
}

View File

@ -22,7 +22,7 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* ColliderBound - Constructors */ /* ColliderBound - Constructors */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
ColliderBound::ColliderBound(int arrayIdx, Entity attachedEntity) CollisionShape::CollisionShape(int arrayIdx, Entity attachedEntity)
: arrayIndex { arrayIdx } : arrayIndex { arrayIdx }
, entity { attachedEntity } , entity { attachedEntity }
{} {}
@ -30,7 +30,7 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* ColliderBound - Setter Functions */ /* ColliderBound - Setter Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void ColliderBound::updateArrayIndex(int index) void CollisionShape::updateArrayIndex(int index)
{ {
arrayIndex = index; arrayIndex = index;
} }
@ -38,42 +38,42 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* BoxColliderBound - Constructors */ /* BoxColliderBound - Constructors */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
BoxColliderBound::BoxColliderBound(int arrayIdx, Entity attachedEntity) BoxCollider::BoxCollider(int arrayIdx, Entity attachedEntity)
: ColliderBound { arrayIndex, attachedEntity } : CollisionShape { arrayIndex, attachedEntity }
{} {}
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* BoxColliderBound - Properties */ /* BoxColliderBound - Properties */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
Vector3 BoxColliderBound::Center::get() Vector3 BoxCollider::Center::get()
{ {
return Convert::ToCLI(getNativeBoundObject<SHBoundingBox>().GetCenter()); return Convert::ToCLI(getNativeBoundObject<SHBoundingBox>().GetCenter());
} }
void BoxColliderBound::Center::set(Vector3 value) void BoxCollider::Center::set(Vector3 value)
{ {
getNativeBoundObject<SHBoundingBox>().SetCenter(Convert::ToNative(value)); getNativeBoundObject<SHBoundingBox>().SetCenter(Convert::ToNative(value));
} }
Vector3 BoxColliderBound::HalfExtents::get() Vector3 BoxCollider::HalfExtents::get()
{ {
return Convert::ToCLI(getNativeBoundObject<SHBoundingBox>().GetHalfExtents()); return Convert::ToCLI(getNativeBoundObject<SHBoundingBox>().GetHalfExtents());
} }
void BoxColliderBound::HalfExtents::set(Vector3 value) void BoxCollider::HalfExtents::set(Vector3 value)
{ {
getNativeBoundObject<SHBoundingBox>().SetHalfExtents(Convert::ToNative(value)); getNativeBoundObject<SHBoundingBox>().SetHalfExtents(Convert::ToNative(value));
} }
Vector3 BoxColliderBound::Min::get() Vector3 BoxCollider::Min::get()
{ {
return Convert::ToCLI(getNativeBoundObject<SHBoundingBox>().GetMin()); return Convert::ToCLI(getNativeBoundObject<SHBoundingBox>().GetMin());
} }
void BoxColliderBound::Min::set(Vector3 value) void BoxCollider::Min::set(Vector3 value)
{ {
getNativeBoundObject<SHBoundingBox>().SetMin(Convert::ToNative(value)); getNativeBoundObject<SHBoundingBox>().SetMin(Convert::ToNative(value));
} }
Vector3 BoxColliderBound::Max::get() Vector3 BoxCollider::Max::get()
{ {
return Convert::ToCLI(getNativeBoundObject<SHBoundingBox>().GetMax()); return Convert::ToCLI(getNativeBoundObject<SHBoundingBox>().GetMax());
} }
void BoxColliderBound::Max::set(Vector3 value) void BoxCollider::Max::set(Vector3 value)
{ {
getNativeBoundObject<SHBoundingBox>().SetMax(Convert::ToNative(value)); getNativeBoundObject<SHBoundingBox>().SetMax(Convert::ToNative(value));
} }
@ -81,11 +81,11 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* BoxColliderBound - Usage Functions */ /* BoxColliderBound - Usage Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
bool BoxColliderBound::TestPoint(Vector3 point) bool BoxCollider::TestPoint(Vector3 point)
{ {
return getNativeBoundObject<SHBoundingBox>().TestPoint(Convert::ToNative(point)); return getNativeBoundObject<SHBoundingBox>().TestPoint(Convert::ToNative(point));
} }
bool BoxColliderBound::Raycast(Ray ray, float maxDistance) bool BoxCollider::Raycast(Ray ray, float maxDistance)
{ {
return getNativeBoundObject<SHBoundingBox>().Raycast(Convert::ToNative(ray), maxDistance); return getNativeBoundObject<SHBoundingBox>().Raycast(Convert::ToNative(ray), maxDistance);
} }
@ -93,19 +93,19 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* BoxColliderBound - Properties */ /* BoxColliderBound - Properties */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
Vector3 SphereColliderBound::Center::get() Vector3 SphereCollider::Center::get()
{ {
return Convert::ToCLI(getNativeBoundObject<SHBoundingSphere>().GetCenter()); return Convert::ToCLI(getNativeBoundObject<SHBoundingSphere>().GetCenter());
} }
void SphereColliderBound::Center::set(Vector3 value) void SphereCollider::Center::set(Vector3 value)
{ {
getNativeBoundObject<SHBoundingSphere>().SetCenter(Convert::ToNative(value)); getNativeBoundObject<SHBoundingSphere>().SetCenter(Convert::ToNative(value));
} }
float SphereColliderBound::Radius::get() float SphereCollider::Radius::get()
{ {
return getNativeBoundObject<SHBoundingSphere>().GetRadius(); return getNativeBoundObject<SHBoundingSphere>().GetRadius();
} }
void SphereColliderBound::Radius::set(float value) void SphereCollider::Radius::set(float value)
{ {
getNativeBoundObject<SHBoundingSphere>().SetRadius(value); getNativeBoundObject<SHBoundingSphere>().SetRadius(value);
} }
@ -113,11 +113,11 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* SphereColliderBound - Usage Functions */ /* SphereColliderBound - Usage Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
bool SphereColliderBound::TestPoint(Vector3 point) bool SphereCollider::TestPoint(Vector3 point)
{ {
return getNativeBoundObject<SHBoundingBox>().TestPoint(Convert::ToNative(point)); return getNativeBoundObject<SHBoundingBox>().TestPoint(Convert::ToNative(point));
} }
bool SphereColliderBound::Raycast(Ray ray, float maxDistance) bool SphereCollider::Raycast(Ray ray, float maxDistance)
{ {
return getNativeBoundObject<SHBoundingBox>().Raycast(Convert::ToNative(ray), maxDistance); return getNativeBoundObject<SHBoundingBox>().Raycast(Convert::ToNative(ray), maxDistance);
} }
@ -125,8 +125,8 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* SphereColliderBound - Constructors */ /* SphereColliderBound - Constructors */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
SphereColliderBound::SphereColliderBound(int arrayIndex, Entity attachedEntity) SphereCollider::SphereCollider(int arrayIndex, Entity attachedEntity)
: ColliderBound{ arrayIndex, attachedEntity } : CollisionShape{ arrayIndex, attachedEntity }
{} {}
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -137,7 +137,7 @@ namespace SHADE
{ {
// Create lists if they don't exist // Create lists if they don't exist
if (colliders == nullptr) if (colliders == nullptr)
colliders = gcnew CollidersMap; colliders = gcnew ColliderMap;
if (!colliders->ContainsKey(entity)) if (!colliders->ContainsKey(entity))
colliders->Add(entity, gcnew WeakReferenceList()); colliders->Add(entity, gcnew WeakReferenceList());
@ -148,7 +148,7 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Collider - Properties */ /* Collider - Properties */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
int Collider::ColliderBoundsCount::get() int Collider::CollisionShapeCount::get()
{ {
return static_cast<int>(GetNativeComponent()->GetColliders().size()); return static_cast<int>(GetNativeComponent()->GetColliders().size());
} }
@ -156,7 +156,7 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Collider - ColliderBound Functions */ /* Collider - ColliderBound Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
ColliderBound^ Collider::GetColliderBound(int index) CollisionShape^ Collider::GetCollisionShape(int index)
{ {
// Populate the list if it hasn't been // Populate the list if it hasn't been
if (subColliderList == nullptr) if (subColliderList == nullptr)
@ -172,15 +172,15 @@ namespace SHADE
return subColliderList[index]; return subColliderList[index];
} }
generic<typename T> generic<typename T>
T Collider::GetColliderBound(int index) T Collider::GetCollisionShape(int index)
{ {
return safe_cast<T>(GetColliderBound(index)); return safe_cast<T>(GetCollisionShape(index));
} }
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Event Handling Functions */ /* Event Handling Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void Collider::OnColliderRemoved(EntityID entity) void Collider::OnCollisionShapeRemoved(EntityID entity)
{ {
SAFE_NATIVE_CALL_BEGIN SAFE_NATIVE_CALL_BEGIN
// Check if there are any colliders to update // Check if there are any colliders to update
@ -192,7 +192,7 @@ namespace SHADE
SAFE_NATIVE_CALL_END("Collider.OnColliderRemoved") SAFE_NATIVE_CALL_END("Collider.OnColliderRemoved")
} }
void Collider::OnColliderBoundChanged(EntityID entity) void Collider::OnCollisionShapeChanged(EntityID entity)
{ {
SAFE_NATIVE_CALL_BEGIN SAFE_NATIVE_CALL_BEGIN
// Check if there are any colliders to update // Check if there are any colliders to update
@ -226,20 +226,20 @@ namespace SHADE
if (subColliderList) if (subColliderList)
subColliderList->Clear(); subColliderList->Clear();
else else
subColliderList = gcnew System::Collections::Generic::List<ColliderBound^>(); subColliderList = gcnew System::Collections::Generic::List<CollisionShape^>();
// Populate the list // Populate the list
int i = 0; int i = 0;
for (const auto& collider : GetNativeComponent()->GetColliders()) for (const auto& collider : GetNativeComponent()->GetColliders())
{ {
ColliderBound^ bound = nullptr; CollisionShape^ bound = nullptr;
switch (collider.first.GetType()) switch (collider.GetType())
{ {
case SHCollider::Type::BOX: case SHCollider::Type::BOX:
bound = gcnew BoxColliderBound(i, Owner.GetEntity()); bound = gcnew BoxCollider(i, Owner.GetEntity());
break; break;
case SHCollider::Type::SPHERE: case SHCollider::Type::SPHERE:
bound = gcnew SphereColliderBound(i, Owner.GetEntity()); bound = gcnew SphereCollider(i, Owner.GetEntity());
break; break;
case SHCollider::Type::CAPSULE: case SHCollider::Type::CAPSULE:
// TODO // TODO

View File

@ -18,8 +18,8 @@ of DigiPen Institute of Technology is prohibited.
#include "Component.hxx" #include "Component.hxx"
namespace SHADE namespace SHADE
{ {
template<typename ColliderBoundType> template<typename CollisionShapeType>
ColliderBoundType& SHADE::ColliderBound::getNativeBoundObject() CollisionShapeType& SHADE::CollisionShape::getNativeBoundObject()
{ {
SHColliderComponent* collider = SHComponentManager::GetComponent_s<SHColliderComponent>(entity); SHColliderComponent* collider = SHComponentManager::GetComponent_s<SHColliderComponent>(entity);
if (!collider) if (!collider)
@ -31,7 +31,7 @@ namespace SHADE
if (bounds.GetType() != SHCollider::Type::BOX) if (bounds.GetType() != SHCollider::Type::BOX)
throw gcnew System::InvalidOperationException("Attempted to retrieve invalid ColliderBound."); throw gcnew System::InvalidOperationException("Attempted to retrieve invalid ColliderBound.");
return reinterpret_cast<ColliderBoundType&>(bounds); return reinterpret_cast<CollisionShapeType&>(bounds);
} }
catch (std::invalid_argument&) catch (std::invalid_argument&)
{ {

View File

@ -27,7 +27,7 @@ namespace SHADE
/// <summary> /// <summary>
/// Base interface for all Collider Shapes. /// Base interface for all Collider Shapes.
/// </summary> /// </summary>
public ref class ColliderBound abstract public ref class CollisionShape abstract
{ {
public: public:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -51,7 +51,7 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Constructors */ /* Constructors */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
ColliderBound(int arrayIdx, Entity attachedEntity); CollisionShape(int arrayIdx, Entity attachedEntity);
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Data Members */ /* Data Members */
@ -62,8 +62,8 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Helper Functions */ /* Helper Functions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
template<typename ColliderBoundType> template<typename CollisionShapeType>
ColliderBoundType& getNativeBoundObject(); CollisionShapeType& getNativeBoundObject();
internal: internal:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -75,7 +75,7 @@ namespace SHADE
/// <summary> /// <summary>
/// Box-shaped Collider Bound. /// Box-shaped Collider Bound.
/// </summary> /// </summary>
public ref class BoxColliderBound : public ColliderBound public ref class BoxCollider : public CollisionShape
{ {
public: public:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -128,13 +128,13 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Constructors */ /* Constructors */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
BoxColliderBound(int arrayIndex, Entity attachedEntity); BoxCollider(int arrayIndex, Entity attachedEntity);
}; };
/// <summary> /// <summary>
/// Sphere-shaped Collider Bound. /// Sphere-shaped Collider Bound.
/// </summary> /// </summary>
public ref class SphereColliderBound : public ColliderBound public ref class SphereCollider : public CollisionShape
{ {
public: public:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -169,7 +169,7 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Constructors */ /* Constructors */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
SphereColliderBound(int arrayIndex, Entity attachedEntity); SphereCollider(int arrayIndex, Entity attachedEntity);
}; };
/// <summary> /// <summary>
@ -196,7 +196,7 @@ namespace SHADE
/// <summary> /// <summary>
/// Total number of ColliderBounds in the Collider component. /// Total number of ColliderBounds in the Collider component.
/// </summary> /// </summary>
property int ColliderBoundsCount property int CollisionShapeCount
{ {
int get(); int get();
} }
@ -209,7 +209,7 @@ namespace SHADE
/// </summary> /// </summary>
/// <param name="index">Index to retrieve a ColliderBound from.</param> /// <param name="index">Index to retrieve a ColliderBound from.</param>
/// <returns>ColliderBound for the specified index.</returns> /// <returns>ColliderBound for the specified index.</returns>
ColliderBound^ GetColliderBound(int index); CollisionShape^ GetCollisionShape(int index);
/// <summary> /// <summary>
/// Retrieves a ColliderBound at the specified index in the ColliderBound list /// Retrieves a ColliderBound at the specified index in the ColliderBound list
/// and casts it to the appropriate type. /// and casts it to the appropriate type.
@ -217,42 +217,42 @@ namespace SHADE
/// <typeparam name="T">Type of the ColliderBound to cast to.</typeparam> /// <typeparam name="T">Type of the ColliderBound to cast to.</typeparam>
/// <param name="index">Index to retrieve a ColliderBound from.</param> /// <param name="index">Index to retrieve a ColliderBound from.</param>
/// <returns>ColliderBound for the specified index.</returns> /// <returns>ColliderBound for the specified index.</returns>
generic<typename T> where T:ColliderBound generic<typename T> where T:CollisionShape
T GetColliderBound(int index); T GetCollisionShape(int index);
internal: internal:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Event Handling Functions */ /* Event Handling Functions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/// <summary> /// <summary>
/// To be called from native code when a collider has been removed. /// To be called from native code when a collision shape has been removed.
/// </summary> /// </summary>
/// <param name="entity">The entity which has it's collider removed.</param> /// <param name="entity">The entity which has it's collision shape removed.</param>
static void OnColliderRemoved(EntityID entity); static void OnCollisionShapeRemoved(EntityID entity);
/// <summary> /// <summary>
/// To be called from native code when a Collider bound has been removed. /// To be called from native code when a Collision Shape has been changed.
/// </summary> /// </summary>
/// <param name="entity"> /// <param name="entity">
/// The entity which has it's collider bounds changed. /// The entity which has it's collision shape changed.
/// </param> /// </param>
static void OnColliderBoundChanged(EntityID entity); static void OnCollisionShapeChanged(EntityID entity);
private: private:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Type Definitions */ /* Type Definitions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
using WeakReferenceList = System::Collections::Generic::List<System::WeakReference^>; using WeakReferenceList = System::Collections::Generic::List<System::WeakReference^>;
using CollidersMap = System::Collections::Generic::Dictionary<EntityID, WeakReferenceList^>; using ColliderMap = System::Collections::Generic::Dictionary<EntityID, WeakReferenceList^>;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Static Data Members */ /* Static Data Members */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
static CollidersMap^ colliders; static ColliderMap^ colliders;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Data Members */ /* Data Members */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
System::Collections::Generic::List<ColliderBound^>^ subColliderList; System::Collections::Generic::List<CollisionShape^>^ subColliderList;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Helper Functions */ /* Helper Functions */

View File

@ -32,17 +32,17 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
SHADE::Mesh^ Renderable::Mesh::get() SHADE::Mesh^ Renderable::Mesh::get()
{ {
return gcnew SHADE::Mesh(GetNativeComponent()->Mesh); return gcnew SHADE::Mesh(GetNativeComponent()->GetMesh());
} }
void Renderable::Mesh::set(SHADE::Mesh^ value) void Renderable::Mesh::set(SHADE::Mesh^ value)
{ {
if (value == nullptr) if (value == nullptr)
{ {
GetNativeComponent()->Mesh = Handle<SHMesh>(); GetNativeComponent()->SetMesh(Handle<SHMesh>());
} }
else else
{ {
GetNativeComponent()->Mesh = Handle<SHMesh>(Convert::ToNative(value->NativeObjectHandle)); GetNativeComponent()->SetMesh(Handle<SHMesh>(Convert::ToNative(value->NativeObjectHandle)));
} }
} }
SHADE::Material^ Renderable::Material::get() SHADE::Material^ Renderable::Material::get()

View File

@ -184,10 +184,6 @@ namespace SHADE
void ReflectionUtilities::writeYamlIntoField(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node) void ReflectionUtilities::writeYamlIntoField(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node)
{ {
if (fieldInfo->FieldType == System::Int16::typeid)
{
fieldInfo->SetValue(object, node.as<int>());
}
if (fieldAssignYaml<System::Int16> (fieldInfo, object, node) || if (fieldAssignYaml<System::Int16> (fieldInfo, object, node) ||
fieldAssignYaml<System::Int32> (fieldInfo, object, node) || fieldAssignYaml<System::Int32> (fieldInfo, object, node) ||
fieldAssignYaml<System::Int64> (fieldInfo, object, node) || fieldAssignYaml<System::Int64> (fieldInfo, object, node) ||