From 388795a2db374eeb1b2c3bda8384dcd204f7020e Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Tue, 25 Oct 2022 22:13:27 +0800 Subject: [PATCH] Transform Components are Enforced through the editor for certain components --- .../Inspector/SHEditorInspector.cpp | 33 +++++-- SHADE_Engine/src/Events/SHEventManager.hpp | 3 +- .../src/Math/Transform/SHTransformSystem.cpp | 94 +++++++++---------- .../src/Math/Transform/SHTransformSystem.h | 9 +- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 6 +- SHADE_Engine/src/Physics/SHPhysicsSystem.h | 2 +- 6 files changed, 83 insertions(+), 64 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp index b59ce9cc..116ad8d6 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp @@ -35,6 +35,23 @@ namespace SHADE return selected; } + template , bool> = true, std::enable_if_t, bool> = true> + bool DrawAddComponentWithEnforcedComponentButton(EntityID const& eid) + { + bool selected = false; + if (!SHComponentManager::HasComponent(eid)) + { + if(selected = ImGui::Selectable(std::format("Add {}", rttr::type::get().get_name().data()).data()); selected) + { + if(SHComponentManager::GetComponent_s(eid) == nullptr) + SHComponentManager::AddComponent(eid); + + SHComponentManager::AddComponent(eid); + } + } + return selected; + } + SHEditorInspector::SHEditorInspector() :SHEditorWindow("Inspector", ImGuiWindowFlags_MenuBar) { @@ -90,15 +107,13 @@ namespace SHADE if(ImGui::BeginMenu(std::format("{} Add Component", ICON_MD_LIBRARY_ADD).data())) { DrawAddComponentButton(eid); - DrawAddComponentButton(eid); - DrawAddComponentButton(eid); - if(DrawAddComponentButton(eid)) - { - if(SHComponentManager::GetComponent_s(eid) == nullptr) - { - SHComponentManager::AddComponent(eid); - } - } + + // Components that require Transforms + + DrawAddComponentWithEnforcedComponentButton(eid); + DrawAddComponentWithEnforcedComponentButton(eid); + DrawAddComponentWithEnforcedComponentButton(eid); + ImGui::EndMenu(); } diff --git a/SHADE_Engine/src/Events/SHEventManager.hpp b/SHADE_Engine/src/Events/SHEventManager.hpp index f511518a..490c6b10 100644 --- a/SHADE_Engine/src/Events/SHEventManager.hpp +++ b/SHADE_Engine/src/Events/SHEventManager.hpp @@ -12,6 +12,7 @@ #include "SHpch.h" #include "SHEvent.h" #include "SHEventReceiver.h" +#include "SH_API.h" /****************************************************************************** INSTRUCTIONS FOR USE: @@ -67,7 +68,7 @@ namespace SHADE using EventManagerListener = std::function; - class SHEventManager + class SH_API SHEventManager { private: diff --git a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp index 5a540cd4..4ab6b909 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp +++ b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp @@ -61,9 +61,9 @@ namespace SHADE void SHTransformSystem::Init() { - std::shared_ptr thisReceiver { std::make_shared>(this, &SHTransformSystem::ChangeParent) }; - ReceiverPtr receiver = std::dynamic_pointer_cast(thisReceiver); - SHEventManager::SubscribeTo(SH_SCENEGRAPH_CHANGE_PARENT_EVENT, receiver); + std::shared_ptr thisChangeParentReceiver { std::make_shared>(this, &SHTransformSystem::ChangeParent) }; + ReceiverPtr changeParentReceiver = std::dynamic_pointer_cast(thisChangeParentReceiver); + SHEventManager::SubscribeTo(SH_SCENEGRAPH_CHANGE_PARENT_EVENT, changeParentReceiver); } void SHTransformSystem::Exit() @@ -75,50 +75,6 @@ namespace SHADE /* Private Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ - SHEventHandle SHTransformSystem::ChangeParent(SHEventPtr changeParentEvent) - { - const auto& eventData = reinterpret_cast*>(changeParentEvent.get()); - - auto* node = eventData->data->node; - auto* tf = SHComponentManager::GetComponent_s(node->GetEntityID()); - - // Recompute local transform and store localToWorld Matrix - SHMatrix localToWorld = SHMatrix::Identity; - SHMatrix worldToLocal = SHMatrix::Identity; - - auto* newParent = eventData->data->newParent; - const auto* PARENT_TF = SHComponentManager::GetComponent_s(newParent->GetEntityID()); - if (PARENT_TF != nullptr) // Not the root - { - localToWorld = PARENT_TF->GetTRS(); - worldToLocal = SHMatrix::Inverse(localToWorld); - } - - // Maintain World Transform and recompute Local Transform - - // Compute Local Position - tf->local.position = SHVec3::Transform(tf->world.position, worldToLocal); - - - tf->localRotation = tf->worldRotation; - tf->local.scale = tf->world.scale; - - if (PARENT_TF != nullptr) - { - // Compute Local Rotation - tf->localRotation -= PARENT_TF->GetLocalRotation(); - - // Compute Local Scale - tf->local.scale /= PARENT_TF->GetLocalScale(); - } - - tf->local.trs = localToWorld; - - // Propagate maintaining world transform down the branch - UpdateChildrenLocalTransforms(node); - return eventData->handle; - } - void SHTransformSystem::UpdateChildrenLocalTransforms(SHSceneNode* node) { // Structure is similar to update entity, albeit without a queue to do being a forced update @@ -300,4 +256,48 @@ namespace SHADE tf.world.ComputeTRS(); } + SHEventHandle SHTransformSystem::ChangeParent(SHEventPtr changeParentEvent) + { + const auto& eventData = reinterpret_cast*>(changeParentEvent.get()); + + auto* node = eventData->data->node; + auto* tf = SHComponentManager::GetComponent_s(node->GetEntityID()); + + // Recompute local transform and store localToWorld Matrix + SHMatrix localToWorld = SHMatrix::Identity; + SHMatrix worldToLocal = SHMatrix::Identity; + + auto* newParent = eventData->data->newParent; + const auto* PARENT_TF = SHComponentManager::GetComponent_s(newParent->GetEntityID()); + if (PARENT_TF != nullptr) // Not the root + { + localToWorld = PARENT_TF->GetTRS(); + worldToLocal = SHMatrix::Inverse(localToWorld); + } + + // Maintain World Transform and recompute Local Transform + + // Compute Local Position + tf->local.position = SHVec3::Transform(tf->world.position, worldToLocal); + + + tf->localRotation = tf->worldRotation; + tf->local.scale = tf->world.scale; + + if (PARENT_TF != nullptr) + { + // Compute Local Rotation + tf->localRotation -= PARENT_TF->GetLocalRotation(); + + // Compute Local Scale + tf->local.scale /= PARENT_TF->GetLocalScale(); + } + + tf->local.trs = localToWorld; + + // Propagate maintaining world transform down the branch + UpdateChildrenLocalTransforms(node); + return eventData->handle; + } + } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Math/Transform/SHTransformSystem.h b/SHADE_Engine/src/Math/Transform/SHTransformSystem.h index e63969ce..f09da3ea 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformSystem.h +++ b/SHADE_Engine/src/Math/Transform/SHTransformSystem.h @@ -11,9 +11,9 @@ #pragma once // Project Headers -#include "SHTransformComponent.h" -#include "Scene/SHSceneGraph.h" #include "ECS_Base/System/SHSystemRoutine.h" +#include "Scene/SHSceneGraph.h" +#include "SHTransformComponent.h" namespace SHADE { @@ -111,11 +111,14 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ - SHEventHandle ChangeParent (SHEventPtr changeParentEvent); static void UpdateChildrenLocalTransforms (SHSceneNode* node); static void UpdateEntity (const SHSceneNode* node, bool clearDirtyFlag); static void UpdateTransform (SHTransformComponent& tf, const SHTransformComponent* parent = nullptr); + + // Event Handlers + + SHEventHandle ChangeParent (SHEventPtr changeParentEvent); }; diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index a1994ad2..f989e41d 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -203,7 +203,7 @@ namespace SHADE // SHLOG_INFO("Adding a Rigidbody to the Physics World.") //#endif - auto* physicsObject = CreatePhysicsObject(entityID); + auto* physicsObject = EnsurePhysicsObject(entityID); physicsObject->CreateRigidBody ( @@ -219,7 +219,7 @@ namespace SHADE // SHLOG_INFO("Adding a Collider to the Physics World.") //#endif - auto* physicsObject = CreatePhysicsObject(entityID); + auto* physicsObject = EnsurePhysicsObject(entityID); physicsObject->CreateCollisionBody ( @@ -359,7 +359,7 @@ namespace SHADE /* Private Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ - SHPhysicsObject* SHPhysicsSystem::CreatePhysicsObject(EntityID entityID) noexcept + SHPhysicsObject* SHPhysicsSystem::EnsurePhysicsObject(EntityID entityID) noexcept { const auto it = map.find(entityID); if (it == map.end()) diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/SHPhysicsSystem.h index bc6a1ba2..37d98300 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.h @@ -186,7 +186,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Function Members */ /*---------------------------------------------------------------------------------*/ - SHPhysicsObject* CreatePhysicsObject (EntityID entityID) noexcept; + SHPhysicsObject* EnsurePhysicsObject (EntityID entityID) noexcept; SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept; void DestroyPhysicsObject (EntityID entityID) noexcept;