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 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);
}
fragColor = mix(vec4(0.0f), vec4(In2.textColor, 1.0f), min (opacity, 1.0f));
if (opacity < 0.2f)
discard;
else
fragColor = mix(vec4(0.0f), vec4(In2.textColor, 1.0f), min (opacity, 1.0f));
// fragColor = vec4 (1.0f);
color = fragColor;
outEntityID = In2.eid;

Binary file not shown.

View File

@ -68,7 +68,7 @@ void main()
// Generate UV coords and vertex positions
Out.uv = CreateQuad(gl_VertexIndex);
vec3 vertexPos = vec3(Out.uv, 1.0f);
vec3 vertexPos = vec3(Out.uv, 0.0f);
// Get the local matrices
mat4 localModel = testPushConstant.worldTransform;
@ -87,16 +87,15 @@ void main()
toFontSpace[2][0] = positionalOffset.x;
toFontSpace[2][1] = positionalOffset.y;
mat4 PVMatrix = cameraData.vpMat;
// Initialize variables for use in FS
//characterIndex = gl_InstanceID;
// Transform the vertices to font space
vertexPos = toFontSpace * vertexPos;
vertexPos = toFontSpace * vec3(vertexPos.xy, 1.0f);
Out2.textColor = testPushConstant.textColor;
// 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_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;
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
#extension GL_KHR_vulkan_glsl : enable
layout(location = 0) out struct
{
vec2 uv; // location = 0
} Out;
vec2 CreateQuad(in uint vertexID)
{
@ -15,7 +10,6 @@ vec2 CreateQuad(in uint vertexID)
void main()
{
vec2 texCoord = CreateQuad (gl_VertexIndex);
vec2 vertexPos = texCoord - vec2(0.5f);
vec2 vertexPos = 2 * (CreateQuad(gl_VertexIndex) - vec2(0.5f));
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",
"26437",
"4275",
"4635"
"4633",
"4634",
"4635",
"4638"
}
linkoptions { "-IGNORE:4006" }

View File

@ -80,10 +80,12 @@ namespace Sandbox
SHSystemManager::CreateSystem<SHCameraSystem>();
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>();
SHGraphicsSystem* graphicsSystem = static_cast<SHGraphicsSystem*>(SHSystemManager::GetSystem<SHGraphicsSystem>());
SHPhysicsSystem* physicsSystem = SHSystemManager::GetSystem<SHPhysicsSystem>();
// Link up SHDebugDraw
SHSystemManager::CreateSystem<SHDebugDrawSystem>();
@ -141,7 +143,7 @@ namespace Sandbox
//SHComponentManager::CreateComponentSparseSet<SHCameraComponent>();
SHAssetManager::Load();
auto font = SHAssetManager::GetData<SHFontAsset>(176667660);
//auto font = SHAssetManager::GetData<SHFontAsset>(176667660);
SHSystemManager::RegisterRoutine<SHAudioSystem, SHAudioSystem::AudioRoutine>();
@ -175,11 +177,16 @@ namespace Sandbox
#ifdef SHEDITOR
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;
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::F10))
{
@ -192,6 +199,13 @@ namespace Sandbox
drawRays = !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
graphicsSystem->AwaitGraphicsExecution();

View File

@ -7,13 +7,14 @@
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
#include "Scene/SHSceneManager.h"
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
#include "Physics/System/SHPhysicsSystem.h"
#include "Scripting/SHScriptEngine.h"
#include "Math/Transform/SHTransformComponent.h"
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
#include "Physics/Interface/SHRigidBodyComponent.h"
#include "Physics/Interface/SHColliderComponent.h"
#include "Graphics/MiddleEnd/Lights/SHLightComponent.h"
#include "Graphics/MiddleEnd/TextRendering/SHTextRendererComponent.h"
#include "Graphics/MiddleEnd/TextRendering/SHTextRenderableComponent.h"
#include "Assets/SHAssetManager.h"
#include "Camera/SHCameraComponent.h"
@ -43,6 +44,15 @@ namespace Sandbox
{
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 */
/*-----------------------------------------------------------------------*/

View File

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

View File

@ -22,6 +22,14 @@ namespace SHADE
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;
// read how many glyphs we have

View File

@ -43,7 +43,9 @@ namespace SHADE
if (!camComponent)
{
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.
if (entityVec[eIndex])
{
auto& children = SHSceneManager::GetCurrentSceneGraph().GetChildren(eID);
auto children = SHSceneManager::GetCurrentSceneGraph().GetChildren(eID);
for (auto& child : children)
{
DestroyEntity(child->GetEntityID());

View File

@ -252,7 +252,7 @@ namespace SHADE
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::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
{
@ -284,6 +284,7 @@ namespace SHADE
//Debug Info (Read-Only)
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("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
@ -495,4 +496,52 @@ namespace SHADE
}
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 "SHEditorComponentView.h"
#include "AudioSystem/SHAudioListenerComponent.h"
#include "Graphics/MiddleEnd/TextRendering/SHTextRenderableComponent.h"
namespace SHADE
{
@ -144,6 +145,10 @@ namespace SHADE
{
DrawComponent(uiComponent);
}
if (auto textRendererComponent = SHComponentManager::GetComponent_s<SHTextRenderableComponent>(eid))
{
DrawComponent(textRendererComponent);
}
ImGui::Separator();
// Render Scripts
SHScriptEngine* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
@ -162,6 +167,7 @@ namespace SHADE
DrawAddComponentWithEnforcedComponentButton<SHRenderable, SHTransformComponent>(eid);
DrawAddComponentWithEnforcedComponentButton<SHRigidBodyComponent, SHTransformComponent>(eid);
DrawAddComponentWithEnforcedComponentButton<SHColliderComponent, SHTransformComponent>(eid);
DrawAddComponentWithEnforcedComponentButton<SHTextRenderableComponent, SHTransformComponent>(eid);
ImGui::EndMenu();

View File

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

View File

@ -55,7 +55,7 @@ namespace SHADE
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();
// Check if we have a Batch with the same pipeline yet

View File

@ -84,7 +84,7 @@ namespace SHADE
if (width == 0 || height == 0)
return;
PrepareResize(resizeWidth, resizeHeight);
PrepareResize(width, height);
});
window->RegisterWindowCloseCallback([&](void)
@ -117,13 +117,16 @@ namespace SHADE
// Create generic command buffer
graphicsCmdPool = device->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true);
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);
SHFreetypeInstance::Init();
//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
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 TEXT_VS = 39816727; textVS = SHResourceManager::LoadOrGet<SHVkShaderModule>(TEXT_VS);
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
@ -299,6 +303,7 @@ namespace SHADE
textRenderingSubSystem->Render(cmdBuffer, frameIndex);
});
#ifdef SHEDITOR
{
// Dummy Node to transition scene render graph resource
auto dummyNode = screenRenderGraph->AddNode("Dummy Pass", { "Scene" }, { "Screen Space Pass" }); // no predecessors
@ -306,7 +311,9 @@ namespace SHADE
dummySubpass->AddInput("Scene");
}
//screenRenderGraph->AddRenderToSwapchainNode ("Scene", "Present", )
#else
screenRenderGraph->AddRenderToSwapchainNode("Scene", "Present", {"Screen Space Pass"}, {renderToSwapchainVS, renderToSwapchainFS});
#endif
screenRenderGraph->Generate();
@ -379,7 +386,6 @@ namespace SHADE
screenRenderer->BindDescSet(cmdBuffer, frameIndex);
});
SHFreetypeInstance::Init();
}
void SHGraphicsSystem::InitBuiltInResources(void)
@ -1041,7 +1047,8 @@ namespace SHADE
worldViewport->SetWidth(static_cast<float>(resizeWidth));
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>();
#ifdef SHEDITOR
@ -1053,8 +1060,6 @@ namespace SHADE
for (auto& semaHandle : graphSemaphores)
semaHandle = device->CreateSemaphore();
}
void SHGraphicsSystem::AwaitGraphicsExecution()

View File

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

View File

@ -1,15 +1,15 @@
#include "SHpch.h"
#include "SHTextRendererComponent.h"
#include "SHTextRenderableComponent.h"
namespace SHADE
{
void SHTextRendererComponent::MakeDirty(void) noexcept
void SHTextRenderableComponent::MakeDirty(void) noexcept
{
requiresRecompute = true;
}
void SHTextRendererComponent::Clean(void) noexcept
void SHTextRenderableComponent::Clean(void) noexcept
{
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;
// Default white color.
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;
MakeDirty();
}
void SHTextRendererComponent::SetFont(Handle<SHFont> font) noexcept
void SHTextRenderableComponent::SetFont(Handle<SHFont> font) noexcept
{
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;
}
}
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 "Math/SHColour.h"
#include "Resource/SHHandle.h"
#include <rttr/registration>
namespace SHADE
{
@ -12,7 +13,7 @@ namespace SHADE
class SHVkDescriptorSetGroup;
class SHVkBuffer;
class SH_API SHTextRendererComponent final : public SHComponent
class SH_API SHTextRenderableComponent final : public SHComponent
{
public:
static constexpr uint32_t MAX_CHARACTERS = 500;
@ -53,9 +54,12 @@ namespace SHADE
void SetFont (Handle<SHFont> font) noexcept;
std::string const& GetText (void) const noexcept;
Handle<SHFont> GetFont (void) const noexcept;
friend class SHTextRenderingSubSystem;
RTTR_ENABLE()
};
}

View File

@ -1,6 +1,6 @@
#include "SHpch.h"
#include "SHTextRenderingSubSystem.h"
#include "Graphics/MiddleEnd/TextRendering/SHTextRendererComponent.h"
#include "Graphics/MiddleEnd/TextRendering/SHTextRenderableComponent.h"
#include "ECS_Base/Managers/SHComponentManager.h"
#include "Math/Vector/SHVec4.h"
#include "Graphics/Devices/SHVkLogicalDevice.h"
@ -14,20 +14,20 @@
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;
// Create the buffer
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)
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
std::vector <SHTextRendererComponent::TextIndexingType> indexingData;
std::vector <SHTextRenderableComponent::TextIndexingType> indexingData;
// For placing glyphs correctly
std::vector <SHVec4> charPositionData;
@ -49,7 +49,7 @@ namespace SHADE
// for every character
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
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);
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
{
SHComponentManager::CreateComponentSparseSet<SHTextRendererComponent>();
SHComponentManager::CreateComponentSparseSet<SHTextRenderableComponent>();
cameraDescSetBind = bindFunction;
@ -115,8 +115,8 @@ namespace SHADE
SHVertexInputState vertexInputState;
// Configure vertex attributes
vertexInputState.AddBinding(false, 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::FLOAT_4D) }); // location = 0 (character position data)
vertexInputState.AddBinding(true, false, { SHVertexAttribute(SHAttribFormat::UINT32_1D) }); // location = 1 (glyph index to index matrices)
// Set vertex state for new pipeline
pipeline->GetPipelineState().SetVertexInputState(vertexInputState);
@ -146,6 +146,13 @@ namespace SHADE
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
pipeline->ConstructPipeline();
@ -172,7 +179,7 @@ namespace SHADE
void SHTextRenderingSubSystem::Run(uint32_t frameIndex) noexcept
{
auto& textRendererComps = SHComponentManager::GetDense<SHTextRendererComponent>();
auto& textRendererComps = SHComponentManager::GetDense<SHTextRenderableComponent>();
for (auto& comp : textRendererComps)
{
@ -187,7 +194,7 @@ namespace SHADE
void SHTextRenderingSubSystem::Render(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
{
auto& textRendererComps = SHComponentManager::GetDense<SHTextRendererComponent>();
auto& textRendererComps = SHComponentManager::GetDense<SHTextRenderableComponent>();
for (auto& comp : textRendererComps)
{
auto* transform = SHComponentManager::GetComponent<SHTransformComponent>(comp.GetEID());

View File

@ -14,7 +14,7 @@ namespace SHADE
class SHVkBuffer;
class SHLightComponent;
class SHVkCommandBuffer;
class SHTextRendererComponent;
class SHTextRenderableComponent;
class SHVkPipeline;
class SHVkPipelineLayout;
class SHVkRenderpass;
@ -48,7 +48,7 @@ namespace SHADE
std::function<void(Handle<SHVkCommandBuffer>, uint32_t)> cameraDescSetBind;
private:
void RecomputePositions(SHTextRendererComponent& textComp) noexcept;
void RecomputePositions(SHTextRenderableComponent& textComp) noexcept;
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;

View File

@ -565,8 +565,10 @@ namespace SHADE
{
cmdBuffer->BindPipeline(renderToSwapchainImageSystem->GetPipeline());
newSubpass->BindDescriptorInputDescriptorSets (cmdBuffer, frameIndex);
// 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/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
#include "Graphics/RenderGraph/SHRenderGraphNode.h"
#include "Graphics/RenderGraph/SHSubpass.h"
#include "Graphics/SHVkUtil.h"
namespace SHADE
{
@ -25,14 +27,34 @@ namespace SHADE
.globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts(),
});
auto newPipeline = logicalDevice->CreateGraphicsPipeline(pipelineLayout, nullptr, renderGraphNode->GetRenderpass(), subpass);
pipeline = logicalDevice->CreateGraphicsPipeline(pipelineLayout, nullptr, renderGraphNode->GetRenderpass(), subpass);
SHInputAssemblyState inputAssembly{};
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{}
, name { name }
, graphStorage{ renderGraphStorage }
, inputImageDescriptors {SHGraphicsConstants::NUM_FRAME_BUFFERS}
, inputImageDescriptorSets{}
{
}
@ -67,7 +67,7 @@ namespace SHADE
, exteriorDrawCalls{ std::move(rhs.exteriorDrawCalls) }
, graphStorage{ rhs.graphStorage }
, inputNames{ std::move(rhs.inputNames) }
, inputImageDescriptors{ std::move(rhs.inputImageDescriptors) }
, inputImageDescriptorSets{ std::move(rhs.inputImageDescriptorSets) }
, inputDescriptorLayout{ rhs.inputDescriptorLayout }
, inputSamplers{ rhs.inputSamplers }
, name { rhs.name }
@ -102,7 +102,7 @@ namespace SHADE
exteriorDrawCalls = std::move(rhs.exteriorDrawCalls);
graphStorage = rhs.graphStorage;
inputNames = std::move(rhs.inputNames);
inputImageDescriptors = std::move(rhs.inputImageDescriptors);
inputImageDescriptorSets = std::move(rhs.inputImageDescriptorSets);
inputDescriptorLayout = rhs.inputDescriptorLayout;
inputSamplers = rhs.inputSamplers;
name = std::move(rhs.name);
@ -202,6 +202,8 @@ namespace SHADE
void SHSubpass::Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept
{
commandBuffer->BeginLabeledSegment(name);
// Ensure correct transforms are provided
superBatch->UpdateBuffers(frameIndex, descPool);
@ -221,6 +223,14 @@ namespace SHADE
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
{
exteriorDrawCalls.push_back(newDrawCall);
@ -237,6 +247,8 @@ namespace SHADE
if (inputNames.empty())
return;
inputImageDescriptorSets.resize(SHGraphicsConstants::NUM_FRAME_BUFFERS);
std::vector<SHVkDescriptorSetLayout::Binding> bindings{};
for (auto& input : inputReferences)
@ -280,8 +292,8 @@ namespace SHADE
}
}
//// maybe do this in handle resize?
//UpdateWriteDescriptors();
// maybe do this in handle resize?
UpdateWriteDescriptors();
}
void SHSubpass::UpdateWriteDescriptors(void) noexcept
@ -296,7 +308,7 @@ namespace SHADE
// For every frame's descriptor set
for (auto& group : inputImageDescriptors)
for (auto& group : inputImageDescriptorSets)
{
if (group)
group.Free();

View File

@ -55,8 +55,11 @@ namespace SHADE
//! For getting attachment reference indices using handles
std::unordered_map<uint64_t, uint32_t> const* resourceAttachmentMapping;
//! Descriptor set group to hold the images for input
std::vector<Handle<SHVkDescriptorSetGroup>> inputImageDescriptors;
//! Descriptor set group to hold the images for input. We have 3 here just in case
//! 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
Handle<SHVkDescriptorSetLayout> inputDescriptorLayout;
@ -104,6 +107,7 @@ namespace SHADE
// Runtime functions
void Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
void HandleResize (void) noexcept;
void BindDescriptorInputDescriptorSets (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) const 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;
// 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()

View File

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

View File

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

View File

@ -322,25 +322,25 @@ namespace SHADE
// dirtyFlags |= 1U << FLAG_POS;
//}
void SHRigidBodyComponent::SetMass(float newMass) noexcept
{
static constexpr int FLAG_POS = 9;
//void SHRigidBodyComponent::SetMass(float newMass) noexcept
//{
// static constexpr int FLAG_POS = 9;
if (newMass < 0.0f)
return;
// if (newMass < 0.0f)
// return;
if (type != Type::DYNAMIC)
{
SHLOG_WARNING("Cannot set mass of a non-dynamic object {}", GetEID())
return;
}
// if (type != Type::DYNAMIC)
// {
// SHLOG_WARNING("Cannot set mass of a non-dynamic object {}", GetEID())
// return;
// }
dirtyFlags |= 1U << FLAG_POS;
mass = newMass;
// dirtyFlags |= 1U << FLAG_POS;
// mass = newMass;
// Turn off automass
flags &= ~(1U << FLAG_POS);
}
// // Turn off automass
// flags &= ~(1U << FLAG_POS);
//}
void SHRigidBodyComponent::SetDrag(float newDrag) noexcept
{
@ -411,6 +411,13 @@ namespace SHADE
}
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
@ -489,7 +496,7 @@ RTTR_REGISTRATION
registration::class_<SHRigidBodyComponent>("RigidBody Component")
.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("Angular Drag" , &SHRigidBodyComponent::GetAngularDrag , &SHRigidBodyComponent::SetAngularDrag )
.property("Use Gravity" , &SHRigidBodyComponent::IsGravityEnabled , &SHRigidBodyComponent::SetGravityEnabled )

View File

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

View File

@ -94,7 +94,7 @@ namespace SHADE
/* Public Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
int SHPhysicsObject::AddCollisionShape(int index) const
int SHPhysicsObject::AddCollisionShape(int index)
{
// Get collider component
auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(entityID);
@ -123,13 +123,19 @@ namespace SHADE
default: break;
}
rp3dBody->updateLocalCenterOfMassFromColliders();
rp3dBody->updateLocalInertiaTensorFromColliders();
if (rp3dBody->getType() == rp3d::BodyType::DYNAMIC)
{
rp3dBody->updateMassPropertiesFromColliders();
auto* rigidBodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(entityID);
if (rigidBodyComponent)
rigidBodyComponent->mass = rp3dBody->getMass();
}
return index;
}
void SHPhysicsObject::RemoveCollisionShape(int index) const
void SHPhysicsObject::RemoveCollisionShape(int index)
{
const int NUM_COLLIDERS = static_cast<int>(rp3dBody->getNbColliders());
if (NUM_COLLIDERS == 0)
@ -140,6 +146,15 @@ namespace SHADE
auto* collider = rp3dBody->getCollider(index);
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
@ -254,6 +269,8 @@ namespace SHADE
}
case 9: // Mass
{
//rp3dBody->setMass(component.mass);
//if (component.GetAutoMass())
//{
// rp3dBody->updateMassPropertiesFromColliders();
@ -261,9 +278,9 @@ namespace SHADE
//}
//else
//{
rp3dBody->setMass(component.mass);
rp3dBody->updateLocalCenterOfMassFromColliders();
rp3dBody->updateLocalInertiaTensorFromColliders();
// rp3dBody->setMass(component.mass);
// rp3dBody->updateLocalCenterOfMassFromColliders();
// rp3dBody->updateLocalInertiaTensorFromColliders();
//}
break;
@ -309,7 +326,18 @@ namespace SHADE
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;
}
@ -319,14 +347,6 @@ namespace SHADE
/* 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
{
const rp3d::Transform OFFSETS

View File

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

View File

@ -15,6 +15,7 @@
// Project Headers
#include "ECS_Base/Managers/SHSystemManager.h"
#include "Editor/SHEditor.h"
#include "Scene/SHSceneManager.h"
namespace SHADE
@ -118,11 +119,22 @@ namespace SHADE
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)
{
const bool DRAW = (system->debugDrawFlags & (1U << i)) > 0;
if (DRAW)
drawFunctions[i](debugDrawSystem);
drawFunctions[i](debugDrawSystem, rp3dRenderer);
}
// Automatically clear the container of raycasts despite debug drawing state
@ -134,7 +146,7 @@ namespace SHADE
/* 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>();
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>();
if (!physicsSystem)

View File

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

View File

@ -14,10 +14,12 @@
#include "SHPhysicsSystem.h"
// Project Headers
#include "Assets/SHAssetMacros.h"
#include "ECS_Base/Managers/SHComponentManager.h"
#include "ECS_Base/Managers/SHEntityManager.h"
#include "ECS_Base/Managers/SHSystemManager.h"
#include "Editor/SHEditor.h"
#include "Physics/Collision/SHCollisionTagMatrix.h"
#include "Physics/SHPhysicsEvents.h"
#include "Scene/SHSceneManager.h"
#include "Scripting/SHScriptEngine.h"
@ -90,6 +92,18 @@ namespace SHADE
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
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);
@ -111,17 +125,66 @@ namespace SHADE
SHEventManager::SubscribeTo(SH_EDITOR_ON_STOP_EVENT, ON_STOP_RECEIVER_PTR);
#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()
{
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()
@ -216,10 +279,13 @@ namespace SHADE
{
objectManager.AddCollisionShape(entityID, index);
auto* colliderComponent = SHComponentManager::GetComponent<SHColliderComponent>(entityID);
auto& collisionShape = colliderComponent->GetCollisionShape(index);
const SHPhysicsColliderAddedEvent COLLIDER_ADDED_EVENT_DATA
{
.entityID = entityID
, .colliderType = SHComponentManager::GetComponent<SHColliderComponent>(entityID)->GetCollisionShape(index).GetType()
, .colliderType = collisionShape.GetType()
, .colliderIndex = index
};
@ -355,6 +421,11 @@ namespace SHADE
return onPlayEvent->handle;
worldState.CreateWorld(factory);
#ifdef _PUBLISH
worldState.world->setIsDebugRenderingEnabled(false);
#else
worldState.world->setIsDebugRenderingEnabled(true);
#endif
// Link Collision Listener & Raycaster
collisionListener.BindToWorld(worldState.world);
@ -363,8 +434,8 @@ namespace SHADE
// Link with object manager & create all physics objects
objectManager.SetWorld(worldState.world);
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph();
SCENE_GRAPH.Traverse(BUILD_PHYSICS_OBJECT);
// Build scene
SHSceneManager::GetCurrentSceneGraph().Traverse(BUILD_PHYSICS_OBJECT);
return onPlayEvent->handle;
}
@ -378,11 +449,11 @@ namespace SHADE
// Clear all collision info
// Collision listener is automatically unbound when world is destroyed
collisionListener.ClearContainers();
raycaster.ClearFrame();
// Destroy the world
worldState.DestroyWorld(factory);
return onStopEvent->handle;
}
} // namespace SHADE

View File

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

View File

@ -1,7 +1,7 @@
/****************************************************************************************
* \file SHSceneGraphEvents.h
* \file SHSceneEvents.h
* \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
* disclosure of this file or its contents without the prior written consent
@ -21,21 +21,21 @@ namespace SHADE
struct SHSceneGraphChangeParentEvent
{
SHSceneNode* node;
SHSceneNode* oldParent;
SHSceneNode* newParent;
SHSceneNode* node = nullptr;
SHSceneNode* oldParent = nullptr;
SHSceneNode* newParent = nullptr;
};
struct SHSceneGraphAddChildEvent
{
SHSceneNode* parent;
SHSceneNode* childAdded;
SHSceneNode* parent = nullptr;
SHSceneNode* childAdded = nullptr;
};
struct SHSceneGraphRemoveChildEvent
{
SHSceneNode* parent;
SHSceneNode* childRemoved;
SHSceneNode* parent = nullptr;
SHSceneNode* childRemoved = nullptr;
};
} // namespace SHADE

View File

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

View File

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

View File

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

View File

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

View File

@ -12,6 +12,9 @@
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
#include "SHSerializationTools.h"
#include "Physics/Interface/SHColliderComponent.h"
#include "Graphics/MiddleEnd/TextRendering/SHTextRenderableComponent.h"
#include "Graphics/MiddleEnd/TextRendering/SHFont.h"
namespace YAML
{
using namespace SHADE;
@ -113,6 +116,7 @@ namespace YAML
static constexpr const char* Bounciness = "Bounciness";
static constexpr const char* Density = "Density";
static constexpr const char* PositionOffset = "Position Offset";
static constexpr const char* RotationOffset = "Rotation Offset";
static Node encode(SHCollisionShape& rhs)
{
@ -148,6 +152,7 @@ namespace YAML
node[Bounciness] = rhs.GetBounciness();
node[Density] = rhs.GetDensity();
node[PositionOffset] = rhs.GetPositionOffset();
node[RotationOffset] = rhs.GetRotationOffset();
return node;
}
@ -188,6 +193,8 @@ namespace YAML
rhs.SetDensity(node[Density].as<float>());
if (node[PositionOffset].IsDefined())
rhs.SetPositionOffset(node[PositionOffset].as<SHVec3>());
if (node[RotationOffset].IsDefined())
rhs.SetRotationOffset(node[RotationOffset].as<SHVec3>());
return true;
}
@ -322,4 +329,45 @@ namespace YAML
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.imguizmo}",
"%{IncludeDir.imnodes}",
"%{IncludeDir.msdf_atlas_gen}",
"%{IncludeDir.msdfgen}",
"%{IncludeDir.yamlcpp}",
"%{IncludeDir.SDL}\\include",
"%{IncludeDir.RTTR}/include",
@ -53,6 +55,8 @@ project "SHADE_Managed"
links
{
"yaml-cpp",
"msdfgen",
"msdf-atlas-gen",
"imgui",
"SDL2.lib",
"SDL2main.lib",
@ -62,7 +66,11 @@ project "SHADE_Managed"
disablewarnings
{
"4251"
"4251",
"4633",
"4634",
"4635",
"4638"
}
defines
@ -85,6 +93,8 @@ project "SHADE_Managed"
dependson
{
"yaml-cpp",
"msdfgen",
"msdf-atlas-gen",
"imgui",
"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
{
/*---------------------------------------------------------------------------------*/
/* 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
#include "NativeAsset.hxx"
#include "Utility/Convert.hxx"
namespace SHADE
{
@ -23,11 +24,6 @@ namespace SHADE
/* Properties */
/*---------------------------------------------------------------------------------*/
template <typename NativeAssetType>
GenericHandle NativeAsset<NativeAssetType>::NativeObjectHandle::get()
{
return nativeObjHandle;
}
template <typename NativeAssetType>
Handle<NativeAssetType> NativeAsset<NativeAssetType>::NativeObject::get()
try
{
@ -43,7 +39,6 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
template <typename NativeAssetType>
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
{
/// <summary>
/// Generalised template class for a managed representation of a native asset
/// Abstract base class that all Native Assets will inherit from.
/// </summary>
/// <typeparam name="NativeAssetType">
/// The type of the asset's native representation.
/// </typeparam>
template<typename NativeAssetType>
public ref class NativeAsset
public ref class Asset abstract
{
internal:
/*-----------------------------------------------------------------------------*/
@ -38,6 +34,36 @@ namespace SHADE
{
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>
/// Copy of the Handle to the native object.
/// </summary>
@ -52,14 +78,8 @@ namespace SHADE
/// <summary>
/// Constructor for the native asset
/// </summary>
/// <param name="ptr">Native asset object.</param>
/// <param name="ptr">Native asset object handle.</param>
NativeAsset(Handle<NativeAssetType> ptr);
protected:
/*-----------------------------------------------------------------------------*/
/* Data Members */
/*-----------------------------------------------------------------------------*/
GenericHandle nativeObjHandle;
};
}

View File

@ -58,7 +58,7 @@ namespace SHADE
}
void RigidBody::Mass::set(float value)
{
return GetNativeComponent()->SetMass(value);
/*return GetNativeComponent()->SetMass(value);*/
}
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
SHEditorUI::PushID(index);
bool enabled = script->Enabled;
if (SHEditorUI::InputCheckbox("", enabled))
{
script->Enabled = enabled;
}
SHEditorUI::SameLine();
if (SHEditorUI::CollapsingHeader(LABEL))
{
SHEditorUI::PushID(LABEL);

View File

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

View File

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

View File

@ -22,6 +22,36 @@ of DigiPen Institute of Technology is prohibited.
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 */
/*---------------------------------------------------------------------------------*/
@ -104,11 +134,10 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
/* "All-time" Lifecycle Functions */
/*---------------------------------------------------------------------------------*/
void Script::Initialize(GameObject newOwner)
void Script::Initialize(SHADE::GameObject newOwner)
{
owner = newOwner;
}
void Script::OnAttached()
{
SAFE_NATIVE_CALL_BEGIN
@ -131,6 +160,12 @@ namespace SHADE
awake();
SAFE_NATIVE_CALL_END(this)
}
void Script::OnEnable()
{
SAFE_NATIVE_CALL_BEGIN
onEnable();
SAFE_NATIVE_CALL_END(this)
}
void Script::Start()
{
SAFE_NATIVE_CALL_BEGIN
@ -162,6 +197,12 @@ namespace SHADE
onDrawGizmos();
SAFE_NATIVE_CALL_END(this)
}
void Script::OnDisable()
{
SAFE_NATIVE_CALL_BEGIN
onDisable();
SAFE_NATIVE_CALL_END(this)
}
void Script::OnDestroy()
{
SAFE_NATIVE_CALL_BEGIN
@ -228,6 +269,7 @@ namespace SHADE
/* Virtual Lifecycle Functions */
/*---------------------------------------------------------------------------------*/
void Script::awake() {}
void Script::onEnable() {}
void Script::start() {}
void Script::fixedUpdate() {}
void Script::update() {}
@ -236,6 +278,7 @@ namespace SHADE
{
OnGizmosDrawOverriden = false;
}
void Script::onDisable() {}
void Script::onDestroy() {}
/*---------------------------------------------------------------------------------*/

View File

@ -38,11 +38,28 @@ namespace SHADE
/* Properties */
/*-----------------------------------------------------------------------------*/
/// <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.
/// </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>
/// <typeparam name="T">
/// Type of script to get.
/// This needs to be a default constructable Script.
/// This needs to be a default constructible Script.
/// </typeparam>
/// <returns>Reference to the script added</returns>
generic<typename T> where T : ref class, Script
@ -206,7 +223,7 @@ namespace SHADE
/// <summary>
/// Used to initialize a Script with a GameObject.
/// </summary>
void Initialize(GameObject newOwner);
void Initialize(SHADE::GameObject newOwner);
/// <summary>
/// Used to call onAttached(). This is called immediately when this script is
/// attached to a GameObject.
@ -232,6 +249,11 @@ namespace SHADE
/// </summary>
void Start();
/// <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
/// update steps and thus in most cases will execute more than Update() will.
/// This will be called immediately before a Physics update step.
@ -253,6 +275,11 @@ namespace SHADE
/// </summary>
void OnDrawGizmos();
/// <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
/// where the attached GameObject or this script is destroyed directly or
/// indirectly due to destruction of the owner.
@ -329,6 +356,10 @@ namespace SHADE
/// </summary>
virtual void awake();
/// <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
/// after Awake().
/// </summary>
@ -353,6 +384,10 @@ namespace SHADE
/// </summary>
virtual void onDrawGizmos();
/// <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
/// this script is destroyed directly or indirectly due to destruction of the
/// owner.
@ -403,7 +438,8 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/
/* Data Members */
/*-----------------------------------------------------------------------------*/
GameObject owner;
SHADE::GameObject owner;
bool enabled = true;
};
}

View File

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

View File

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