Bug fixes and new assets #246

Merged
glencelow merged 10 commits from PlayerController into main 2022-11-22 16:25:14 +08:00
73 changed files with 1569 additions and 271 deletions
Showing only changes of commit 6c4ec7c807 - Show all commits

View File

@ -0,0 +1,16 @@
0 1
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
10 11
11 12
12 13
13 14
14 15
15 16

BIN
Assets/Fonts/ALGER.shfont Normal file

Binary file not shown.

View File

@ -0,0 +1,3 @@
Name: ALGER
ID: 182525173
Type: 10

BIN
Assets/Fonts/ALGER.ttf Normal file

Binary file not shown.

Binary file not shown.

View File

@ -45,15 +45,14 @@ void main()
float screenPxDistance = 2 * (sd - 0.5f); float screenPxDistance = 2 * (sd - 0.5f);
float opacity = clamp (screenPxDistance + 0.5f, 0.0f, 2.0f); float opacity = clamp (screenPxDistance + 0.5f, 0.0f, 2.0f);
vec4 fragColor = vec4 (1.0f); vec4 fragColor;
if (opacity > 0.02f && opacity < 1.9f) if (opacity < 0.2f)
{ discard;
fragColor = vec4(0.0f, 1.0f, 1.0f, 1.0f); else
} fragColor = mix(vec4(0.0f), vec4(In2.textColor, 1.0f), min (opacity, 1.0f));
fragColor = mix(vec4(0.0f), vec4(In2.textColor, 1.0f), min (opacity, 1.0f));
// fragColor = vec4 (1.0f);
color = fragColor; color = fragColor;
outEntityID = In2.eid; outEntityID = In2.eid;

Binary file not shown.

View File

@ -68,7 +68,7 @@ void main()
// Generate UV coords and vertex positions // Generate UV coords and vertex positions
Out.uv = CreateQuad(gl_VertexIndex); Out.uv = CreateQuad(gl_VertexIndex);
vec3 vertexPos = vec3(Out.uv, 1.0f); vec3 vertexPos = vec3(Out.uv, 0.0f);
// Get the local matrices // Get the local matrices
mat4 localModel = testPushConstant.worldTransform; mat4 localModel = testPushConstant.worldTransform;
@ -87,16 +87,15 @@ void main()
toFontSpace[2][0] = positionalOffset.x; toFontSpace[2][0] = positionalOffset.x;
toFontSpace[2][1] = positionalOffset.y; toFontSpace[2][1] = positionalOffset.y;
mat4 PVMatrix = cameraData.vpMat;
// Initialize variables for use in FS // Initialize variables for use in FS
//characterIndex = gl_InstanceID; //characterIndex = gl_InstanceID;
// Transform the vertices to font space // Transform the vertices to font space
vertexPos = toFontSpace * vertexPos; vertexPos = toFontSpace * vec3(vertexPos.xy, 1.0f);
Out2.textColor = testPushConstant.textColor; Out2.textColor = testPushConstant.textColor;
// transform the vertex position to font space // transform the vertex position to font space
gl_Position = PVMatrix * localModel * vec4(vertexPos, 1.0f); gl_Position = cameraData.orthoMat * localModel * vec4(vertexPos, 1.0f);
// gl_Position = vec4(vertexPos, 1.0f);
} }

Binary file not shown.

View File

@ -3,17 +3,12 @@
#extension GL_ARB_shading_language_420pack : enable #extension GL_ARB_shading_language_420pack : enable
#extension GL_EXT_nonuniform_qualifier : require #extension GL_EXT_nonuniform_qualifier : require
layout (input_attachment_index = 0, set = 4, binding = 0) uniform subpassInput vec4 sceneTexture; layout (input_attachment_index = 0, set = 4, binding = 0) uniform subpassInput sceneTexture;
layout(location = 0) in struct
{
vec2 uv; // location = 0
} In;
layout(location = 0) out vec4 fragColor; layout(location = 0) out vec4 fragColor;
void main() void main()
{ {
fragColor = vec4 (texture (sceneTexture, In.uv).rgb, 1.0f); fragColor = vec4 (subpassLoad(sceneTexture).rgb, 1.0f);
} }

Binary file not shown.

View File

@ -0,0 +1,3 @@
Name: ToSwapchain_FS
ID: 36869006
Type: 2

View File

@ -1,11 +1,6 @@
#version 450 #version 450
#extension GL_KHR_vulkan_glsl : enable #extension GL_KHR_vulkan_glsl : enable
layout(location = 0) out struct
{
vec2 uv; // location = 0
} Out;
vec2 CreateQuad(in uint vertexID) vec2 CreateQuad(in uint vertexID)
{ {
@ -15,7 +10,6 @@ vec2 CreateQuad(in uint vertexID)
void main() void main()
{ {
vec2 texCoord = CreateQuad (gl_VertexIndex); vec2 vertexPos = 2 * (CreateQuad(gl_VertexIndex) - vec2(0.5f));
vec2 vertexPos = texCoord - vec2(0.5f);
gl_Position = vec4 (vertexPos, 0.0f, 1.0f); gl_Position = vec4 (vertexPos, 0.0f, 1.0f);
} }

Binary file not shown.

View File

@ -0,0 +1,3 @@
Name: ToSwapchain_VS
ID: 48082949
Type: 2

View File

@ -78,7 +78,10 @@ project "SHADE_Application"
"26451", "26451",
"26437", "26437",
"4275", "4275",
"4635" "4633",
"4634",
"4635",
"4638"
} }
linkoptions { "-IGNORE:4006" } linkoptions { "-IGNORE:4006" }

View File

@ -80,10 +80,12 @@ namespace Sandbox
SHSystemManager::CreateSystem<SHCameraSystem>(); SHSystemManager::CreateSystem<SHCameraSystem>();
SHSystemManager::CreateSystem<SHUISystem>(); SHSystemManager::CreateSystem<SHUISystem>();
std::system("FontCompiler.exe ../../Assets/Fonts/SegoeUI.ttf"); //std::system("FontCompiler.exe ../../Assets/Fonts/SegoeUI.ttf");
//std::system("FontCompiler.exe ../../Assets/Fonts/ALGER.ttf");
SHSystemManager::CreateSystem<SHGraphicsSystem>(); SHSystemManager::CreateSystem<SHGraphicsSystem>();
SHGraphicsSystem* graphicsSystem = static_cast<SHGraphicsSystem*>(SHSystemManager::GetSystem<SHGraphicsSystem>()); SHGraphicsSystem* graphicsSystem = static_cast<SHGraphicsSystem*>(SHSystemManager::GetSystem<SHGraphicsSystem>());
SHPhysicsSystem* physicsSystem = SHSystemManager::GetSystem<SHPhysicsSystem>();
// Link up SHDebugDraw // Link up SHDebugDraw
SHSystemManager::CreateSystem<SHDebugDrawSystem>(); SHSystemManager::CreateSystem<SHDebugDrawSystem>();
@ -141,7 +143,7 @@ namespace Sandbox
//SHComponentManager::CreateComponentSparseSet<SHCameraComponent>(); //SHComponentManager::CreateComponentSparseSet<SHCameraComponent>();
SHAssetManager::Load(); SHAssetManager::Load();
auto font = SHAssetManager::GetData<SHFontAsset>(176667660); //auto font = SHAssetManager::GetData<SHFontAsset>(176667660);
SHSystemManager::RegisterRoutine<SHAudioSystem, SHAudioSystem::AudioRoutine>(); SHSystemManager::RegisterRoutine<SHAudioSystem, SHAudioSystem::AudioRoutine>();
@ -175,11 +177,16 @@ namespace Sandbox
#ifdef SHEDITOR #ifdef SHEDITOR
if(editor->editorState == SHEditor::State::PLAY) if(editor->editorState == SHEditor::State::PLAY)
SHSceneManager::SceneUpdate(0.016f);
SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, 0.016f);
editor->PollPicking();
#endif
#endif
SHSceneManager::SceneUpdate(0.016f);
#ifdef SHEDITOR
SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, SHFrameRateController::GetRawDeltaTime());
editor->PollPicking();
#else
SHSystemManager::RunRoutines(false, SHFrameRateController::GetRawDeltaTime());
#endif
// TODO: Move into an Editor menu
static bool drawColliders = false; static bool drawColliders = false;
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::F10)) if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::F10))
{ {
@ -192,6 +199,13 @@ namespace Sandbox
drawRays = !drawRays; drawRays = !drawRays;
SHSystemManager::GetSystem<SHPhysicsDebugDrawSystem>()->SetDebugDrawFlag(SHPhysicsDebugDrawSystem::DebugDrawFlags::RAYCASTS, drawRays); SHSystemManager::GetSystem<SHPhysicsDebugDrawSystem>()->SetDebugDrawFlag(SHPhysicsDebugDrawSystem::DebugDrawFlags::RAYCASTS, drawRays);
} }
static bool drawContacts = false;
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::F9))
{
drawContacts = !drawContacts;
SHSystemManager::GetSystem<SHPhysicsDebugDrawSystem>()->SetDebugDrawFlag(SHPhysicsDebugDrawSystem::DebugDrawFlags::CONTACT_POINTS, drawContacts);
SHSystemManager::GetSystem<SHPhysicsDebugDrawSystem>()->SetDebugDrawFlag(SHPhysicsDebugDrawSystem::DebugDrawFlags::CONTACT_NORMALS, drawContacts);
}
} }
// Finish all graphics jobs first // Finish all graphics jobs first
graphicsSystem->AwaitGraphicsExecution(); graphicsSystem->AwaitGraphicsExecution();

View File

@ -7,13 +7,14 @@
#include "Graphics/MiddleEnd/Interface/SHRenderable.h" #include "Graphics/MiddleEnd/Interface/SHRenderable.h"
#include "Scene/SHSceneManager.h" #include "Scene/SHSceneManager.h"
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
#include "Physics/System/SHPhysicsSystem.h"
#include "Scripting/SHScriptEngine.h" #include "Scripting/SHScriptEngine.h"
#include "Math/Transform/SHTransformComponent.h" #include "Math/Transform/SHTransformComponent.h"
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h" #include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
#include "Physics/Interface/SHRigidBodyComponent.h" #include "Physics/Interface/SHRigidBodyComponent.h"
#include "Physics/Interface/SHColliderComponent.h" #include "Physics/Interface/SHColliderComponent.h"
#include "Graphics/MiddleEnd/Lights/SHLightComponent.h" #include "Graphics/MiddleEnd/Lights/SHLightComponent.h"
#include "Graphics/MiddleEnd/TextRendering/SHTextRendererComponent.h" #include "Graphics/MiddleEnd/TextRendering/SHTextRenderableComponent.h"
#include "Assets/SHAssetManager.h" #include "Assets/SHAssetManager.h"
#include "Camera/SHCameraComponent.h" #include "Camera/SHCameraComponent.h"
@ -43,6 +44,15 @@ namespace Sandbox
{ {
sceneName = SHSerialization::DeserializeSceneFromFile(sceneAssetID); sceneName = SHSerialization::DeserializeSceneFromFile(sceneAssetID);
auto* physicsSystem = SHSystemManager::GetSystem<SHPhysicsSystem>();
if (!physicsSystem)
{
SHLOGV_CRITICAL("Failed to get the physics system for building the scene!")
return;
}
physicsSystem->BuildScene(SHSceneManager::GetCurrentSceneGraph());
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* TESTING CODE */ /* TESTING CODE */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/

View File

@ -79,7 +79,10 @@ project "SHADE_Engine"
"26451", "26451",
"26437", "26437",
"4275", "4275",
"4635" "4633",
"4634",
"4635",
"4638"
} }
linkoptions { "-IGNORE:4006" } linkoptions { "-IGNORE:4006" }

View File

@ -22,6 +22,14 @@ namespace SHADE
return nullptr; return nullptr;
} }
// Attempt to load font geometry for advance data
auto ttfFilePath = path.string();
ttfFilePath = ttfFilePath.substr(0, ttfFilePath.find_last_of('.'));
ttfFilePath += TTF_EXTENSION.data();
msdfgen::FontHandle* fontHandle = nullptr;
fontHandle = msdfgen::loadFont(SHFreetypeInstance::GetFreetypeHandle(), ttfFilePath.c_str());
newFontAsset->fontGeometry.loadCharset(fontHandle, 1.0f, msdf_atlas::Charset::ASCII);
uint32_t numGlyphs = 0; uint32_t numGlyphs = 0;
// read how many glyphs we have // read how many glyphs we have

View File

@ -43,7 +43,9 @@ namespace SHADE
if (!camComponent) if (!camComponent)
{ {
SHLOG_WARNING("Camera Director warning: Entity does not have a camera"); SHLOG_WARNING("Camera Director warning: Entity does not have a camera");
return nullptr;
} }
return camComponent;
} }

View File

@ -146,7 +146,7 @@ namespace SHADE
//Call all the children to Destroy themselves first before the parent is destroyed. //Call all the children to Destroy themselves first before the parent is destroyed.
if (entityVec[eIndex]) if (entityVec[eIndex])
{ {
auto& children = SHSceneManager::GetCurrentSceneGraph().GetChildren(eID); auto children = SHSceneManager::GetCurrentSceneGraph().GetChildren(eID);
for (auto& child : children) for (auto& child : children)
{ {
DestroyEntity(child->GetEntityID()); DestroyEntity(child->GetEntityID());

View File

@ -252,7 +252,7 @@ namespace SHADE
if(rbType == SHRigidBodyComponent::Type::DYNAMIC) //Dynamic only fields if(rbType == SHRigidBodyComponent::Type::DYNAMIC) //Dynamic only fields
{ {
SHEditorWidgets::CheckBox("Use Gravity", [component]{return component->IsGravityEnabled();}, [component](bool const& value){component->SetGravityEnabled(value);}, "Gravity"); SHEditorWidgets::CheckBox("Use Gravity", [component]{return component->IsGravityEnabled();}, [component](bool const& value){component->SetGravityEnabled(value);}, "Gravity");
SHEditorWidgets::DragFloat("Mass", [component] {return component->GetMass(); }, [component](float const& value) {component->SetMass(value); }, "Mass"); //SHEditorWidgets::DragFloat("Mass", [component] {return component->GetMass(); }, [component](float const& value) {component->SetMass(value); }, "Mass");
} }
if (rbType == SHRigidBodyComponent::Type::DYNAMIC || rbType == SHRigidBodyComponent::Type::KINEMATIC) //Dynamic or Kinematic only fields if (rbType == SHRigidBodyComponent::Type::DYNAMIC || rbType == SHRigidBodyComponent::Type::KINEMATIC) //Dynamic or Kinematic only fields
{ {
@ -284,6 +284,7 @@ namespace SHADE
//Debug Info (Read-Only) //Debug Info (Read-Only)
if(ImGui::CollapsingHeader("Debug Information", ImGuiTreeNodeFlags_DefaultOpen))//Dynamic or Kinematic only fields if(ImGui::CollapsingHeader("Debug Information", ImGuiTreeNodeFlags_DefaultOpen))//Dynamic or Kinematic only fields
{ {
SHEditorWidgets::DragFloat("Mass", [component] { return component->GetMass(); }, [](float value){}, "Mass", 0.1f, 0.0f, std::numeric_limits<float>::infinity(), "%.3f", ImGuiSliderFlags_ReadOnly);
SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [component] {return component->GetPosition(); }, [](SHVec3 const& value) {}, false, "Position", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly); SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [component] {return component->GetPosition(); }, [](SHVec3 const& value) {}, false, "Position", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly);
SHEditorWidgets::DragVec3("Rotation", { "X", "Y", "Z" }, [component] {return component->GetRotation(); }, [](SHVec3 const& value) {}, false, "Rotation", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly); SHEditorWidgets::DragVec3("Rotation", { "X", "Y", "Z" }, [component] {return component->GetRotation(); }, [](SHVec3 const& value) {}, false, "Rotation", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly);
if (rbType == SHRigidBodyComponent::Type::DYNAMIC || rbType == SHRigidBodyComponent::Type::KINEMATIC) //Dynamic or Kinematic only fields if (rbType == SHRigidBodyComponent::Type::DYNAMIC || rbType == SHRigidBodyComponent::Type::KINEMATIC) //Dynamic or Kinematic only fields
@ -495,4 +496,52 @@ namespace SHADE
} }
ImGui::PopID(); ImGui::PopID();
} }
template<>
static void DrawComponent(SHTextRenderableComponent* component)
{
if (!component)
return;
ImGui::PushID(SHFamilyID<SHComponent>::GetID<SHTextRenderableComponent>());
const auto componentType = rttr::type::get(*component);
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
ImGui::SameLine();
if (ImGui::CollapsingHeader(componentType.get_name().data()))
{
DrawContextMenu(component);
Handle<SHFont> const& font = component->GetFont();
const auto FONT_NAME = SHResourceManager::GetAssetName<SHFont>(font).value_or("");
SHEditorWidgets::DragDropReadOnlyField<AssetID>("Font", FONT_NAME, [component]()
{
Handle<SHFont> const& font = component->GetFont();
return SHResourceManager::GetAssetID<SHFont>(font).value_or(0);
},
[component](AssetID const& id)
{
if (SHAssetManager::GetType(id) != AssetType::FONT)
{
SHLOG_WARNING("Attempted to assign non font asset to TextRendererComponent Font property!")
return;
}
component->SetFont(SHResourceManager::LoadOrGet<SHFont>(id));
SHResourceManager::FinaliseChanges();
}, SHDragDrop::DRAG_RESOURCE);
SHEditorWidgets::InputText("Text",
[component](void)
{
return component->GetText();
},
[component](std::string const& val)
{
component->SetText(val);
}
);
}
else
{
DrawContextMenu(component);
}
ImGui::PopID();
}
} }

View File

@ -22,6 +22,7 @@
#include "UI/SHCanvasComponent.h" #include "UI/SHCanvasComponent.h"
#include "SHEditorComponentView.h" #include "SHEditorComponentView.h"
#include "AudioSystem/SHAudioListenerComponent.h" #include "AudioSystem/SHAudioListenerComponent.h"
#include "Graphics/MiddleEnd/TextRendering/SHTextRenderableComponent.h"
namespace SHADE namespace SHADE
{ {
@ -144,6 +145,10 @@ namespace SHADE
{ {
DrawComponent(uiComponent); DrawComponent(uiComponent);
} }
if (auto textRendererComponent = SHComponentManager::GetComponent_s<SHTextRenderableComponent>(eid))
{
DrawComponent(textRendererComponent);
}
ImGui::Separator(); ImGui::Separator();
// Render Scripts // Render Scripts
SHScriptEngine* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>()); SHScriptEngine* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
@ -162,6 +167,7 @@ namespace SHADE
DrawAddComponentWithEnforcedComponentButton<SHRenderable, SHTransformComponent>(eid); DrawAddComponentWithEnforcedComponentButton<SHRenderable, SHTransformComponent>(eid);
DrawAddComponentWithEnforcedComponentButton<SHRigidBodyComponent, SHTransformComponent>(eid); DrawAddComponentWithEnforcedComponentButton<SHRigidBodyComponent, SHTransformComponent>(eid);
DrawAddComponentWithEnforcedComponentButton<SHColliderComponent, SHTransformComponent>(eid); DrawAddComponentWithEnforcedComponentButton<SHColliderComponent, SHTransformComponent>(eid);
DrawAddComponentWithEnforcedComponentButton<SHTextRenderableComponent, SHTransformComponent>(eid);
ImGui::EndMenu(); ImGui::EndMenu();

View File

@ -4,9 +4,9 @@
\par email: kahwei.tng\@digipen.edu \par email: kahwei.tng\@digipen.edu
\date Nov 7, 2021 \date Nov 7, 2021
\brief Contains the implementation of the EditorUI class. \brief Contains the implementation of the EditorUI class.
Copyright (C) 2021 DigiPen Institute of Technology. Copyright (C) 2021 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited. of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/ *//*************************************************************************************/
// Precompiled Header // Precompiled Header
@ -57,10 +57,10 @@ namespace SHADE
{ {
const bool OPENED = ImGui::CollapsingHeader(title.c_str(), ImGuiTreeNodeFlags_DefaultOpen); const bool OPENED = ImGui::CollapsingHeader(title.c_str(), ImGuiTreeNodeFlags_DefaultOpen);
if (isHovered) if (isHovered)
*isHovered = ImGui::IsItemHovered(); *isHovered = ImGui::IsItemHovered();
return OPENED; return OPENED;
} }
void SHEditorUI::SameLine() void SHEditorUI::SameLine()
{ {
ImGui::SameLine(); ImGui::SameLine();
@ -98,7 +98,7 @@ namespace SHADE
void SHEditorUI::EndTooltip() void SHEditorUI::EndTooltip()
{ {
ImGui::EndTooltip(); ImGui::EndTooltip();
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -146,7 +146,7 @@ namespace SHADE
bool SHEditorUI::Selectable(const std::string& label) bool SHEditorUI::Selectable(const std::string& label)
{ {
return ImGui::Selectable(label.data()); return ImGui::Selectable(label.data());
} }
bool SHEditorUI::Selectable(const std::string& label, const char* icon) bool SHEditorUI::Selectable(const std::string& label, const char* icon)
@ -156,30 +156,41 @@ namespace SHADE
bool SHEditorUI::InputCheckbox(const std::string& label, bool& value, bool* isHovered) bool SHEditorUI::InputCheckbox(const std::string& label, bool& value, bool* isHovered)
{ {
ImGui::Text(label.c_str()); if (!label.empty())
{
ImGui::Text(label.c_str());
ImGui::SameLine();
}
if (isHovered) if (isHovered)
*isHovered = ImGui::IsItemHovered(); *isHovered = ImGui::IsItemHovered();
ImGui::SameLine();
return ImGui::Checkbox("##", &value); return ImGui::Checkbox("##", &value);
} }
bool SHEditorUI::InputInt(const std::string& label, int& value, bool* isHovered) bool SHEditorUI::InputInt(const std::string& label, int& value, bool* isHovered)
{ {
ImGui::Text(label.c_str()); if (!label.empty())
{
ImGui::Text(label.c_str());
ImGui::SameLine();
}
if (isHovered) if (isHovered)
*isHovered = ImGui::IsItemHovered(); *isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
return ImGui::DragInt("##", &value, 0.001f, return ImGui::DragInt("##", &value, 0.001f,
std::numeric_limits<int>::min(), std::numeric_limits<int>::min(),
std::numeric_limits<int>::max(), std::numeric_limits<int>::max(),
"%d", "%d",
ImGuiInputTextFlags_EnterReturnsTrue); ImGuiInputTextFlags_EnterReturnsTrue);
} }
bool SHEditorUI::InputUnsignedInt(const std::string& label, unsigned int& value, bool* isHovered) bool SHEditorUI::InputUnsignedInt(const std::string& label, unsigned int& value, bool* isHovered)
{ {
int signedVal = static_cast<int>(value); int signedVal = static_cast<int>(value);
ImGui::Text(label.c_str()); if (!label.empty())
{
ImGui::Text(label.c_str());
ImGui::SameLine();
}
if (isHovered) if (isHovered)
*isHovered = ImGui::IsItemHovered(); *isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
const bool CHANGED = InputInt("##", signedVal); const bool CHANGED = InputInt("##", signedVal);
if (CHANGED) if (CHANGED)
@ -191,15 +202,19 @@ namespace SHADE
} }
bool SHEditorUI::InputFloat(const std::string& label, float& value, bool* isHovered) bool SHEditorUI::InputFloat(const std::string& label, float& value, bool* isHovered)
{ {
ImGui::Text(label.c_str()); if (!label.empty())
{
ImGui::Text(label.c_str());
ImGui::SameLine();
}
if (isHovered) if (isHovered)
*isHovered = ImGui::IsItemHovered(); *isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
return ImGui::DragFloat("##", &value, 0.001f, return ImGui::DragFloat("##", &value, 0.001f,
std::numeric_limits<float>::lowest(), std::numeric_limits<float>::lowest(),
std::numeric_limits<float>::max(), std::numeric_limits<float>::max(),
"%.3f", "%.3f",
ImGuiInputTextFlags_EnterReturnsTrue); ImGuiInputTextFlags_EnterReturnsTrue);
} }
bool SHEditorUI::InputDouble(const std::string& label, double& value, bool* isHovered) bool SHEditorUI::InputDouble(const std::string& label, double& value, bool* isHovered)
{ {
@ -213,48 +228,56 @@ namespace SHADE
} }
bool SHEditorUI::InputSlider(const std::string& label, int min, int max, int& value, bool* isHovered /*= nullptr*/) bool SHEditorUI::InputSlider(const std::string& label, int min, int max, int& value, bool* isHovered /*= nullptr*/)
{ {
if (!label.empty())
{
ImGui::Text(label.c_str()); ImGui::Text(label.c_str());
if (isHovered)
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
return ImGui::SliderInt("##", &value, }
static_cast<float>(min), static_cast<float>(max), "%d", if (isHovered)
ImGuiInputTextFlags_EnterReturnsTrue); *isHovered = ImGui::IsItemHovered();
ImGui::SameLine();
return ImGui::SliderInt("##", &value,
static_cast<float>(min), static_cast<float>(max), "%d",
ImGuiInputTextFlags_EnterReturnsTrue);
} }
bool SHEditorUI::InputSlider(const std::string& label, unsigned int min, unsigned int max, unsigned int& value, bool* isHovered /*= nullptr*/) bool SHEditorUI::InputSlider(const std::string& label, unsigned int min, unsigned int max, unsigned int& value, bool* isHovered /*= nullptr*/)
{ {
int val = static_cast<int>(value); int val = static_cast<int>(value);
const bool CHANGED = InputSlider(label, min, max, val, isHovered); const bool CHANGED = InputSlider(label, min, max, val, isHovered);
if (CHANGED) if (CHANGED)
{ {
value = static_cast<int>(val); value = static_cast<int>(val);
} }
return CHANGED; return CHANGED;
} }
bool SHEditorUI::InputSlider(const std::string& label, float min, float max, float& value, bool* isHovered) bool SHEditorUI::InputSlider(const std::string& label, float min, float max, float& value, bool* isHovered)
{ {
if (!label.empty())
{
ImGui::Text(label.c_str()); ImGui::Text(label.c_str());
if (isHovered)
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
return ImGui::SliderFloat("##", &value, }
static_cast<float>(min), static_cast<float>(max), "%.3f", if (isHovered)
ImGuiInputTextFlags_EnterReturnsTrue); *isHovered = ImGui::IsItemHovered();
ImGui::SameLine();
return ImGui::SliderFloat("##", &value,
static_cast<float>(min), static_cast<float>(max), "%.3f",
ImGuiInputTextFlags_EnterReturnsTrue);
} }
bool SHEditorUI::InputSlider(const std::string& label, double min, double max, double& value, bool* isHovered /*= nullptr*/) bool SHEditorUI::InputSlider(const std::string& label, double min, double max, double& value, bool* isHovered /*= nullptr*/)
{ {
float val = static_cast<float>(value); float val = static_cast<float>(value);
const bool CHANGED = InputSlider(label, min, max, val, isHovered); const bool CHANGED = InputSlider(label, min, max, val, isHovered);
if (CHANGED) if (CHANGED)
{ {
value = static_cast<double>(val); value = static_cast<double>(val);
} }
return CHANGED; return CHANGED;
} }
bool SHEditorUI::InputVec2(const std::string& label, SHVec2& value, bool* isHovered) bool SHEditorUI::InputVec2(const std::string& label, SHVec2& value, bool* isHovered)
@ -264,7 +287,7 @@ namespace SHADE
} }
bool SHEditorUI::InputVec3(const std::string& label, SHVec3& value, bool* isHovered) bool SHEditorUI::InputVec3(const std::string& label, SHVec3& value, bool* isHovered)
{ {
static const std::vector<std::string> COMPONENT_LABELS = { "X", "Y", "Z"}; static const std::vector<std::string> COMPONENT_LABELS = { "X", "Y", "Z" };
return SHEditorWidgets::DragN<float, 3>(label, COMPONENT_LABELS, { &value.x, &value.y, &value.z }, 0.1f, "%.3f", float{}, float{}, 0, isHovered); return SHEditorWidgets::DragN<float, 3>(label, COMPONENT_LABELS, { &value.x, &value.y, &value.z }, 0.1f, "%.3f", float{}, float{}, 0, isHovered);
} }
@ -272,9 +295,13 @@ namespace SHADE
{ {
std::array<char, TEXT_FIELD_MAX_LENGTH> buffer = { '\0' }; std::array<char, TEXT_FIELD_MAX_LENGTH> buffer = { '\0' };
strcpy_s(buffer.data(), TEXT_FIELD_MAX_LENGTH, value.c_str()); strcpy_s(buffer.data(), TEXT_FIELD_MAX_LENGTH, value.c_str());
ImGui::Text(label.c_str()); if (!label.empty())
{
ImGui::Text(label.c_str());
ImGui::SameLine();
}
if (isHovered) if (isHovered)
*isHovered = ImGui::IsItemHovered(); *isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
const bool CHANGED = ImGui::InputText("##", &buffer[0], TEXT_FIELD_MAX_LENGTH); const bool CHANGED = ImGui::InputText("##", &buffer[0], TEXT_FIELD_MAX_LENGTH);
if (CHANGED) if (CHANGED)
@ -286,7 +313,11 @@ namespace SHADE
bool SHEditorUI::InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered, bool alwaysNull) bool SHEditorUI::InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered, bool alwaysNull)
{ {
ImGui::Text(label.c_str()); if (!label.empty())
{
ImGui::Text(label.c_str());
ImGui::SameLine();
}
if (isHovered) if (isHovered)
*isHovered = ImGui::IsItemHovered(); *isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
@ -326,9 +357,13 @@ namespace SHADE
const std::string& INITIAL_NAME = v >= static_cast<int>(enumNames.size()) ? "Unknown" : enumNames[v]; const std::string& INITIAL_NAME = v >= static_cast<int>(enumNames.size()) ? "Unknown" : enumNames[v];
bool b = false; bool b = false;
ImGui::Text(label.c_str()); if (!label.empty())
{
ImGui::Text(label.c_str());
ImGui::SameLine();
}
if (isHovered) if (isHovered)
*isHovered = ImGui::IsItemHovered(); *isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::BeginCombo("##", INITIAL_NAME.c_str(), ImGuiComboFlags_None)) if (ImGui::BeginCombo("##", INITIAL_NAME.c_str(), ImGuiComboFlags_None))
{ {

View File

@ -55,7 +55,7 @@ namespace SHADE
void SHSuperBatch::Remove(const SHRenderable* renderable) noexcept void SHSuperBatch::Remove(const SHRenderable* renderable) noexcept
{ {
Handle<SHMaterial> baseMat = renderable->GetMaterial()->GetBaseMaterial(); Handle<SHMaterial> baseMat = (renderable->HasMaterialChanged() ? renderable->GetPrevMaterial() : renderable->GetMaterial())->GetBaseMaterial();
const Handle<SHVkPipeline> PIPELINE = baseMat->HasPipelineChanged() ? baseMat->GetPrevPipeline() : baseMat->GetPipeline(); const Handle<SHVkPipeline> PIPELINE = baseMat->HasPipelineChanged() ? baseMat->GetPrevPipeline() : baseMat->GetPipeline();
// Check if we have a Batch with the same pipeline yet // Check if we have a Batch with the same pipeline yet

View File

@ -84,7 +84,7 @@ namespace SHADE
if (width == 0 || height == 0) if (width == 0 || height == 0)
return; return;
PrepareResize(resizeWidth, resizeHeight); PrepareResize(width, height);
}); });
window->RegisterWindowCloseCallback([&](void) window->RegisterWindowCloseCallback([&](void)
@ -117,13 +117,16 @@ namespace SHADE
// Create generic command buffer // Create generic command buffer
graphicsCmdPool = device->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true); graphicsCmdPool = device->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true);
SHAssetManager::CompileAsset("../../Assets/Shaders/Text_VS.glsl", false); SHFreetypeInstance::Init();
SHAssetManager::CompileAsset("../../Assets/Shaders/Text_FS.glsl", false);
SHAssetManager::CompileAsset("../../Assets/Shaders/TestCube_VS.glsl", false); //SHAssetManager::CompileAsset("../../Assets/Shaders/Text_VS.glsl", false);
SHAssetManager::CompileAsset("../../Assets/Shaders/UI_VS.glsl", false); //SHAssetManager::CompileAsset("../../Assets/Shaders/Text_FS.glsl", false);
SHAssetManager::CompileAsset("../../Assets/Shaders/UI_FS.glsl", false); //SHAssetManager::CompileAsset("../../Assets/Shaders/TestCube_VS.glsl", false);
//SHAssetManager::CompileAsset("../../Assets/Shaders/UI_VS.glsl", false);
SHAssetManager::CompileAsset("../../Assets/Models/Quad.gltf", false); //SHAssetManager::CompileAsset("../../Assets/Shaders/UI_FS.glsl", false);
//SHAssetManager::CompileAsset("../../Assets/Models/Quad.gltf", false);
//SHAssetManager::CompileAsset("../../Assets/Shaders/ToSwapchain_VS.glsl", false);
//SHAssetManager::CompileAsset("../../Assets/Shaders/ToSwapchain_FS.glsl", false);
// Load Built In Shaders // Load Built In Shaders
static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEFAULT); static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEFAULT);
@ -135,7 +138,8 @@ namespace SHADE
static constexpr AssetID SSAO_BLUR = 39760835; ssaoBlurShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(SSAO_BLUR); static constexpr AssetID SSAO_BLUR = 39760835; ssaoBlurShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(SSAO_BLUR);
static constexpr AssetID TEXT_VS = 39816727; textVS = SHResourceManager::LoadOrGet<SHVkShaderModule>(TEXT_VS); static constexpr AssetID TEXT_VS = 39816727; textVS = SHResourceManager::LoadOrGet<SHVkShaderModule>(TEXT_VS);
static constexpr AssetID TEXT_FS = 38024754; textFS = SHResourceManager::LoadOrGet<SHVkShaderModule>(TEXT_FS); static constexpr AssetID TEXT_FS = 38024754; textFS = SHResourceManager::LoadOrGet<SHVkShaderModule>(TEXT_FS);
static constexpr AssetID SEGOE_UI_FONT = 176667660; testFont = SHResourceManager::LoadOrGet<SHFont>(SEGOE_UI_FONT); static constexpr AssetID RENDER_SC_VS = 48082949; renderToSwapchainVS = SHResourceManager::LoadOrGet<SHVkShaderModule>(RENDER_SC_VS);
static constexpr AssetID RENDER_SC_FS = 36869006; renderToSwapchainFS = SHResourceManager::LoadOrGet<SHVkShaderModule>(RENDER_SC_FS);
} }
void SHGraphicsSystem::InitSceneRenderGraph(void) noexcept void SHGraphicsSystem::InitSceneRenderGraph(void) noexcept
@ -299,6 +303,7 @@ namespace SHADE
textRenderingSubSystem->Render(cmdBuffer, frameIndex); textRenderingSubSystem->Render(cmdBuffer, frameIndex);
}); });
#ifdef SHEDITOR
{ {
// Dummy Node to transition scene render graph resource // Dummy Node to transition scene render graph resource
auto dummyNode = screenRenderGraph->AddNode("Dummy Pass", { "Scene" }, { "Screen Space Pass" }); // no predecessors auto dummyNode = screenRenderGraph->AddNode("Dummy Pass", { "Scene" }, { "Screen Space Pass" }); // no predecessors
@ -306,7 +311,9 @@ namespace SHADE
dummySubpass->AddInput("Scene"); dummySubpass->AddInput("Scene");
} }
//screenRenderGraph->AddRenderToSwapchainNode ("Scene", "Present", ) #else
screenRenderGraph->AddRenderToSwapchainNode("Scene", "Present", {"Screen Space Pass"}, {renderToSwapchainVS, renderToSwapchainFS});
#endif
screenRenderGraph->Generate(); screenRenderGraph->Generate();
@ -379,7 +386,6 @@ namespace SHADE
screenRenderer->BindDescSet(cmdBuffer, frameIndex); screenRenderer->BindDescSet(cmdBuffer, frameIndex);
}); });
SHFreetypeInstance::Init();
} }
void SHGraphicsSystem::InitBuiltInResources(void) void SHGraphicsSystem::InitBuiltInResources(void)
@ -1041,7 +1047,8 @@ namespace SHADE
worldViewport->SetWidth(static_cast<float>(resizeWidth)); worldViewport->SetWidth(static_cast<float>(resizeWidth));
worldViewport->SetHeight(static_cast<float>(resizeHeight)); worldViewport->SetHeight(static_cast<float>(resizeHeight));
worldCamera->SetPerspective(90.0f, static_cast<float>(resizeWidth), static_cast<float>(resizeHeight), 0.0f, 100.0f); //worldCamera->SetPerspective(90.0f, static_cast<float>(resizeWidth), static_cast<float>(resizeHeight), 0.0f, 100.0f);
//screenCamera->SetOrthographic(static_cast<float>(resizeWidth), static_cast<float>(resizeHeight), 0.01f, 100.0f);
auto cameraSystem = SHSystemManager::GetSystem<SHCameraSystem>(); auto cameraSystem = SHSystemManager::GetSystem<SHCameraSystem>();
#ifdef SHEDITOR #ifdef SHEDITOR
@ -1053,8 +1060,6 @@ namespace SHADE
for (auto& semaHandle : graphSemaphores) for (auto& semaHandle : graphSemaphores)
semaHandle = device->CreateSemaphore(); semaHandle = device->CreateSemaphore();
} }
void SHGraphicsSystem::AwaitGraphicsExecution() void SHGraphicsSystem::AwaitGraphicsExecution()

View File

@ -444,6 +444,8 @@ namespace SHADE
Handle<SHVkShaderModule> ssaoBlurShader; Handle<SHVkShaderModule> ssaoBlurShader;
Handle<SHVkShaderModule> textVS; Handle<SHVkShaderModule> textVS;
Handle<SHVkShaderModule> textFS; Handle<SHVkShaderModule> textFS;
Handle<SHVkShaderModule> renderToSwapchainVS;
Handle<SHVkShaderModule> renderToSwapchainFS;
// Fonts // Fonts
Handle<SHFont> testFont; Handle<SHFont> testFont;

View File

@ -1,15 +1,15 @@
#include "SHpch.h" #include "SHpch.h"
#include "SHTextRendererComponent.h" #include "SHTextRenderableComponent.h"
namespace SHADE namespace SHADE
{ {
void SHTextRendererComponent::MakeDirty(void) noexcept void SHTextRenderableComponent::MakeDirty(void) noexcept
{ {
requiresRecompute = true; requiresRecompute = true;
} }
void SHTextRendererComponent::Clean(void) noexcept void SHTextRenderableComponent::Clean(void) noexcept
{ {
requiresRecompute = false; requiresRecompute = false;
} }
@ -22,16 +22,16 @@ namespace SHADE
*/ */
/***************************************************************************/ /***************************************************************************/
void SHTextRendererComponent::OnCreate(void) void SHTextRenderableComponent::OnCreate(void)
{ {
text = "Text"; text = "My name is Brandon.";
requiresRecompute = true; requiresRecompute = true;
// Default white color. // Default white color.
color = SHColour::WHITE; color = SHColour::WHITE;
} }
void SHTextRendererComponent::OnDestroy(void) void SHTextRenderableComponent::OnDestroy(void)
{ {
} }
@ -49,15 +49,16 @@ namespace SHADE
*/ */
/***************************************************************************/ /***************************************************************************/
void SHTextRendererComponent::SetText(std::string_view newText) noexcept void SHTextRenderableComponent::SetText(std::string_view newText) noexcept
{ {
text = newText; text = newText;
MakeDirty(); MakeDirty();
} }
void SHTextRendererComponent::SetFont(Handle<SHFont> font) noexcept void SHTextRenderableComponent::SetFont(Handle<SHFont> font) noexcept
{ {
fontHandle = font; fontHandle = font;
MakeDirty();
} }
/***************************************************************************/ /***************************************************************************/
@ -71,9 +72,24 @@ namespace SHADE
*/ */
/***************************************************************************/ /***************************************************************************/
std::string const& SHTextRendererComponent::GetText(void) const noexcept std::string const& SHTextRenderableComponent::GetText(void) const noexcept
{ {
return text; return text;
} }
} Handle<SHFont> SHTextRenderableComponent::GetFont(void) const noexcept
{
return fontHandle;
}
}
namespace rttr
{
RTTR_REGISTRATION
{
using namespace SHADE;
registration::class_<SHTextRenderableComponent>("Text Renderer Component");
};
}

View File

@ -5,6 +5,7 @@
#include "ECS_Base/Components/SHComponent.h" #include "ECS_Base/Components/SHComponent.h"
#include "Math/SHColour.h" #include "Math/SHColour.h"
#include "Resource/SHHandle.h" #include "Resource/SHHandle.h"
#include <rttr/registration>
namespace SHADE namespace SHADE
{ {
@ -12,7 +13,7 @@ namespace SHADE
class SHVkDescriptorSetGroup; class SHVkDescriptorSetGroup;
class SHVkBuffer; class SHVkBuffer;
class SH_API SHTextRendererComponent final : public SHComponent class SH_API SHTextRenderableComponent final : public SHComponent
{ {
public: public:
static constexpr uint32_t MAX_CHARACTERS = 500; static constexpr uint32_t MAX_CHARACTERS = 500;
@ -53,9 +54,12 @@ namespace SHADE
void SetFont (Handle<SHFont> font) noexcept; void SetFont (Handle<SHFont> font) noexcept;
std::string const& GetText (void) const noexcept; std::string const& GetText (void) const noexcept;
Handle<SHFont> GetFont (void) const noexcept;
friend class SHTextRenderingSubSystem; friend class SHTextRenderingSubSystem;
RTTR_ENABLE()
}; };
} }

View File

@ -1,6 +1,6 @@
#include "SHpch.h" #include "SHpch.h"
#include "SHTextRenderingSubSystem.h" #include "SHTextRenderingSubSystem.h"
#include "Graphics/MiddleEnd/TextRendering/SHTextRendererComponent.h" #include "Graphics/MiddleEnd/TextRendering/SHTextRenderableComponent.h"
#include "ECS_Base/Managers/SHComponentManager.h" #include "ECS_Base/Managers/SHComponentManager.h"
#include "Math/Vector/SHVec4.h" #include "Math/Vector/SHVec4.h"
#include "Graphics/Devices/SHVkLogicalDevice.h" #include "Graphics/Devices/SHVkLogicalDevice.h"
@ -14,20 +14,20 @@
namespace SHADE namespace SHADE
{ {
void SHTextRenderingSubSystem::RecomputePositions(SHTextRendererComponent& textComp) noexcept void SHTextRenderingSubSystem::RecomputePositions(SHTextRenderableComponent& textComp) noexcept
{ {
if (textComp.text.empty() || textComp.fontHandle) if (textComp.text.empty() || !textComp.fontHandle)
return; return;
// Create the buffer // Create the buffer
if (!textComp.indexingDataBuffer) if (!textComp.indexingDataBuffer)
textComp.indexingDataBuffer = logicalDevice->CreateBuffer(SHTextRendererComponent::MAX_CHARACTERS * sizeof(uint32_t), nullptr, SHTextRendererComponent::MAX_CHARACTERS * sizeof(uint32_t), vk::BufferUsageFlagBits::eVertexBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT); textComp.indexingDataBuffer = logicalDevice->CreateBuffer(SHTextRenderableComponent::MAX_CHARACTERS * sizeof(uint32_t), nullptr, SHTextRenderableComponent::MAX_CHARACTERS * sizeof(uint32_t), vk::BufferUsageFlagBits::eVertexBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT);
if (!textComp.charPositionDataBuffer) if (!textComp.charPositionDataBuffer)
textComp.indexingDataBuffer = logicalDevice->CreateBuffer(SHTextRendererComponent::MAX_CHARACTERS * sizeof(SHVec4), nullptr, SHTextRendererComponent::MAX_CHARACTERS * sizeof(SHVec4), vk::BufferUsageFlagBits::eVertexBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT); textComp.charPositionDataBuffer = logicalDevice->CreateBuffer(SHTextRenderableComponent::MAX_CHARACTERS * sizeof(SHVec4), nullptr, SHTextRenderableComponent::MAX_CHARACTERS * sizeof(SHVec4), vk::BufferUsageFlagBits::eVertexBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT);
// For indexing font transformation in the shader // For indexing font transformation in the shader
std::vector <SHTextRendererComponent::TextIndexingType> indexingData; std::vector <SHTextRenderableComponent::TextIndexingType> indexingData;
// For placing glyphs correctly // For placing glyphs correctly
std::vector <SHVec4> charPositionData; std::vector <SHVec4> charPositionData;
@ -49,7 +49,7 @@ namespace SHADE
// for every character // for every character
for (uint32_t i = 0; i < numChars; ++i) for (uint32_t i = 0; i < numChars; ++i)
{ {
SHTextRendererComponent::TextIndexingType index = glyphTransformIndices.at(textComp.text[i]); SHTextRenderableComponent::TextIndexingType index = glyphTransformIndices.at(textComp.text[i]);
// Copy baseline // Copy baseline
SHVec4 characterPos = baselineOrigin; SHVec4 characterPos = baselineOrigin;
@ -83,7 +83,7 @@ namespace SHADE
//} //}
} }
textComp.indexingDataBuffer->WriteToMemory(indexingData.data(), static_cast<uint32_t>(indexingData.size()) * sizeof (SHTextRendererComponent::TextIndexingType),0, 0); textComp.indexingDataBuffer->WriteToMemory(indexingData.data(), static_cast<uint32_t>(indexingData.size()) * sizeof (SHTextRenderableComponent::TextIndexingType),0, 0);
textComp.charPositionDataBuffer->WriteToMemory(charPositionData.data(), static_cast<uint32_t>(charPositionData.size()) * sizeof (SHVec4), 0, 0); textComp.charPositionDataBuffer->WriteToMemory(charPositionData.data(), static_cast<uint32_t>(charPositionData.size()) * sizeof (SHVec4), 0, 0);
indexingData.clear(); indexingData.clear();
@ -93,7 +93,7 @@ namespace SHADE
void SHTextRenderingSubSystem::Init(Handle<SHVkLogicalDevice> device, Handle<SHVkRenderpass> compatibleRenderpass, Handle<SHSubpass> subpass, Handle<SHVkDescriptorPool> descPool, Handle<SHVkShaderModule> textVS, Handle<SHVkShaderModule> textFS, std::function<void(Handle<SHVkCommandBuffer>, uint32_t)> const& bindFunction) noexcept void SHTextRenderingSubSystem::Init(Handle<SHVkLogicalDevice> device, Handle<SHVkRenderpass> compatibleRenderpass, Handle<SHSubpass> subpass, Handle<SHVkDescriptorPool> descPool, Handle<SHVkShaderModule> textVS, Handle<SHVkShaderModule> textFS, std::function<void(Handle<SHVkCommandBuffer>, uint32_t)> const& bindFunction) noexcept
{ {
SHComponentManager::CreateComponentSparseSet<SHTextRendererComponent>(); SHComponentManager::CreateComponentSparseSet<SHTextRenderableComponent>();
cameraDescSetBind = bindFunction; cameraDescSetBind = bindFunction;
@ -115,8 +115,8 @@ namespace SHADE
SHVertexInputState vertexInputState; SHVertexInputState vertexInputState;
// Configure vertex attributes // Configure vertex attributes
vertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_4D) }); // location = 0 (character position data) vertexInputState.AddBinding(true, false, { SHVertexAttribute(SHAttribFormat::FLOAT_4D) }); // location = 0 (character position data)
vertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::UINT32_1D) }); // location = 1 (glyph index to index matrices) vertexInputState.AddBinding(true, false, { SHVertexAttribute(SHAttribFormat::UINT32_1D) }); // location = 1 (glyph index to index matrices)
// Set vertex state for new pipeline // Set vertex state for new pipeline
pipeline->GetPipelineState().SetVertexInputState(vertexInputState); pipeline->GetPipelineState().SetVertexInputState(vertexInputState);
@ -146,6 +146,13 @@ namespace SHADE
pipeline->GetPipelineState().SetColorBlenState(colorBlendState); pipeline->GetPipelineState().SetColorBlenState(colorBlendState);
SHInputAssemblyState inputAssembly{};
inputAssembly.topology = vk::PrimitiveTopology::eTriangleFan;
pipeline->GetPipelineState().SetInputAssemblyState(inputAssembly);
SHRasterizationState rasterState{};
rasterState.frontFacingOrientation = vk::FrontFace::eClockwise;
pipeline->GetPipelineState().SetRasterizationState(rasterState);
// Construct pipeline // Construct pipeline
pipeline->ConstructPipeline(); pipeline->ConstructPipeline();
@ -172,7 +179,7 @@ namespace SHADE
void SHTextRenderingSubSystem::Run(uint32_t frameIndex) noexcept void SHTextRenderingSubSystem::Run(uint32_t frameIndex) noexcept
{ {
auto& textRendererComps = SHComponentManager::GetDense<SHTextRendererComponent>(); auto& textRendererComps = SHComponentManager::GetDense<SHTextRenderableComponent>();
for (auto& comp : textRendererComps) for (auto& comp : textRendererComps)
{ {
@ -187,7 +194,7 @@ namespace SHADE
void SHTextRenderingSubSystem::Render(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept void SHTextRenderingSubSystem::Render(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
{ {
auto& textRendererComps = SHComponentManager::GetDense<SHTextRendererComponent>(); auto& textRendererComps = SHComponentManager::GetDense<SHTextRenderableComponent>();
for (auto& comp : textRendererComps) for (auto& comp : textRendererComps)
{ {
auto* transform = SHComponentManager::GetComponent<SHTransformComponent>(comp.GetEID()); auto* transform = SHComponentManager::GetComponent<SHTransformComponent>(comp.GetEID());

View File

@ -14,7 +14,7 @@ namespace SHADE
class SHVkBuffer; class SHVkBuffer;
class SHLightComponent; class SHLightComponent;
class SHVkCommandBuffer; class SHVkCommandBuffer;
class SHTextRendererComponent; class SHTextRenderableComponent;
class SHVkPipeline; class SHVkPipeline;
class SHVkPipelineLayout; class SHVkPipelineLayout;
class SHVkRenderpass; class SHVkRenderpass;
@ -48,7 +48,7 @@ namespace SHADE
std::function<void(Handle<SHVkCommandBuffer>, uint32_t)> cameraDescSetBind; std::function<void(Handle<SHVkCommandBuffer>, uint32_t)> cameraDescSetBind;
private: private:
void RecomputePositions(SHTextRendererComponent& textComp) noexcept; void RecomputePositions(SHTextRenderableComponent& textComp) noexcept;
public: public:
void Init(Handle<SHVkLogicalDevice> device, Handle<SHVkRenderpass> compatibleRenderpass, Handle<SHSubpass> subpass, Handle<SHVkDescriptorPool> descPool, Handle<SHVkShaderModule> textVS, Handle<SHVkShaderModule> textFS, std::function<void(Handle<SHVkCommandBuffer>, uint32_t)> const& bindFunction) noexcept; void Init(Handle<SHVkLogicalDevice> device, Handle<SHVkRenderpass> compatibleRenderpass, Handle<SHSubpass> subpass, Handle<SHVkDescriptorPool> descPool, Handle<SHVkShaderModule> textVS, Handle<SHVkShaderModule> textFS, std::function<void(Handle<SHVkCommandBuffer>, uint32_t)> const& bindFunction) noexcept;

View File

@ -565,8 +565,10 @@ namespace SHADE
{ {
cmdBuffer->BindPipeline(renderToSwapchainImageSystem->GetPipeline()); cmdBuffer->BindPipeline(renderToSwapchainImageSystem->GetPipeline());
newSubpass->BindDescriptorInputDescriptorSets (cmdBuffer, frameIndex);
// draw a quad. // draw a quad.
cmdBuffer->DrawIndexed(4, 0, 0); cmdBuffer->DrawArrays(4, 1, 0, 0);
}); });
} }
} }

View File

@ -3,6 +3,8 @@
#include "Graphics/Devices/SHVkLogicalDevice.h" #include "Graphics/Devices/SHVkLogicalDevice.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" #include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
#include "Graphics/RenderGraph/SHRenderGraphNode.h" #include "Graphics/RenderGraph/SHRenderGraphNode.h"
#include "Graphics/RenderGraph/SHSubpass.h"
#include "Graphics/SHVkUtil.h"
namespace SHADE namespace SHADE
{ {
@ -25,14 +27,34 @@ namespace SHADE
.globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts(), .globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts(),
}); });
auto newPipeline = logicalDevice->CreateGraphicsPipeline(pipelineLayout, nullptr, renderGraphNode->GetRenderpass(), subpass); pipeline = logicalDevice->CreateGraphicsPipeline(pipelineLayout, nullptr, renderGraphNode->GetRenderpass(), subpass);
SHInputAssemblyState inputAssembly{}; SHInputAssemblyState inputAssembly{};
inputAssembly.topology = vk::PrimitiveTopology::eTriangleFan; inputAssembly.topology = vk::PrimitiveTopology::eTriangleFan;
newPipeline->GetPipelineState().SetInputAssemblyState(inputAssembly); pipeline->GetPipelineState().SetInputAssemblyState(inputAssembly);
newPipeline->ConstructPipeline(); SHColorBlendState colorBlendState{};
colorBlendState.logic_op_enable = VK_FALSE;
colorBlendState.logic_op = vk::LogicOp::eCopy;
auto const& subpassColorReference = subpass->GetColorAttachmentReferences()[0];
colorBlendState.attachments.push_back(vk::PipelineColorBlendAttachmentState
{
.blendEnable = SHVkUtil::IsBlendCompatible(subpass->GetFormatFromAttachmentReference(subpassColorReference.attachment)),
.srcColorBlendFactor = vk::BlendFactor::eSrcAlpha,
.dstColorBlendFactor = vk::BlendFactor::eOneMinusSrcAlpha,
.colorBlendOp = vk::BlendOp::eAdd,
.srcAlphaBlendFactor = vk::BlendFactor::eOne,
.dstAlphaBlendFactor = vk::BlendFactor::eZero,
.alphaBlendOp = vk::BlendOp::eAdd,
.colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA,
}
);
pipeline->GetPipelineState().SetColorBlenState(colorBlendState);
pipeline->ConstructPipeline();
} }

View File

@ -40,7 +40,7 @@ namespace SHADE
, inputReferences{} , inputReferences{}
, name { name } , name { name }
, graphStorage{ renderGraphStorage } , graphStorage{ renderGraphStorage }
, inputImageDescriptors {SHGraphicsConstants::NUM_FRAME_BUFFERS} , inputImageDescriptorSets{}
{ {
} }
@ -67,7 +67,7 @@ namespace SHADE
, exteriorDrawCalls{ std::move(rhs.exteriorDrawCalls) } , exteriorDrawCalls{ std::move(rhs.exteriorDrawCalls) }
, graphStorage{ rhs.graphStorage } , graphStorage{ rhs.graphStorage }
, inputNames{ std::move(rhs.inputNames) } , inputNames{ std::move(rhs.inputNames) }
, inputImageDescriptors{ std::move(rhs.inputImageDescriptors) } , inputImageDescriptorSets{ std::move(rhs.inputImageDescriptorSets) }
, inputDescriptorLayout{ rhs.inputDescriptorLayout } , inputDescriptorLayout{ rhs.inputDescriptorLayout }
, inputSamplers{ rhs.inputSamplers } , inputSamplers{ rhs.inputSamplers }
, name { rhs.name } , name { rhs.name }
@ -102,7 +102,7 @@ namespace SHADE
exteriorDrawCalls = std::move(rhs.exteriorDrawCalls); exteriorDrawCalls = std::move(rhs.exteriorDrawCalls);
graphStorage = rhs.graphStorage; graphStorage = rhs.graphStorage;
inputNames = std::move(rhs.inputNames); inputNames = std::move(rhs.inputNames);
inputImageDescriptors = std::move(rhs.inputImageDescriptors); inputImageDescriptorSets = std::move(rhs.inputImageDescriptorSets);
inputDescriptorLayout = rhs.inputDescriptorLayout; inputDescriptorLayout = rhs.inputDescriptorLayout;
inputSamplers = rhs.inputSamplers; inputSamplers = rhs.inputSamplers;
name = std::move(rhs.name); name = std::move(rhs.name);
@ -202,6 +202,8 @@ namespace SHADE
void SHSubpass::Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept void SHSubpass::Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept
{ {
commandBuffer->BeginLabeledSegment(name); commandBuffer->BeginLabeledSegment(name);
// Ensure correct transforms are provided // Ensure correct transforms are provided
superBatch->UpdateBuffers(frameIndex, descPool); superBatch->UpdateBuffers(frameIndex, descPool);
@ -221,6 +223,14 @@ namespace SHADE
UpdateWriteDescriptors(); UpdateWriteDescriptors();
} }
void SHSubpass::BindDescriptorInputDescriptorSets(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) const noexcept
{
if (!inputImageDescriptorSets.empty())
{
cmdBuffer->BindDescriptorSet(inputImageDescriptorSets[frameIndex], SH_PIPELINE_TYPE::GRAPHICS, SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, { });
}
}
void SHSubpass::AddExteriorDrawCalls(std::function<void(Handle<SHVkCommandBuffer>&, uint32_t)> const& newDrawCall) noexcept void SHSubpass::AddExteriorDrawCalls(std::function<void(Handle<SHVkCommandBuffer>&, uint32_t)> const& newDrawCall) noexcept
{ {
exteriorDrawCalls.push_back(newDrawCall); exteriorDrawCalls.push_back(newDrawCall);
@ -237,6 +247,8 @@ namespace SHADE
if (inputNames.empty()) if (inputNames.empty())
return; return;
inputImageDescriptorSets.resize(SHGraphicsConstants::NUM_FRAME_BUFFERS);
std::vector<SHVkDescriptorSetLayout::Binding> bindings{}; std::vector<SHVkDescriptorSetLayout::Binding> bindings{};
for (auto& input : inputReferences) for (auto& input : inputReferences)
@ -280,8 +292,8 @@ namespace SHADE
} }
} }
//// maybe do this in handle resize? // maybe do this in handle resize?
//UpdateWriteDescriptors(); UpdateWriteDescriptors();
} }
void SHSubpass::UpdateWriteDescriptors(void) noexcept void SHSubpass::UpdateWriteDescriptors(void) noexcept
@ -296,7 +308,7 @@ namespace SHADE
// For every frame's descriptor set // For every frame's descriptor set
for (auto& group : inputImageDescriptors) for (auto& group : inputImageDescriptorSets)
{ {
if (group) if (group)
group.Free(); group.Free();

View File

@ -55,8 +55,11 @@ namespace SHADE
//! For getting attachment reference indices using handles //! For getting attachment reference indices using handles
std::unordered_map<uint64_t, uint32_t> const* resourceAttachmentMapping; std::unordered_map<uint64_t, uint32_t> const* resourceAttachmentMapping;
//! Descriptor set group to hold the images for input //! Descriptor set group to hold the images for input. We have 3 here just in case
std::vector<Handle<SHVkDescriptorSetGroup>> inputImageDescriptors; //! one of the images is a swapchain image. Practically speaking its not likely not
//! swapchain images will end up being images used in descriptor sets, but this is
//! to have the support for it. The cost is not much.
std::vector<Handle<SHVkDescriptorSetGroup>> inputImageDescriptorSets;
//! Descriptor set layout for allocating descriptor set for inputs //! Descriptor set layout for allocating descriptor set for inputs
Handle<SHVkDescriptorSetLayout> inputDescriptorLayout; Handle<SHVkDescriptorSetLayout> inputDescriptorLayout;
@ -104,6 +107,7 @@ namespace SHADE
// Runtime functions // Runtime functions
void Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept; void Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
void HandleResize (void) noexcept; void HandleResize (void) noexcept;
void BindDescriptorInputDescriptorSets (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) const noexcept;
void Init(SHResourceHub& resourceManager) noexcept; void Init(SHResourceHub& resourceManager) noexcept;

View File

@ -0,0 +1,223 @@
/****************************************************************************************
* \file SHCollisionTagMatrix.cpp
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Implementation for Collision Tag Matrix for handling sets of Collision Tags.
*
* \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>
#include <fstream>
// Primary Header
#include "SHCollisionTagMatrix.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Static Data Member Definitions */
/*-----------------------------------------------------------------------------------*/
SHCollisionTag SHCollisionTagMatrix::collisionTags[SHCollisionTag::NUM_LAYERS];
/*-----------------------------------------------------------------------------------*/
/* Getter Function Definitions */
/*-----------------------------------------------------------------------------------*/
const std::string& SHCollisionTagMatrix::GetTagName(int tagIndex)
{
if (tagIndex < 0 || tagIndex > SHCollisionTag::NUM_LAYERS)
throw std::invalid_argument("Index out of range!");
return collisionTags[tagIndex].GetName();
}
int SHCollisionTagMatrix::GetTagIndex(const std::string& tagName) noexcept
{
for (int i = 0; i < SHCollisionTag::NUM_LAYERS; ++i)
{
if (collisionTags[i].GetName() == tagName)
return i;
}
SHLOGV_WARNING("Collision Tag {} cannot be found!", tagName)
return -1;
}
SHCollisionTag* SHCollisionTagMatrix::GetTag(int tagIndex)
{
if (tagIndex < 0 || tagIndex > SHCollisionTag::NUM_LAYERS)
throw std::invalid_argument("Index out of range!");
return &collisionTags[tagIndex];
}
SHCollisionTag* SHCollisionTagMatrix::GetTag(const std::string& tagName) noexcept
{
for (int i = 0; i < SHCollisionTag::NUM_LAYERS; ++i)
{
if (collisionTags[i].GetName() == tagName)
return &collisionTags[i];
}
SHLOGV_WARNING("Collision Tag {} cannot be found!", tagName)
return nullptr;
}
/*-----------------------------------------------------------------------------------*/
/* Setter Function Definitions */
/*-----------------------------------------------------------------------------------*/
void SHCollisionTagMatrix::SetTagName(const std::string& oldTagName, const std::string& newTagName) noexcept
{
for (auto& collisionTag : collisionTags)
{
if (collisionTag.GetName() != oldTagName)
continue;
collisionTag.SetName(newTagName);
return;
}
SHLOGV_WARNING("Collision tag {} cannot be found!", oldTagName)
}
void SHCollisionTagMatrix::SetTag(const std::string& tagName, const SHCollisionTag& newTag) noexcept
{
for (auto& collisionTag : collisionTags)
{
if (collisionTag.GetName() != tagName)
continue;
collisionTag = newTag;
return;
}
SHLOGV_WARNING("Collision tag {} cannot be found!", tagName)
}
void SHCollisionTagMatrix::SetTag(const std::string& tagName, uint16_t mask) noexcept
{
for (auto& collisionTag : collisionTags)
{
if (collisionTag.GetName() != tagName)
continue;
collisionTag.SetMask(mask);
return;
}
SHLOGV_WARNING("Collision tag {} cannot be found!", tagName)
}
void SHCollisionTagMatrix::SetTagName(int tagIndex, const std::string& newTagName)
{
if (tagIndex < 0 || tagIndex > SHCollisionTag::NUM_LAYERS)
throw std::invalid_argument("Index out of range!");
collisionTags[tagIndex].SetName(newTagName);
}
void SHCollisionTagMatrix::SetTag(int tagIndex, const SHCollisionTag& newTag)
{
if (tagIndex < 0 || tagIndex > SHCollisionTag::NUM_LAYERS)
throw std::invalid_argument("Index out of range!");
collisionTags[tagIndex] = newTag;
}
void SHCollisionTagMatrix::SetTag(int tagIndex, uint16_t mask)
{
if (tagIndex < 0 || tagIndex > SHCollisionTag::NUM_LAYERS)
throw std::invalid_argument("Index out of range!");
collisionTags[tagIndex].SetMask(mask);
}
/*-----------------------------------------------------------------------------------*/
/* Public Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
void SHCollisionTagMatrix::Init(const std::filesystem::path& tagNameFilePath) noexcept
{
/**
* I HATE FILE IO
*
* Each line in the file should be "index<space>tag name".
* If the line fails to follow this format, use the default tag name (index + 1)
*/
// Populate tag names with default
for (int i = 0; i < SHCollisionTag::NUM_LAYERS; ++i)
collisionTags[i].SetName(std::to_string(i + 1));
std::ifstream collisionTagNamesFile { tagNameFilePath };
if (!collisionTagNamesFile.is_open())
{
SHLOG_ERROR("Failed to open file for Collision Tag Names! Default tag names used!")
return;
}
std::stringstream ss;
std::string line;
int linesRead = 0;
while (std::getline(collisionTagNamesFile, line))
{
// Do not read anything beyond the first 16 lines
if (linesRead >= 16)
break;
ss << line;
++linesRead;
// First element is index.
int tagIndex;
ss >> tagIndex;
// Next element is name of the tag
std::string tagName;
ss >> tagName;
// If no tag name read, use default.
if (tagName.empty())
{
SHLOG_ERROR
(
"Collision tag file line {} does not match the required format of 'index<space>tag name'. Default tag used for index {}"
, linesRead + 1
, tagIndex
)
// Use default
collisionTags[tagIndex].SetName(std::to_string(tagIndex + 1));
continue;
}
collisionTags[tagIndex].SetName(tagName);
ss.clear();
}
collisionTagNamesFile.close();
}
void SHCollisionTagMatrix::Exit(const std::filesystem::path& tagNameFilePath) noexcept
{
std::ofstream collisionTagNamesFile { tagNameFilePath };
if (!collisionTagNamesFile.is_open())
{
SHLOG_ERROR("Failed to open file for Collision Tag Names! Tag names not saved!")
return;
}
for (int i = 0; i < SHCollisionTag::NUM_LAYERS; ++i)
collisionTagNamesFile << i << " " << collisionTags[i].GetName() << std::endl;
collisionTagNamesFile.close();
}
} // namespace SHADE

View File

@ -0,0 +1,67 @@
/****************************************************************************************
* \file SHCollisionTagMatrix.h
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Interface for Collision Tag Matrix for handling sets of Collision Tags.
*
* \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
* disclosure of this file or its contents without the prior written consent
* of DigiPen Institute of Technology is prohibited.
****************************************************************************************/
#pragma once
#include <filesystem>
// Project Includes
#include "SH_API.h"
#include "SHCollisionTags.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
class SH_API SHCollisionTagMatrix
{
public:
/*---------------------------------------------------------------------------------*/
/* Getter Functions */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] static const std::string& GetTagName (int tagIndex);
[[nodiscard]] static int GetTagIndex (const std::string& tagName) noexcept;
[[nodiscard]] static SHCollisionTag* GetTag (int tagIndex);
[[nodiscard]] static SHCollisionTag* GetTag (const std::string& tagName) noexcept;
/*---------------------------------------------------------------------------------*/
/* Setter Functions */
/*---------------------------------------------------------------------------------*/
static void SetTagName (const std::string& oldTagName, const std::string& newTagName) noexcept;
static void SetTag (const std::string& tagName, const SHCollisionTag& newTag) noexcept;
static void SetTag (const std::string& tagName, uint16_t mask) noexcept;
// Unsafe Setters: Can throw exceptions
static void SetTagName (int tagIndex, const std::string& newTagName);
static void SetTag (int tagIndex, const SHCollisionTag& newTag);
static void SetTag (int tagIndex, uint16_t mask);
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
static void Init (const std::filesystem::path& tagNameFilePath) noexcept;
static void Exit (const std::filesystem::path& tagNameFilePath) noexcept;
private:
/*---------------------------------------------------------------------------------*/
/* Data Members */
/*---------------------------------------------------------------------------------*/
static SHCollisionTag collisionTags[SHCollisionTag::NUM_LAYERS];
};
}

View File

@ -0,0 +1,116 @@
/****************************************************************************************
* \file SHCollisionTags.cpp
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Implementation for Collision Tags for filtering collisions.
*
* \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>
#include <fstream>
// Primary Header
#include "SHCollisionTags.h"
// Project Headers
#include "Tools/Utilities/SHUtilities.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Constructors & Destructor Definitions */
/*-----------------------------------------------------------------------------------*/
SHCollisionTag::SHCollisionTag() noexcept
: mask { SHUtilities::ConvertEnum(Layer::ALL) }
{}
SHCollisionTag::SHCollisionTag(uint16_t _mask) noexcept
: mask { _mask }
{}
SHCollisionTag::SHCollisionTag(Layer layer) noexcept
: mask { SHUtilities::ConvertEnum(layer) }
{}
/*-----------------------------------------------------------------------------------*/
/* Operator Overload Definitions */
/*-----------------------------------------------------------------------------------*/
bool SHCollisionTag::operator==(const SHCollisionTag& rhs) const noexcept
{
return mask == rhs.mask;
}
bool SHCollisionTag::operator!=(const SHCollisionTag& rhs) const noexcept
{
return mask != rhs.mask;
}
SHCollisionTag::operator uint16_t() const noexcept
{
return mask;
}
/*-----------------------------------------------------------------------------------*/
/* Getter Function Definitions */
/*-----------------------------------------------------------------------------------*/
uint16_t SHCollisionTag::GetMask() const noexcept
{
return mask;
}
const std::string& SHCollisionTag::GetName() const noexcept
{
return name;
}
bool SHCollisionTag::GetLayerState(Layer layer) const noexcept
{
return (mask & SHUtilities::ConvertEnum(layer)) > 0;
}
bool SHCollisionTag::GetLayerState(int layerIndex) const
{
if (layerIndex < 0 || layerIndex > NUM_LAYERS)
throw std::invalid_argument("Index out of range!");
return (mask & (1U << layerIndex)) > 0;
}
/*-----------------------------------------------------------------------------------*/
/* Setter Function Definitions */
/*-----------------------------------------------------------------------------------*/
void SHCollisionTag::SetMask(uint16_t newMask) noexcept
{
mask = newMask;
}
void SHCollisionTag::SetName(const std::string_view& newName) noexcept
{
name = newName;
}
void SHCollisionTag::SetLayerState(Layer layer, bool state) noexcept
{
const auto VALUE = SHUtilities::ConvertEnum(layer);
state ? mask |= VALUE : mask &= ~(VALUE);
}
void SHCollisionTag::SetLayerState(int layerIndex, bool state)
{
if (layerIndex < 0 || layerIndex > NUM_LAYERS)
throw std::invalid_argument("Index out of range!");
const auto VALUE = 1U << layerIndex;
state ? mask |= (VALUE) : mask &= ~(VALUE);
}
} // namespace SHADE
SHADE::SHCollisionTag::Layer operator|(SHADE::SHCollisionTag::Layer lhs, SHADE::SHCollisionTag::Layer rhs) noexcept
{
return static_cast<SHADE::SHCollisionTag::Layer>(SHADE::SHUtilities::ConvertEnum(lhs) | SHADE::SHUtilities::ConvertEnum(rhs));
}

View File

@ -0,0 +1,112 @@
/****************************************************************************************
* \file SHCollisionTags.h
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Interface for Collision Tags for filtering collisions.
*
* \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
* disclosure of this file or its contents without the prior written consent
* of DigiPen Institute of Technology is prohibited.
****************************************************************************************/
#pragma once
#include <string>
// Project Headers
#include "SH_API.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
class SH_API SHCollisionTag
{
public:
/*---------------------------------------------------------------------------------*/
/* Type Definitions */
/*---------------------------------------------------------------------------------*/
enum class Layer : uint16_t
{
_1 = 0x0001
, _2 = 0x0002
, _3 = 0x0004
, _4 = 0x0008
, _5 = 0x0010
, _6 = 0x0020
, _7 = 0x0040
, _8 = 0x0080
, _9 = 0x0100
, _10 = 0x0200
, _11 = 0x0400
, _12 = 0x0800
, _13 = 0x1000
, _14 = 0x2000
, _15 = 0x4000
, _16 = 0x8000
, ALL = 0xFFFF
};
/*---------------------------------------------------------------------------------*/
/* Data Members */
/*---------------------------------------------------------------------------------*/
static constexpr int NUM_LAYERS = 16;
/*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/
SHCollisionTag () noexcept;
SHCollisionTag (uint16_t mask) noexcept;
SHCollisionTag (Layer layer) noexcept;
SHCollisionTag (const SHCollisionTag&) noexcept = default;
SHCollisionTag (SHCollisionTag&&) noexcept = default;
~SHCollisionTag () = default;
/*---------------------------------------------------------------------------------*/
/* Operator Overloads */
/*---------------------------------------------------------------------------------*/
SHCollisionTag& operator=(const SHCollisionTag&) noexcept = default;
SHCollisionTag& operator=(SHCollisionTag&&) noexcept = default;
[[nodiscard]] bool operator==(const SHCollisionTag& rhs) const noexcept;
[[nodiscard]] bool operator!=(const SHCollisionTag& rhs) const noexcept;
operator uint16_t() const noexcept;
/*---------------------------------------------------------------------------------*/
/* Getter Functions */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] uint16_t GetMask () const noexcept;
[[nodiscard]] const std::string& GetName () const noexcept;
[[nodiscard]] bool GetLayerState (Layer layer) const noexcept;
[[nodiscard]] bool GetLayerState (int layerIndex) const;
/*---------------------------------------------------------------------------------*/
/* Setter Functions */
/*---------------------------------------------------------------------------------*/
void SetMask (uint16_t newMask) noexcept;
void SetName (const std::string_view& newName) noexcept;
void SetLayerState (Layer layer, bool state) noexcept;
void SetLayerState (int layerIndex, bool state);
private:
/*---------------------------------------------------------------------------------*/
/* Data Members */
/*---------------------------------------------------------------------------------*/
uint16_t mask;
std::string name;
};
} // namespace SHADE
SHADE::SHCollisionTag::Layer SH_API operator|(SHADE::SHCollisionTag::Layer lhs, SHADE::SHCollisionTag::Layer rhs) noexcept;

View File

@ -80,6 +80,14 @@ namespace SHADE
} }
system = physicsSystem; system = physicsSystem;
// Sync with transform if one already exists
if (auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(GetEID()); transformComponent)
{
position = transformComponent->GetWorldPosition();
orientation = transformComponent->GetWorldOrientation();
scale = transformComponent->GetWorldScale();
}
} }
void SHColliderComponent::OnDestroy() void SHColliderComponent::OnDestroy()

View File

@ -16,6 +16,7 @@
#include "Math/Geometry/SHBox.h" #include "Math/Geometry/SHBox.h"
#include "Math/Geometry/SHSphere.h" #include "Math/Geometry/SHSphere.h"
#include "Math/SHMathHelpers.h" #include "Math/SHMathHelpers.h"
#include "Physics/Collision/SHCollisionTagMatrix.h"
#include "Reflection/SHReflectionMetadata.h" #include "Reflection/SHReflectionMetadata.h"
#include "SHColliderComponent.h" #include "SHColliderComponent.h"
@ -26,12 +27,13 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHCollisionShape::SHCollisionShape(EntityID eid, Type colliderType, const SHPhysicsMaterial& physicsMaterial) SHCollisionShape::SHCollisionShape(EntityID eid, Type colliderType, const SHPhysicsMaterial& physicsMaterial)
: type { colliderType } : type { colliderType }
, entityID { eid } , entityID { eid }
, isTrigger { false } , isTrigger { false }
, dirty { true } , dirty { true }
, shape { nullptr } , shape { nullptr }
, material { physicsMaterial } , material { physicsMaterial }
, collisionTag { SHCollisionTagMatrix::GetTag(0) }
{ {
switch (type) switch (type)
{ {
@ -57,6 +59,8 @@ namespace SHADE
, shape { nullptr } , shape { nullptr }
, material { rhs.material } , material { rhs.material }
, positionOffset { rhs.positionOffset } , positionOffset { rhs.positionOffset }
, rotationOffset { rhs.rotationOffset }
, collisionTag { rhs.collisionTag }
{ {
CopyShape(rhs.shape); CopyShape(rhs.shape);
} }
@ -69,6 +73,8 @@ namespace SHADE
, shape { nullptr } , shape { nullptr }
, material { rhs.material } , material { rhs.material }
, positionOffset { rhs.positionOffset } , positionOffset { rhs.positionOffset }
, rotationOffset { rhs.rotationOffset }
, collisionTag { rhs.collisionTag }
{ {
CopyShape(rhs.shape); CopyShape(rhs.shape);
} }
@ -93,6 +99,8 @@ namespace SHADE
dirty = true; dirty = true;
material = rhs.material; material = rhs.material;
positionOffset = rhs.positionOffset; positionOffset = rhs.positionOffset;
rotationOffset = rhs.rotationOffset;
collisionTag = rhs.collisionTag;
delete shape; delete shape;
CopyShape(rhs.shape); CopyShape(rhs.shape);
@ -108,6 +116,8 @@ namespace SHADE
dirty = true; dirty = true;
material = rhs.material; material = rhs.material;
positionOffset = rhs.positionOffset; positionOffset = rhs.positionOffset;
rotationOffset = rhs.rotationOffset;
collisionTag = rhs.collisionTag;
delete shape; delete shape;
CopyShape(rhs.shape); CopyShape(rhs.shape);
@ -134,6 +144,11 @@ namespace SHADE
return type; return type;
} }
const SHCollisionTag& SHCollisionShape::GetCollisionTag() const noexcept
{
return *collisionTag;
}
float SHCollisionShape::GetFriction() const noexcept float SHCollisionShape::GetFriction() const noexcept
{ {
return material.GetFriction(); return material.GetFriction();
@ -240,6 +255,12 @@ namespace SHADE
isTrigger = trigger; isTrigger = trigger;
} }
void SHCollisionShape::SetCollisionTag(SHCollisionTag* newCollisionTag) noexcept
{
dirty = true;
collisionTag = newCollisionTag;
}
void SHCollisionShape::SetFriction(float friction) noexcept void SHCollisionShape::SetFriction(float friction) noexcept
{ {
dirty = true; dirty = true;

View File

@ -17,6 +17,7 @@
#include "Math/Geometry/SHShape.h" #include "Math/Geometry/SHShape.h"
#include "Math/SHQuaternion.h" #include "Math/SHQuaternion.h"
#include "SHPhysicsMaterial.h" #include "SHPhysicsMaterial.h"
#include "Physics/Collision/SHCollisionTags.h"
namespace SHADE namespace SHADE
{ {
@ -74,6 +75,8 @@ namespace SHADE
[[nodiscard]] Type GetType () const noexcept; [[nodiscard]] Type GetType () const noexcept;
[[nodiscard]] const SHCollisionTag& GetCollisionTag () 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;
@ -92,6 +95,7 @@ namespace SHADE
void SetBoundingSphere (float radius); void SetBoundingSphere (float radius);
void SetIsTrigger (bool isTrigger) noexcept; void SetIsTrigger (bool isTrigger) noexcept;
void SetCollisionTag (SHCollisionTag* newCollisionTag) 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;
@ -109,11 +113,15 @@ namespace SHADE
EntityID entityID; // The entity this collider belongs to EntityID entityID; // The entity this collider belongs to
bool isTrigger; bool isTrigger;
bool dirty; bool dirty;
SHShape* shape; SHShape* shape;
SHPhysicsMaterial material; SHPhysicsMaterial material;
SHVec3 positionOffset; SHVec3 positionOffset;
SHVec3 rotationOffset; SHVec3 rotationOffset;
SHCollisionTag* collisionTag;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Function Members */ /* Function Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -322,25 +322,25 @@ namespace SHADE
// dirtyFlags |= 1U << FLAG_POS; // dirtyFlags |= 1U << FLAG_POS;
//} //}
void SHRigidBodyComponent::SetMass(float newMass) noexcept //void SHRigidBodyComponent::SetMass(float newMass) noexcept
{ //{
static constexpr int FLAG_POS = 9; // static constexpr int FLAG_POS = 9;
if (newMass < 0.0f) // if (newMass < 0.0f)
return; // return;
if (type != Type::DYNAMIC) // if (type != Type::DYNAMIC)
{ // {
SHLOG_WARNING("Cannot set mass of a non-dynamic object {}", GetEID()) // SHLOG_WARNING("Cannot set mass of a non-dynamic object {}", GetEID())
return; // return;
} // }
dirtyFlags |= 1U << FLAG_POS; // dirtyFlags |= 1U << FLAG_POS;
mass = newMass; // mass = newMass;
// Turn off automass // // Turn off automass
flags &= ~(1U << FLAG_POS); // flags &= ~(1U << FLAG_POS);
} //}
void SHRigidBodyComponent::SetDrag(float newDrag) noexcept void SHRigidBodyComponent::SetDrag(float newDrag) noexcept
{ {
@ -411,6 +411,13 @@ namespace SHADE
} }
system = physicsSystem; system = physicsSystem;
// Sync with transform if one already exists
if (auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(GetEID()); transformComponent)
{
position = transformComponent->GetWorldPosition();
orientation = transformComponent->GetWorldOrientation();
}
} }
void SHRigidBodyComponent::AddForce(const SHVec3& force) const noexcept void SHRigidBodyComponent::AddForce(const SHVec3& force) const noexcept
@ -489,7 +496,7 @@ RTTR_REGISTRATION
registration::class_<SHRigidBodyComponent>("RigidBody Component") registration::class_<SHRigidBodyComponent>("RigidBody Component")
.property("Type" , &SHRigidBodyComponent::GetType , &SHRigidBodyComponent::SetType ) .property("Type" , &SHRigidBodyComponent::GetType , &SHRigidBodyComponent::SetType )
.property("Mass" , &SHRigidBodyComponent::GetMass , &SHRigidBodyComponent::SetMass ) //.property("Mass" , &SHRigidBodyComponent::GetMass , &SHRigidBodyComponent::SetMass )
.property("Drag" , &SHRigidBodyComponent::GetDrag , &SHRigidBodyComponent::SetDrag ) .property("Drag" , &SHRigidBodyComponent::GetDrag , &SHRigidBodyComponent::SetDrag )
.property("Angular Drag" , &SHRigidBodyComponent::GetAngularDrag , &SHRigidBodyComponent::SetAngularDrag ) .property("Angular Drag" , &SHRigidBodyComponent::GetAngularDrag , &SHRigidBodyComponent::SetAngularDrag )
.property("Use Gravity" , &SHRigidBodyComponent::IsGravityEnabled , &SHRigidBodyComponent::SetGravityEnabled ) .property("Use Gravity" , &SHRigidBodyComponent::IsGravityEnabled , &SHRigidBodyComponent::SetGravityEnabled )

View File

@ -114,7 +114,7 @@ namespace SHADE
void SetInterpolate (bool allowInterpolation) noexcept; void SetInterpolate (bool allowInterpolation) noexcept;
//void SetAutoMass (bool autoMass) noexcept; //void SetAutoMass (bool autoMass) noexcept;
void SetMass (float newMass) noexcept; //void SetMass (float newMass) noexcept;
void SetDrag (float newDrag) noexcept; void SetDrag (float newDrag) noexcept;
void SetAngularDrag (float newAngularDrag) noexcept; void SetAngularDrag (float newAngularDrag) noexcept;

View File

@ -94,7 +94,7 @@ namespace SHADE
/* Public Function Member Definitions */ /* Public Function Member Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
int SHPhysicsObject::AddCollisionShape(int index) const int SHPhysicsObject::AddCollisionShape(int index)
{ {
// Get collider component // Get collider component
auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(entityID); auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(entityID);
@ -123,13 +123,19 @@ namespace SHADE
default: break; default: break;
} }
rp3dBody->updateLocalCenterOfMassFromColliders(); if (rp3dBody->getType() == rp3d::BodyType::DYNAMIC)
rp3dBody->updateLocalInertiaTensorFromColliders(); {
rp3dBody->updateMassPropertiesFromColliders();
auto* rigidBodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(entityID);
if (rigidBodyComponent)
rigidBodyComponent->mass = rp3dBody->getMass();
}
return index; return index;
} }
void SHPhysicsObject::RemoveCollisionShape(int index) const void SHPhysicsObject::RemoveCollisionShape(int index)
{ {
const int NUM_COLLIDERS = static_cast<int>(rp3dBody->getNbColliders()); const int NUM_COLLIDERS = static_cast<int>(rp3dBody->getNbColliders());
if (NUM_COLLIDERS == 0) if (NUM_COLLIDERS == 0)
@ -140,6 +146,15 @@ namespace SHADE
auto* collider = rp3dBody->getCollider(index); auto* collider = rp3dBody->getCollider(index);
rp3dBody->removeCollider(collider); rp3dBody->removeCollider(collider);
if (rp3dBody->getType() == rp3d::BodyType::DYNAMIC)
{
rp3dBody->updateMassPropertiesFromColliders();
auto* rigidBodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(entityID);
if (rigidBodyComponent)
rigidBodyComponent->mass = rp3dBody->getMass();
}
} }
void SHPhysicsObject::RemoveAllCollisionShapes() const noexcept void SHPhysicsObject::RemoveAllCollisionShapes() const noexcept
@ -254,6 +269,8 @@ namespace SHADE
} }
case 9: // Mass case 9: // Mass
{ {
//rp3dBody->setMass(component.mass);
//if (component.GetAutoMass()) //if (component.GetAutoMass())
//{ //{
// rp3dBody->updateMassPropertiesFromColliders(); // rp3dBody->updateMassPropertiesFromColliders();
@ -261,9 +278,9 @@ namespace SHADE
//} //}
//else //else
//{ //{
rp3dBody->setMass(component.mass); // rp3dBody->setMass(component.mass);
rp3dBody->updateLocalCenterOfMassFromColliders(); // rp3dBody->updateLocalCenterOfMassFromColliders();
rp3dBody->updateLocalInertiaTensorFromColliders(); // rp3dBody->updateLocalInertiaTensorFromColliders();
//} //}
break; break;
@ -309,7 +326,18 @@ namespace SHADE
default: break; default: break;
} }
syncMaterial(i, collisionShape); // Sync material
auto* rp3dCollider = rp3dBody->getCollider(i);
auto& rp3dMaterial = rp3dCollider->getMaterial();
rp3dMaterial.setFrictionCoefficient(collisionShape.GetFriction());
rp3dMaterial.setBounciness(collisionShape.GetBounciness());
rp3dMaterial.setMassDensity(collisionShape.GetDensity());
// Sync tags
const unsigned short MASK_BITS = collisionShape.GetCollisionTag();
rp3dCollider->setCollisionCategoryBits(MASK_BITS);
rp3dCollider->setCollideWithMaskBits(MASK_BITS);
collisionShape.dirty = false; collisionShape.dirty = false;
} }
@ -319,14 +347,6 @@ namespace SHADE
/* Private Function Member Definitions */ /* Private Function Member Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void SHPhysicsObject::syncMaterial(int colliderIndex, SHCollisionShape& collisionShape) const noexcept
{
auto& rp3dMaterial = rp3dBody->getCollider(colliderIndex)->getMaterial();
rp3dMaterial.setFrictionCoefficient(collisionShape.GetFriction());
rp3dMaterial.setBounciness(collisionShape.GetBounciness());
rp3dMaterial.setMassDensity(collisionShape.GetDensity());
}
void SHPhysicsObject::addBoxShape(SHCollisionShape& boxShape) const noexcept void SHPhysicsObject::addBoxShape(SHCollisionShape& boxShape) const noexcept
{ {
const rp3d::Transform OFFSETS const rp3d::Transform OFFSETS

View File

@ -71,8 +71,8 @@ namespace SHADE
/* Function Members */ /* Function Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
int AddCollisionShape (int index) const; int AddCollisionShape (int index);
void RemoveCollisionShape (int index) const; void RemoveCollisionShape (int index);
void RemoveAllCollisionShapes () const noexcept; void RemoveAllCollisionShapes () const noexcept;
void SyncRigidBody (SHRigidBodyComponent& component) const noexcept; void SyncRigidBody (SHRigidBodyComponent& component) const noexcept;
@ -96,16 +96,14 @@ namespace SHADE
/* Function Members */ /* Function Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void syncMaterial (int colliderIndex, SHCollisionShape& collisionShape) const noexcept;
// Box Shapes // Box Shapes
void addBoxShape (SHCollisionShape& boxShape) const noexcept; void addBoxShape (SHCollisionShape& boxShape) const noexcept;
void syncBoxShape (int index, SHCollisionShape& boxShape) const noexcept; void syncBoxShape (int index, SHCollisionShape& boxShape) const noexcept;
// Sphere Shapes // Sphere Shapes
void addSphereShape (SHCollisionShape& sphereShape) const noexcept; void addSphereShape (SHCollisionShape& sphereShape) const noexcept;
void syncSphereShape (int index, SHCollisionShape& sphereShape) const noexcept; void syncSphereShape (int index, SHCollisionShape& sphereShape) const noexcept;
}; };
} // namespace SHADE } // namespace SHADE

View File

@ -15,6 +15,7 @@
// Project Headers // Project Headers
#include "ECS_Base/Managers/SHSystemManager.h" #include "ECS_Base/Managers/SHSystemManager.h"
#include "Editor/SHEditor.h"
#include "Scene/SHSceneManager.h" #include "Scene/SHSceneManager.h"
namespace SHADE namespace SHADE
@ -118,11 +119,22 @@ namespace SHADE
return; return;
} }
rp3d::DebugRenderer* rp3dRenderer = nullptr;
#ifdef SHEDITOR
const auto* EDITOR = SHSystemManager::GetSystem<SHEditor>();
if (EDITOR && EDITOR->editorState != SHEditor::State::STOP)
{
rp3dRenderer = &system->physicsSystem->worldState.world->getDebugRenderer();
rp3dRenderer->setIsDebugItemDisplayed(rp3d::DebugRenderer::DebugItem::CONTACT_POINT, false);
rp3dRenderer->setIsDebugItemDisplayed(rp3d::DebugRenderer::DebugItem::CONTACT_NORMAL, false);
}
#endif
for (int i = 0; i < SHUtilities::ConvertEnum(DebugDrawFlags::NUM_FLAGS); ++i) for (int i = 0; i < SHUtilities::ConvertEnum(DebugDrawFlags::NUM_FLAGS); ++i)
{ {
const bool DRAW = (system->debugDrawFlags & (1U << i)) > 0; const bool DRAW = (system->debugDrawFlags & (1U << i)) > 0;
if (DRAW) if (DRAW)
drawFunctions[i](debugDrawSystem); drawFunctions[i](debugDrawSystem, rp3dRenderer);
} }
// Automatically clear the container of raycasts despite debug drawing state // Automatically clear the container of raycasts despite debug drawing state
@ -134,7 +146,7 @@ namespace SHADE
/* Private Function Member Definitions */ /* Private Function Member Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void SHPhysicsDebugDrawSystem::drawColliders(SHDebugDrawSystem* debugRenderer) noexcept void SHPhysicsDebugDrawSystem::drawColliders(SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept
{ {
const auto& COLLIDER_SET = SHComponentManager::GetDense<SHColliderComponent>(); const auto& COLLIDER_SET = SHComponentManager::GetDense<SHColliderComponent>();
for (const auto& COLLIDER : COLLIDER_SET) for (const auto& COLLIDER : COLLIDER_SET)
@ -155,27 +167,53 @@ namespace SHADE
} }
} }
void SHPhysicsDebugDrawSystem::drawColliderAABBs(SHDebugDrawSystem* debugRenderer) noexcept void SHPhysicsDebugDrawSystem::drawColliderAABBs(SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept
{ {
} }
void SHPhysicsDebugDrawSystem::drawBroadPhaseAABBs(SHDebugDrawSystem* debugRenderer) noexcept void SHPhysicsDebugDrawSystem::drawBroadPhaseAABBs(SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept
{ {
} }
void SHPhysicsDebugDrawSystem::drawContactPoints(SHDebugDrawSystem* debugRenderer) noexcept void SHPhysicsDebugDrawSystem::drawContactPoints(SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept
{ {
#ifdef SHEDITOR
const auto* EDITOR = SHSystemManager::GetSystem<SHEditor>();
if (EDITOR && EDITOR->editorState != SHEditor::State::STOP)
{
rp3dRenderer->setIsDebugItemDisplayed(rp3d::DebugRenderer::DebugItem::CONTACT_POINT, true);
const int NUM_TRIS = static_cast<int>(rp3dRenderer->getNbTriangles());
if (NUM_TRIS == 0)
return;
const auto& TRI_ARRAY = rp3dRenderer->getTrianglesArray();
for (int i = 0; i < NUM_TRIS; ++i)
debugRenderer->DrawTri(SHColour::RED, TRI_ARRAY[i].point1, TRI_ARRAY[i].point2, TRI_ARRAY[i].point3);
}
#endif
} }
void SHPhysicsDebugDrawSystem::drawContactNormals(SHDebugDrawSystem* debugRenderer) noexcept void SHPhysicsDebugDrawSystem::drawContactNormals(SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept
{ {
#ifdef SHEDITOR
const auto* EDITOR = SHSystemManager::GetSystem<SHEditor>();
if (EDITOR && EDITOR->editorState != SHEditor::State::STOP)
{
rp3dRenderer->setIsDebugItemDisplayed(rp3d::DebugRenderer::DebugItem::CONTACT_NORMAL, true);
const int NUM_LINES = static_cast<int>(rp3dRenderer->getNbLines());
if (NUM_LINES == 0)
return;
const auto& LINE_ARRAY = rp3dRenderer->getLinesArray();
for (int i = 0; i < NUM_LINES; ++i)
debugRenderer->DrawLine(SHColour::RED, LINE_ARRAY[i].point1, LINE_ARRAY[i].point2);
}
#endif
} }
void SHPhysicsDebugDrawSystem::drawRaycasts(SHDebugDrawSystem* debugRenderer) noexcept void SHPhysicsDebugDrawSystem::drawRaycasts(SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept
{ {
auto* physicsSystem = SHSystemManager::GetSystem<SHPhysicsSystem>(); auto* physicsSystem = SHSystemManager::GetSystem<SHPhysicsSystem>();
if (!physicsSystem) if (!physicsSystem)

View File

@ -93,7 +93,7 @@ namespace SHADE
/* Type Definitions */ /* Type Definitions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
using DebugDrawFunction = void(*)(SHDebugDrawSystem*) noexcept; using DebugDrawFunction = void(*)(SHDebugDrawSystem*, rp3d::DebugRenderer*) noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Data Members */ /* Data Members */
@ -118,12 +118,12 @@ namespace SHADE
// Generic Draw Functions // Generic Draw Functions
static void drawColliders (SHDebugDrawSystem* debugRenderer) noexcept; static void drawColliders (SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept;
static void drawColliderAABBs (SHDebugDrawSystem* debugRenderer) noexcept; static void drawColliderAABBs (SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept;
static void drawBroadPhaseAABBs (SHDebugDrawSystem* debugRenderer) noexcept; static void drawBroadPhaseAABBs (SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept;
static void drawContactPoints (SHDebugDrawSystem* debugRenderer) noexcept; static void drawContactPoints (SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept;
static void drawContactNormals (SHDebugDrawSystem* debugRenderer) noexcept; static void drawContactNormals (SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept;
static void drawRaycasts (SHDebugDrawSystem* debugRenderer) noexcept; static void drawRaycasts (SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept;
// Shape Generation Functions // Shape Generation Functions

View File

@ -14,10 +14,12 @@
#include "SHPhysicsSystem.h" #include "SHPhysicsSystem.h"
// Project Headers // Project Headers
#include "Assets/SHAssetMacros.h"
#include "ECS_Base/Managers/SHComponentManager.h" #include "ECS_Base/Managers/SHComponentManager.h"
#include "ECS_Base/Managers/SHEntityManager.h" #include "ECS_Base/Managers/SHEntityManager.h"
#include "ECS_Base/Managers/SHSystemManager.h" #include "ECS_Base/Managers/SHSystemManager.h"
#include "Editor/SHEditor.h" #include "Editor/SHEditor.h"
#include "Physics/Collision/SHCollisionTagMatrix.h"
#include "Physics/SHPhysicsEvents.h" #include "Physics/SHPhysicsEvents.h"
#include "Scene/SHSceneManager.h" #include "Scene/SHSceneManager.h"
#include "Scripting/SHScriptEngine.h" #include "Scripting/SHScriptEngine.h"
@ -90,6 +92,18 @@ namespace SHADE
void SHPhysicsSystem::Init() void SHPhysicsSystem::Init()
{ {
// Initialise collision tags
std::filesystem::path defaultCollisionTagNameFilePath { ASSET_ROOT };
defaultCollisionTagNameFilePath.append("CollisionTags.SHConfig");
SHCollisionTagMatrix::Init(defaultCollisionTagNameFilePath);
// Link Physics Object Manager with System & Raycaster
objectManager.SetFactory(factory);
raycaster.SetObjectManager(&objectManager);
// Link Collision Listener with System
collisionListener.BindToSystem(this);
// Subscribe to component events // Subscribe to component events
const std::shared_ptr ADD_COMPONENT_RECEIVER { std::make_shared<SHEventReceiverSpec<SHPhysicsSystem>>(this, &SHPhysicsSystem::addPhysicsComponent) }; const std::shared_ptr ADD_COMPONENT_RECEIVER { std::make_shared<SHEventReceiverSpec<SHPhysicsSystem>>(this, &SHPhysicsSystem::addPhysicsComponent) };
const ReceiverPtr ADD_COMPONENT_RECEIVER_PTR = std::dynamic_pointer_cast<SHEventReceiver>(ADD_COMPONENT_RECEIVER); const ReceiverPtr ADD_COMPONENT_RECEIVER_PTR = std::dynamic_pointer_cast<SHEventReceiver>(ADD_COMPONENT_RECEIVER);
@ -111,17 +125,66 @@ namespace SHADE
SHEventManager::SubscribeTo(SH_EDITOR_ON_STOP_EVENT, ON_STOP_RECEIVER_PTR); SHEventManager::SubscribeTo(SH_EDITOR_ON_STOP_EVENT, ON_STOP_RECEIVER_PTR);
#endif #endif
// Link Physics Object Manager with System & Raycaster
objectManager.SetFactory(factory);
raycaster.SetObjectManager(&objectManager);
// Link Collision Listener with System
collisionListener.BindToSystem(this);
} }
void SHPhysicsSystem::Exit() void SHPhysicsSystem::Exit()
{ {
worldState.DestroyWorld(factory); worldState.DestroyWorld(factory);
// Write collision tag names to file
std::filesystem::path defaultCollisionTagNameFilePath { ASSET_ROOT };
defaultCollisionTagNameFilePath.append("CollisionTags.SHConfig");
SHCollisionTagMatrix::Exit(defaultCollisionTagNameFilePath);
}
void SHPhysicsSystem::BuildScene(SHSceneGraph& sceneGraph)
{
static const auto BUILD_NEW_SCENE_PHYSICS_OBJECT = [&](SHSceneNode* node)
{
const EntityID EID = node->GetEntityID();
if (SHComponentManager::HasComponent<SHRigidBodyComponent>(EID))
objectManager.AddRigidBody(EID);
if (SHComponentManager::HasComponent<SHColliderComponent>(EID))
objectManager.AddCollider(EID);
};
////////////////////////////////
// Destroy an existing world
if (worldState.world != nullptr)
{
objectManager.RemoveAllObjects();
objectManager.SetWorld(nullptr);
collisionListener.ClearContainers();
raycaster.ClearFrame();
worldState.DestroyWorld(factory);
}
worldState.CreateWorld(factory);
#ifdef _PUBLISH
worldState.world->setIsDebugRenderingEnabled(false);
#else
worldState.world->setIsDebugRenderingEnabled(true);
#endif
// Link Collision Listener & Raycaster
collisionListener.BindToWorld(worldState.world);
raycaster.BindToWorld(worldState.world);
// Link with object manager & create all physics objects
objectManager.SetWorld(worldState.world);
// When building a scene, clear the object manager command queue and build scene objects again.
// This is done to avoid duplicate adds.
while (!objectManager.commandQueue.empty())
objectManager.commandQueue.pop();
sceneGraph.Traverse(BUILD_NEW_SCENE_PHYSICS_OBJECT);
} }
void SHPhysicsSystem::ForceUpdate() void SHPhysicsSystem::ForceUpdate()
@ -216,10 +279,13 @@ namespace SHADE
{ {
objectManager.AddCollisionShape(entityID, index); objectManager.AddCollisionShape(entityID, index);
auto* colliderComponent = SHComponentManager::GetComponent<SHColliderComponent>(entityID);
auto& collisionShape = colliderComponent->GetCollisionShape(index);
const SHPhysicsColliderAddedEvent COLLIDER_ADDED_EVENT_DATA const SHPhysicsColliderAddedEvent COLLIDER_ADDED_EVENT_DATA
{ {
.entityID = entityID .entityID = entityID
, .colliderType = SHComponentManager::GetComponent<SHColliderComponent>(entityID)->GetCollisionShape(index).GetType() , .colliderType = collisionShape.GetType()
, .colliderIndex = index , .colliderIndex = index
}; };
@ -355,6 +421,11 @@ namespace SHADE
return onPlayEvent->handle; return onPlayEvent->handle;
worldState.CreateWorld(factory); worldState.CreateWorld(factory);
#ifdef _PUBLISH
worldState.world->setIsDebugRenderingEnabled(false);
#else
worldState.world->setIsDebugRenderingEnabled(true);
#endif
// Link Collision Listener & Raycaster // Link Collision Listener & Raycaster
collisionListener.BindToWorld(worldState.world); collisionListener.BindToWorld(worldState.world);
@ -363,8 +434,8 @@ namespace SHADE
// Link with object manager & create all physics objects // Link with object manager & create all physics objects
objectManager.SetWorld(worldState.world); objectManager.SetWorld(worldState.world);
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph(); // Build scene
SCENE_GRAPH.Traverse(BUILD_PHYSICS_OBJECT); SHSceneManager::GetCurrentSceneGraph().Traverse(BUILD_PHYSICS_OBJECT);
return onPlayEvent->handle; return onPlayEvent->handle;
} }
@ -378,11 +449,11 @@ namespace SHADE
// Clear all collision info // Clear all collision info
// Collision listener is automatically unbound when world is destroyed // Collision listener is automatically unbound when world is destroyed
collisionListener.ClearContainers(); collisionListener.ClearContainers();
raycaster.ClearFrame();
// Destroy the world // Destroy the world
worldState.DestroyWorld(factory); worldState.DestroyWorld(factory);
return onStopEvent->handle; return onStopEvent->handle;
} }
} // namespace SHADE } // namespace SHADE

View File

@ -27,7 +27,7 @@
#include "Physics/Interface/SHColliderComponent.h" #include "Physics/Interface/SHColliderComponent.h"
#include "Physics/PhysicsObject/SHPhysicsObjectManager.h" #include "Physics/PhysicsObject/SHPhysicsObjectManager.h"
#include "Physics/SHPhysicsWorld.h" #include "Physics/SHPhysicsWorld.h"
#include "Scene/SHSceneGraph.h"
namespace SHADE namespace SHADE
{ {
@ -74,10 +74,12 @@ namespace SHADE
/* Function Members */ /* Function Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void Init () override; void Init () override;
void Exit () override; void Exit () override;
void BuildScene (SHSceneGraph& sceneGraph);
void ForceUpdate ();
void ForceUpdate ();
/** /**
* @brief Casts a ray into the world. * @brief Casts a ray into the world.
@ -280,11 +282,11 @@ namespace SHADE
/* Function Members */ /* Function Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
SHEventHandle addPhysicsComponent (SHEventPtr addComponentEvent) noexcept; SHEventHandle addPhysicsComponent (SHEventPtr addComponentEvent) noexcept;
SHEventHandle removePhysicsComponent (SHEventPtr removeComponentEvent) noexcept; SHEventHandle removePhysicsComponent (SHEventPtr removeComponentEvent) noexcept;
SHEventHandle onPlay (SHEventPtr onPlayEvent);
SHEventHandle onStop (SHEventPtr onStopEvent);
SHEventHandle onPlay (SHEventPtr onPlayEvent);
SHEventHandle onStop (SHEventPtr onStopEvent);
SHEventHandle buildScene (SHEventPtr onSceneChangeEvent);
}; };
} // namespace SHADE } // namespace SHADE

View File

@ -1,7 +1,7 @@
/**************************************************************************************** /****************************************************************************************
* \file SHSceneGraphEvents.h * \file SHSceneEvents.h
* \author Diren D Bharwani, diren.dbharwani, 390002520 * \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Interface for Scene Graph Events. * \brief Interface for Scene Events.
* *
* \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
* disclosure of this file or its contents without the prior written consent * disclosure of this file or its contents without the prior written consent
@ -21,21 +21,21 @@ namespace SHADE
struct SHSceneGraphChangeParentEvent struct SHSceneGraphChangeParentEvent
{ {
SHSceneNode* node; SHSceneNode* node = nullptr;
SHSceneNode* oldParent; SHSceneNode* oldParent = nullptr;
SHSceneNode* newParent; SHSceneNode* newParent = nullptr;
}; };
struct SHSceneGraphAddChildEvent struct SHSceneGraphAddChildEvent
{ {
SHSceneNode* parent; SHSceneNode* parent = nullptr;
SHSceneNode* childAdded; SHSceneNode* childAdded = nullptr;
}; };
struct SHSceneGraphRemoveChildEvent struct SHSceneGraphRemoveChildEvent
{ {
SHSceneNode* parent; SHSceneNode* parent = nullptr;
SHSceneNode* childRemoved; SHSceneNode* childRemoved = nullptr;
}; };
} // namespace SHADE } // namespace SHADE

View File

@ -16,7 +16,7 @@
#include "ECS_Base/Entity/SHEntity.h" #include "ECS_Base/Entity/SHEntity.h"
#include "SH_API.h" #include "SH_API.h"
#include "SHSceneNode.h" #include "SHSceneNode.h"
#include "SHSceneGraphEvents.h" #include "SHSceneEvents.h"
namespace SHADE namespace SHADE
{ {

View File

@ -85,7 +85,6 @@ namespace SHADE
currentScene->Load(); currentScene->Load();
currentScene->Init(); currentScene->Init();
} }
} }
else // restarting scene else // restarting scene
{ {

View File

@ -27,7 +27,7 @@ of DigiPen Institute of Technology is prohibited.
#include "Events/SHEventManager.hpp" #include "Events/SHEventManager.hpp"
#include "Physics/System/SHPhysicsSystem.h" #include "Physics/System/SHPhysicsSystem.h"
#include "Physics/SHPhysicsEvents.h" #include "Physics/SHPhysicsEvents.h"
#include "Scene/SHSceneGraphEvents.h" #include "Scene/SHSceneEvents.h"
#include "Assets/SHAssetMacros.h" #include "Assets/SHAssetMacros.h"

View File

@ -211,6 +211,7 @@ namespace SHADE
AddComponentToComponentNode<SHLightComponent>(components, eid); AddComponentToComponentNode<SHLightComponent>(components, eid);
AddComponentToComponentNode<SHRigidBodyComponent>(components, eid); AddComponentToComponentNode<SHRigidBodyComponent>(components, eid);
AddConvComponentToComponentNode<SHColliderComponent>(components, eid); AddConvComponentToComponentNode<SHColliderComponent>(components, eid);
AddConvComponentToComponentNode<SHTextRenderableComponent>(components, eid);
node[ComponentsNode] = components; node[ComponentsNode] = components;
@ -262,6 +263,7 @@ namespace SHADE
AddComponentID<SHRigidBodyComponent>(componentIDList, componentsNode); AddComponentID<SHRigidBodyComponent>(componentIDList, componentsNode);
AddComponentID<SHLightComponent>(componentIDList, componentsNode); AddComponentID<SHLightComponent>(componentIDList, componentsNode);
AddComponentID<SHColliderComponent>(componentIDList, componentsNode); AddComponentID<SHColliderComponent>(componentIDList, componentsNode);
AddComponentID<SHTextRenderableComponent>(componentIDList, componentsNode);
return componentIDList; return componentIDList;
} }
@ -338,6 +340,7 @@ namespace SHADE
SHSerializationHelper::InitializeComponentFromNode<SHRigidBodyComponent>(componentsNode, eid); SHSerializationHelper::InitializeComponentFromNode<SHRigidBodyComponent>(componentsNode, eid);
SHSerializationHelper::ConvertNodeToComponent<SHRenderable>(componentsNode, eid); SHSerializationHelper::ConvertNodeToComponent<SHRenderable>(componentsNode, eid);
SHSerializationHelper::ConvertNodeToComponent<SHColliderComponent>(componentsNode, eid); SHSerializationHelper::ConvertNodeToComponent<SHColliderComponent>(componentsNode, eid);
SHSerializationHelper::ConvertNodeToComponent<SHTextRenderableComponent>(componentsNode, eid);
SHSerializationHelper::InitializeComponentFromNode<SHLightComponent>(componentsNode, eid); SHSerializationHelper::InitializeComponentFromNode<SHLightComponent>(componentsNode, eid);
} }
} }

View File

@ -12,6 +12,9 @@
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h" #include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
#include "SHSerializationTools.h" #include "SHSerializationTools.h"
#include "Physics/Interface/SHColliderComponent.h" #include "Physics/Interface/SHColliderComponent.h"
#include "Graphics/MiddleEnd/TextRendering/SHTextRenderableComponent.h"
#include "Graphics/MiddleEnd/TextRendering/SHFont.h"
namespace YAML namespace YAML
{ {
using namespace SHADE; using namespace SHADE;
@ -113,6 +116,7 @@ namespace YAML
static constexpr const char* Bounciness = "Bounciness"; static constexpr const char* Bounciness = "Bounciness";
static constexpr const char* Density = "Density"; static constexpr const char* Density = "Density";
static constexpr const char* PositionOffset = "Position Offset"; static constexpr const char* PositionOffset = "Position Offset";
static constexpr const char* RotationOffset = "Rotation Offset";
static Node encode(SHCollisionShape& rhs) static Node encode(SHCollisionShape& rhs)
{ {
@ -148,6 +152,7 @@ namespace YAML
node[Bounciness] = rhs.GetBounciness(); node[Bounciness] = rhs.GetBounciness();
node[Density] = rhs.GetDensity(); node[Density] = rhs.GetDensity();
node[PositionOffset] = rhs.GetPositionOffset(); node[PositionOffset] = rhs.GetPositionOffset();
node[RotationOffset] = rhs.GetRotationOffset();
return node; return node;
} }
@ -188,6 +193,8 @@ namespace YAML
rhs.SetDensity(node[Density].as<float>()); rhs.SetDensity(node[Density].as<float>());
if (node[PositionOffset].IsDefined()) if (node[PositionOffset].IsDefined())
rhs.SetPositionOffset(node[PositionOffset].as<SHVec3>()); rhs.SetPositionOffset(node[PositionOffset].as<SHVec3>());
if (node[RotationOffset].IsDefined())
rhs.SetRotationOffset(node[RotationOffset].as<SHVec3>());
return true; return true;
} }
@ -322,4 +329,45 @@ namespace YAML
return true; return true;
} }
}; };
template<>
struct convert<SHTextRenderableComponent>
{
static constexpr std::string_view TEXT_YAML_TAG = "Text";
static constexpr std::string_view FONT_YAML_TAG = "Font";
static YAML::Node encode(SHTextRenderableComponent const& rhs)
{
YAML::Node node;
node[TEXT_YAML_TAG.data()] = rhs.GetText();
auto font = rhs.GetFont();
if (font)
{
node[FONT_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHFont>(rhs.GetFont()).value_or(0);
}
else
{
node[FONT_YAML_TAG.data()] = 0;
}
return node;
}
static bool decode(YAML::Node const& node, SHTextRenderableComponent& rhs)
{
if (node[TEXT_YAML_TAG.data()].IsDefined())
{
rhs.SetText(node[TEXT_YAML_TAG.data()].as<std::string>());
}
if (node[FONT_YAML_TAG.data()].IsDefined())
{
// Temporarily, use default material
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
if (!gfxSystem)
return false;
rhs.SetFont(SHResourceManager::LoadOrGet<SHFont>(node[TEXT_YAML_TAG.data()].as<AssetID>()));
}
return true;
}
};
} }

View File

@ -33,6 +33,8 @@ project "SHADE_Managed"
"%{IncludeDir.imgui}", "%{IncludeDir.imgui}",
"%{IncludeDir.imguizmo}", "%{IncludeDir.imguizmo}",
"%{IncludeDir.imnodes}", "%{IncludeDir.imnodes}",
"%{IncludeDir.msdf_atlas_gen}",
"%{IncludeDir.msdfgen}",
"%{IncludeDir.yamlcpp}", "%{IncludeDir.yamlcpp}",
"%{IncludeDir.SDL}\\include", "%{IncludeDir.SDL}\\include",
"%{IncludeDir.RTTR}/include", "%{IncludeDir.RTTR}/include",
@ -53,6 +55,8 @@ project "SHADE_Managed"
links links
{ {
"yaml-cpp", "yaml-cpp",
"msdfgen",
"msdf-atlas-gen",
"imgui", "imgui",
"SDL2.lib", "SDL2.lib",
"SDL2main.lib", "SDL2main.lib",
@ -62,7 +66,11 @@ project "SHADE_Managed"
disablewarnings disablewarnings
{ {
"4251" "4251",
"4633",
"4634",
"4635",
"4638"
} }
defines defines
@ -85,6 +93,8 @@ project "SHADE_Managed"
dependson dependson
{ {
"yaml-cpp", "yaml-cpp",
"msdfgen",
"msdf-atlas-gen",
"imgui", "imgui",
"SHADE_Engine" "SHADE_Engine"
} }

View File

@ -0,0 +1,32 @@
/************************************************************************************//*!
\file Font.cxx
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 28, 2022
\brief Contains the implementation of the functions of the managed Font class.
Note: This file is written in C++17/CLI.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
// Precompiled Headers
#include "SHpch.h"
// Primary Header
#include "Font.hxx"
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* Explicit Template Instantiation */
/*---------------------------------------------------------------------------------*/
template ref class NativeAsset<SHFont>;
/*---------------------------------------------------------------------------------*/
/* Constructors/Destructor */
/*---------------------------------------------------------------------------------*/
Font::Font(Handle<SHFont> font)
: NativeAsset<SHFont> { font }
{}
}

View File

@ -0,0 +1,41 @@
/************************************************************************************//*!
\file Font.hxx
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 28, 2022
\brief Contains the definition of the managed Font class.
Note: This file is written in C++17/CLI.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
// External Dependencies
#include "Resource/SHHandle.h"
#include "Graphics/MiddleEnd/TextRendering/SHFont.h"
// Project Includes
#include "NativeAsset.hxx"
#include "Engine/GenericHandle.hxx"
namespace SHADE
{
/// <summary>
/// Managed counterpart of the native Font object that can be fed to TextRenderables
/// for rendering.
/// </summary>
public ref class Font : public NativeAsset<SHFont>
{
internal:
/*-----------------------------------------------------------------------------*/
/* Constructors/Destructor */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Constructor for the Font.
/// </summary>
/// <param name="font">Handle to the font object.</param>
Font(Handle<SHFont> font);
};
}

View File

@ -21,6 +21,17 @@ of DigiPen Institute of Technology is prohibited.
namespace SHADE namespace SHADE
{ {
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Explicit Tempalte Instantiations */ /* Properties */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
GenericHandle Asset::NativeObjectHandle::get()
{
return nativeObjHandle;
}
/*---------------------------------------------------------------------------------*/
/* Constructors */
/*---------------------------------------------------------------------------------*/
Asset::Asset(Handle<void> nativeHandle)
: nativeObjHandle { Convert::ToCLI(Handle<void>(nativeHandle)) }
{}
} }

View File

@ -16,6 +16,7 @@ of DigiPen Institute of Technology is prohibited.
// Primary Include // Primary Include
#include "NativeAsset.hxx" #include "NativeAsset.hxx"
#include "Utility/Convert.hxx"
namespace SHADE namespace SHADE
{ {
@ -23,11 +24,6 @@ namespace SHADE
/* Properties */ /* Properties */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
template <typename NativeAssetType> template <typename NativeAssetType>
GenericHandle NativeAsset<NativeAssetType>::NativeObjectHandle::get()
{
return nativeObjHandle;
}
template <typename NativeAssetType>
Handle<NativeAssetType> NativeAsset<NativeAssetType>::NativeObject::get() Handle<NativeAssetType> NativeAsset<NativeAssetType>::NativeObject::get()
try try
{ {
@ -43,7 +39,6 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
template <typename NativeAssetType> template <typename NativeAssetType>
NativeAsset<NativeAssetType>::NativeAsset(Handle<NativeAssetType> nativeObj) NativeAsset<NativeAssetType>::NativeAsset(Handle<NativeAssetType> nativeObj)
: nativeObjHandle{ Convert::ToCLI(Handle<void>(nativeObj)) } : Asset { Handle<void>(nativeObj) }
{} {}
} }

View File

@ -19,13 +19,9 @@ of DigiPen Institute of Technology is prohibited.
namespace SHADE namespace SHADE
{ {
/// <summary> /// <summary>
/// Generalised template class for a managed representation of a native asset /// Abstract base class that all Native Assets will inherit from.
/// </summary> /// </summary>
/// <typeparam name="NativeAssetType"> public ref class Asset abstract
/// The type of the asset's native representation.
/// </typeparam>
template<typename NativeAssetType>
public ref class NativeAsset
{ {
internal: internal:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -38,6 +34,36 @@ namespace SHADE
{ {
GenericHandle get(); GenericHandle get();
} }
/*-----------------------------------------------------------------------------*/
/* Constructors/Destructor */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Constructor for the asset.
/// </summary>
/// <param name="ptr">Native asset object handle.</param>
Asset(Handle<void> nativeHandle);
protected:
/*-----------------------------------------------------------------------------*/
/* Data Members */
/*-----------------------------------------------------------------------------*/
GenericHandle nativeObjHandle;
};
/// <summary>
/// Generalised template class for a managed representation of a native asset
/// </summary>
/// <typeparam name="NativeAssetType">
/// The type of the asset's native representation.
/// </typeparam>
template<typename NativeAssetType>
public ref class NativeAsset abstract : Asset
{
internal:
/*-----------------------------------------------------------------------------*/
/* Properties */
/*-----------------------------------------------------------------------------*/
/// <summary> /// <summary>
/// Copy of the Handle to the native object. /// Copy of the Handle to the native object.
/// </summary> /// </summary>
@ -52,14 +78,8 @@ namespace SHADE
/// <summary> /// <summary>
/// Constructor for the native asset /// Constructor for the native asset
/// </summary> /// </summary>
/// <param name="ptr">Native asset object.</param> /// <param name="ptr">Native asset object handle.</param>
NativeAsset(Handle<NativeAssetType> ptr); NativeAsset(Handle<NativeAssetType> ptr);
protected:
/*-----------------------------------------------------------------------------*/
/* Data Members */
/*-----------------------------------------------------------------------------*/
GenericHandle nativeObjHandle;
}; };
} }

View File

@ -58,7 +58,7 @@ namespace SHADE
} }
void RigidBody::Mass::set(float value) void RigidBody::Mass::set(float value)
{ {
return GetNativeComponent()->SetMass(value); /*return GetNativeComponent()->SetMass(value);*/
} }
float RigidBody::Drag::get() float RigidBody::Drag::get()
{ {

View File

@ -0,0 +1,57 @@
/************************************************************************************//*!
\file TextRenderable.cxx
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 28, 2022
\brief Contains the definition of the functions of the managed TextRenderable
class.
Note: This file is written in C++17/CLI.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
// Precompiled Headers
#include "SHpch.h"
// Primary Header
#include "TextRenderable.hxx"
#include "Assets/NativeAsset.hxx"
#include "Utility/Convert.hxx"
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* Constructors */
/*---------------------------------------------------------------------------------*/
TextRenderable::TextRenderable(Entity entity)
: Component(entity)
{}
/*---------------------------------------------------------------------------------*/
/* Properties */
/*---------------------------------------------------------------------------------*/
System::String^ TextRenderable::Text::get()
{
return Convert::ToCLI(GetNativeComponent()->GetText());
}
void TextRenderable::Text::set(System::String^ value)
{
GetNativeComponent()->SetText(Convert::ToNative(value));
}
SHADE::Font^ TextRenderable::Font::get()
{
return gcnew SHADE::Font(GetNativeComponent()->GetFont());
}
void TextRenderable::Font::set(SHADE::Font^ value)
{
if (value == nullptr)
{
GetNativeComponent()->SetFont(Handle<SHFont>());
}
else
{
GetNativeComponent()->SetFont(Handle<SHFont>(Convert::ToNative(value->NativeObjectHandle)));
}
}
}

View File

@ -0,0 +1,65 @@
/************************************************************************************//*!
\file TextRenderable.hxx
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Nov 21, 2022
\brief Contains the definition of the managed TextRenderable class with the
declaration of functions for working with it.
Note: This file is written in C++17/CLI.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
// External Dependencies
#include "Graphics/MiddleEnd/TextRendering/SHTextRenderableComponent.h"
// Project Includes
#include "Components/Component.hxx"
#include "Math/Vector3.hxx"
#include "Math/Quaternion.hxx"
#include "Assets/Font.hxx"
namespace SHADE
{
/// <summary>
/// CLR version of the SHADE Engine's SHTextRenderableComponent.
/// </summary>
public ref class TextRenderable : public Component<SHTextRenderableComponent>
{
internal:
/*-----------------------------------------------------------------------------*/
/* Constructors */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Constructs a TextRenderable Component that represents a native TextRenderable
/// component tied to the specified Entity.
/// </summary>
/// <param name="entity">Entity that this Component will be tied to.</param>
TextRenderable(Entity entity);
public:
/*-----------------------------------------------------------------------------*/
/* Properties */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Text to render using this TextRenderable.
/// </summary>
property System::String^ Text
{
System::String^ get();
void set(System::String^ value);
}
/// <summary>
/// Font to use to render using this TextRenderable.
/// </summary>
property SHADE::Font^ Font
{
SHADE::Font^ get();
void set(SHADE::Font^ value);
}
};
}

View File

@ -117,6 +117,12 @@ namespace SHADE
// Header // Header
SHEditorUI::PushID(index); SHEditorUI::PushID(index);
bool enabled = script->Enabled;
if (SHEditorUI::InputCheckbox("", enabled))
{
script->Enabled = enabled;
}
SHEditorUI::SameLine();
if (SHEditorUI::CollapsingHeader(LABEL)) if (SHEditorUI::CollapsingHeader(LABEL))
{ {
SHEditorUI::PushID(LABEL); SHEditorUI::PushID(LABEL);

View File

@ -54,6 +54,14 @@ namespace SHADE
return GameObject(ENTITY_ID); return GameObject(ENTITY_ID);
} }
/*---------------------------------------------------------------------------------*/
/* Static Properties */
/*---------------------------------------------------------------------------------*/
GameObject GameObject::Null::get()
{
return GameObject();
}
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Properties */ /* Properties */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -62,6 +62,17 @@ namespace SHADE
/// <returns>GameObject that has the specified name. Null if not found.</returns> /// <returns>GameObject that has the specified name. Null if not found.</returns>
static System::Nullable<GameObject> Find(System::String^ name); static System::Nullable<GameObject> Find(System::String^ name);
/*-----------------------------------------------------------------------------*/
/* Static Properties */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Default empty GameObject.
/// </summary>
static property GameObject Null
{
GameObject get();
}
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Properties */ /* Properties */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/

View File

@ -22,6 +22,36 @@ of DigiPen Institute of Technology is prohibited.
namespace SHADE namespace SHADE
{ {
/*---------------------------------------------------------------------------------*/
/* Properties */
/*---------------------------------------------------------------------------------*/
GameObject Script::Owner::get()
{
return owner;
}
GameObject Script::GameObject::get()
{
return owner;
}
bool Script::Enabled::get()
{
return enabled;
}
void Script::Enabled::set(bool value)
{
// Same, don't set
if (value == enabled)
return;
enabled = value;
// There's a change, so call the appropriate function
if (enabled)
OnEnable();
else
OnDisable();
}
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Component Access Functions */ /* Component Access Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -104,11 +134,10 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* "All-time" Lifecycle Functions */ /* "All-time" Lifecycle Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void Script::Initialize(GameObject newOwner) void Script::Initialize(SHADE::GameObject newOwner)
{ {
owner = newOwner; owner = newOwner;
} }
void Script::OnAttached() void Script::OnAttached()
{ {
SAFE_NATIVE_CALL_BEGIN SAFE_NATIVE_CALL_BEGIN
@ -131,6 +160,12 @@ namespace SHADE
awake(); awake();
SAFE_NATIVE_CALL_END(this) SAFE_NATIVE_CALL_END(this)
} }
void Script::OnEnable()
{
SAFE_NATIVE_CALL_BEGIN
onEnable();
SAFE_NATIVE_CALL_END(this)
}
void Script::Start() void Script::Start()
{ {
SAFE_NATIVE_CALL_BEGIN SAFE_NATIVE_CALL_BEGIN
@ -162,6 +197,12 @@ namespace SHADE
onDrawGizmos(); onDrawGizmos();
SAFE_NATIVE_CALL_END(this) SAFE_NATIVE_CALL_END(this)
} }
void Script::OnDisable()
{
SAFE_NATIVE_CALL_BEGIN
onDisable();
SAFE_NATIVE_CALL_END(this)
}
void Script::OnDestroy() void Script::OnDestroy()
{ {
SAFE_NATIVE_CALL_BEGIN SAFE_NATIVE_CALL_BEGIN
@ -228,6 +269,7 @@ namespace SHADE
/* Virtual Lifecycle Functions */ /* Virtual Lifecycle Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void Script::awake() {} void Script::awake() {}
void Script::onEnable() {}
void Script::start() {} void Script::start() {}
void Script::fixedUpdate() {} void Script::fixedUpdate() {}
void Script::update() {} void Script::update() {}
@ -236,6 +278,7 @@ namespace SHADE
{ {
OnGizmosDrawOverriden = false; OnGizmosDrawOverriden = false;
} }
void Script::onDisable() {}
void Script::onDestroy() {} void Script::onDestroy() {}
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -38,11 +38,28 @@ namespace SHADE
/* Properties */ /* Properties */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/// <summary> /// <summary>
/// GameObject that this Script belongs to. This is a legacy interface, use
/// GameObject instead.
/// </summary>
[System::ObsoleteAttribute("Use GameObject instead.", false)]
property SHADE::GameObject Owner
{
SHADE::GameObject get();
}
/// <summary>
/// GameObject that this Script belongs to. /// GameObject that this Script belongs to.
/// </summary> /// </summary>
property GameObject Owner property SHADE::GameObject GameObject
{ {
GameObject get() { return owner; } SHADE::GameObject get();
}
/// <summary>
/// Whether or not this Script should have it's update functions be executed.
/// </summary>
property bool Enabled
{
bool get();
void set(bool value);
} }
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -127,7 +144,7 @@ namespace SHADE
/// </summary> /// </summary>
/// <typeparam name="T"> /// <typeparam name="T">
/// Type of script to get. /// Type of script to get.
/// This needs to be a default constructable Script. /// This needs to be a default constructible Script.
/// </typeparam> /// </typeparam>
/// <returns>Reference to the script added</returns> /// <returns>Reference to the script added</returns>
generic<typename T> where T : ref class, Script generic<typename T> where T : ref class, Script
@ -206,7 +223,7 @@ namespace SHADE
/// <summary> /// <summary>
/// Used to initialize a Script with a GameObject. /// Used to initialize a Script with a GameObject.
/// </summary> /// </summary>
void Initialize(GameObject newOwner); void Initialize(SHADE::GameObject newOwner);
/// <summary> /// <summary>
/// Used to call onAttached(). This is called immediately when this script is /// Used to call onAttached(). This is called immediately when this script is
/// attached to a GameObject. /// attached to a GameObject.
@ -232,6 +249,11 @@ namespace SHADE
/// </summary> /// </summary>
void Start(); void Start();
/// <summary> /// <summary>
/// Used to call onEnable. This should be called right when a script is enabled
/// directly.
/// </summary>
void OnEnable();
/// <summary>
/// Used to call fixedUpdate(). This should be called in sync with Physics /// Used to call fixedUpdate(). This should be called in sync with Physics
/// update steps and thus in most cases will execute more than Update() will. /// update steps and thus in most cases will execute more than Update() will.
/// This will be called immediately before a Physics update step. /// This will be called immediately before a Physics update step.
@ -253,6 +275,11 @@ namespace SHADE
/// </summary> /// </summary>
void OnDrawGizmos(); void OnDrawGizmos();
/// <summary> /// <summary>
/// Used to call onDisable. This should be called right when a script is disabled
/// directly.
/// </summary>
void OnDisable();
/// <summary>
/// Used to call onDestroy(). This should be called at the end of the frame /// Used to call onDestroy(). This should be called at the end of the frame
/// where the attached GameObject or this script is destroyed directly or /// where the attached GameObject or this script is destroyed directly or
/// indirectly due to destruction of the owner. /// indirectly due to destruction of the owner.
@ -329,6 +356,10 @@ namespace SHADE
/// </summary> /// </summary>
virtual void awake(); virtual void awake();
/// <summary> /// <summary>
/// Called when this script is enabled.
/// </summary>
virtual void onEnable();
/// <summary>
/// Called on the first frame that the attached GameObject is active but always /// Called on the first frame that the attached GameObject is active but always
/// after Awake(). /// after Awake().
/// </summary> /// </summary>
@ -353,6 +384,10 @@ namespace SHADE
/// </summary> /// </summary>
virtual void onDrawGizmos(); virtual void onDrawGizmos();
/// <summary> /// <summary>
/// Called when this script is disabled.
/// </summary>
virtual void onDisable();
/// <summary>
/// Called just before the end of the frame where the attached GameObject or /// Called just before the end of the frame where the attached GameObject or
/// this script is destroyed directly or indirectly due to destruction of the /// this script is destroyed directly or indirectly due to destruction of the
/// owner. /// owner.
@ -403,7 +438,8 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Data Members */ /* Data Members */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
GameObject owner; SHADE::GameObject owner;
bool enabled = true;
}; };
} }

View File

@ -528,7 +528,8 @@ namespace SHADE
ScriptList^ scripts = entity.Value; ScriptList^ scripts = entity.Value;
for (int i = 0; i < scripts->Count; ++i) for (int i = 0; i < scripts->Count; ++i)
{ {
scripts[i]->FixedUpdate(); if (scripts[i]->Enabled)
scripts[i]->FixedUpdate();
} }
} }
SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore") SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
@ -546,7 +547,8 @@ namespace SHADE
ScriptList^ scripts = entity.Value; ScriptList^ scripts = entity.Value;
for (int i = 0; i < scripts->Count; ++i) for (int i = 0; i < scripts->Count; ++i)
{ {
scripts[i]->Update(); if (scripts[i]->Enabled)
scripts[i]->Update();
} }
} }
SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore") SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
@ -564,7 +566,8 @@ namespace SHADE
ScriptList^ scripts = entity.Value; ScriptList^ scripts = entity.Value;
for (int i = 0; i < scripts->Count; ++i) for (int i = 0; i < scripts->Count; ++i)
{ {
scripts[i]->LateUpdate(); if (scripts[i]->Enabled)
scripts[i]->LateUpdate();
} }
} }
SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore") SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
@ -583,7 +586,8 @@ namespace SHADE
ScriptList^ scripts = entity.Value; ScriptList^ scripts = entity.Value;
for (int i = 0; i < scripts->Count; ++i) for (int i = 0; i < scripts->Count; ++i)
{ {
scripts[i]->OnDrawGizmos(); if (scripts[i]->Enabled)
scripts[i]->OnDrawGizmos();
} }
} }
SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore") SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")

View File

@ -89,6 +89,8 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
std::string Convert::ToNative(System::String^ str) std::string Convert::ToNative(System::String^ str)
{ {
if (str == nullptr)
return "";
return msclr::interop::marshal_as<std::string>(str); return msclr::interop::marshal_as<std::string>(str);
} }