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)
{
fragColor = vec4(0.0f, 1.0f, 1.0f, 1.0f);
}
if (opacity < 0.2f)
discard;
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

@ -155,16 +155,23 @@ namespace SHADE
} }
bool SHEditorUI::InputCheckbox(const std::string& label, bool& value, bool* isHovered) bool SHEditorUI::InputCheckbox(const std::string& label, bool& value, bool* isHovered)
{
if (!label.empty())
{ {
ImGui::Text(label.c_str()); 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)
{
if (!label.empty())
{ {
ImGui::Text(label.c_str()); ImGui::Text(label.c_str());
ImGui::SameLine();
}
if (isHovered) if (isHovered)
*isHovered = ImGui::IsItemHovered(); *isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
@ -177,7 +184,11 @@ namespace SHADE
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);
if (!label.empty())
{
ImGui::Text(label.c_str()); ImGui::Text(label.c_str());
ImGui::SameLine();
}
if (isHovered) if (isHovered)
*isHovered = ImGui::IsItemHovered(); *isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
@ -190,8 +201,12 @@ namespace SHADE
return CHANGED; return CHANGED;
} }
bool SHEditorUI::InputFloat(const std::string& label, float& value, bool* isHovered) bool SHEditorUI::InputFloat(const std::string& label, float& value, bool* isHovered)
{
if (!label.empty())
{ {
ImGui::Text(label.c_str()); ImGui::Text(label.c_str());
ImGui::SameLine();
}
if (isHovered) if (isHovered)
*isHovered = ImGui::IsItemHovered(); *isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
@ -212,8 +227,12 @@ namespace SHADE
return CHANGED; return CHANGED;
} }
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());
ImGui::SameLine();
}
if (isHovered) if (isHovered)
*isHovered = ImGui::IsItemHovered(); *isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
@ -235,8 +254,12 @@ namespace SHADE
} }
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());
ImGui::SameLine();
}
if (isHovered) if (isHovered)
*isHovered = ImGui::IsItemHovered(); *isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
@ -272,7 +295,11 @@ 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());
if (!label.empty())
{
ImGui::Text(label.c_str()); ImGui::Text(label.c_str());
ImGui::SameLine();
}
if (isHovered) if (isHovered)
*isHovered = ImGui::IsItemHovered(); *isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
@ -285,8 +312,12 @@ 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)
{
if (!label.empty())
{ {
ImGui::Text(label.c_str()); ImGui::Text(label.c_str());
ImGui::SameLine();
}
if (isHovered) if (isHovered)
*isHovered = ImGui::IsItemHovered(); *isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
@ -326,7 +357,11 @@ 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;
if (!label.empty())
{
ImGui::Text(label.c_str()); ImGui::Text(label.c_str());
ImGui::SameLine();
}
if (isHovered) if (isHovered)
*isHovered = ImGui::IsItemHovered(); *isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();

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/UI_VS.glsl", false);
SHAssetManager::CompileAsset("../../Assets/Shaders/UI_FS.glsl", false);
SHAssetManager::CompileAsset("../../Assets/Models/Quad.gltf", false); //SHAssetManager::CompileAsset("../../Assets/Shaders/Text_VS.glsl", false);
//SHAssetManager::CompileAsset("../../Assets/Shaders/Text_FS.glsl", false);
//SHAssetManager::CompileAsset("../../Assets/Shaders/TestCube_VS.glsl", false);
//SHAssetManager::CompileAsset("../../Assets/Shaders/UI_VS.glsl", 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"
@ -32,6 +33,7 @@ namespace SHADE
, 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,8 +96,6 @@ 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;

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
{ {
@ -77,8 +77,10 @@ namespace SHADE
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.
* @param ray The ray to cast. * @param ray The ray to cast.
@ -285,6 +287,6 @@ namespace SHADE
SHEventHandle onPlay (SHEventPtr onPlayEvent); SHEventHandle onPlay (SHEventPtr onPlayEvent);
SHEventHandle onStop (SHEventPtr onStopEvent); 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,6 +528,7 @@ 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)
{ {
if (scripts[i]->Enabled)
scripts[i]->FixedUpdate(); scripts[i]->FixedUpdate();
} }
} }
@ -546,6 +547,7 @@ 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)
{ {
if (scripts[i]->Enabled)
scripts[i]->Update(); scripts[i]->Update();
} }
} }
@ -564,6 +566,7 @@ 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)
{ {
if (scripts[i]->Enabled)
scripts[i]->LateUpdate(); scripts[i]->LateUpdate();
} }
} }
@ -583,6 +586,7 @@ 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)
{ {
if (scripts[i]->Enabled)
scripts[i]->OnDrawGizmos(); scripts[i]->OnDrawGizmos();
} }
} }

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