Transform Components are Enforced through the editor for certain components
This commit is contained in:
parent
f04ff595c4
commit
388795a2db
|
@ -35,6 +35,23 @@ namespace SHADE
|
|||
return selected;
|
||||
}
|
||||
|
||||
template <typename ComponentType, typename EnforcedComponent, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true, std::enable_if_t<std::is_base_of_v<SHComponent, EnforcedComponent>, bool> = true>
|
||||
bool DrawAddComponentWithEnforcedComponentButton(EntityID const& eid)
|
||||
{
|
||||
bool selected = false;
|
||||
if (!SHComponentManager::HasComponent<ComponentType>(eid))
|
||||
{
|
||||
if(selected = ImGui::Selectable(std::format("Add {}", rttr::type::get<ComponentType>().get_name().data()).data()); selected)
|
||||
{
|
||||
if(SHComponentManager::GetComponent_s<EnforcedComponent>(eid) == nullptr)
|
||||
SHComponentManager::AddComponent<EnforcedComponent>(eid);
|
||||
|
||||
SHComponentManager::AddComponent<ComponentType>(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<SHTransformComponent>(eid);
|
||||
DrawAddComponentButton<SHRenderable>(eid);
|
||||
DrawAddComponentButton<SHColliderComponent>(eid);
|
||||
if(DrawAddComponentButton<SHRigidBodyComponent>(eid))
|
||||
{
|
||||
if(SHComponentManager::GetComponent_s<SHTransformComponent>(eid) == nullptr)
|
||||
{
|
||||
SHComponentManager::AddComponent<SHTransformComponent>(eid);
|
||||
}
|
||||
}
|
||||
|
||||
// Components that require Transforms
|
||||
|
||||
DrawAddComponentWithEnforcedComponentButton<SHRenderable, SHTransformComponent>(eid);
|
||||
DrawAddComponentWithEnforcedComponentButton<SHRigidBodyComponent, SHTransformComponent>(eid);
|
||||
DrawAddComponentWithEnforcedComponentButton<SHColliderComponent, SHTransformComponent>(eid);
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
|
|
|
@ -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<void(SHEvent)>;
|
||||
|
||||
|
||||
class SHEventManager
|
||||
class SH_API SHEventManager
|
||||
{
|
||||
private:
|
||||
|
||||
|
|
|
@ -61,9 +61,9 @@ namespace SHADE
|
|||
|
||||
void SHTransformSystem::Init()
|
||||
{
|
||||
std::shared_ptr thisReceiver { std::make_shared<SHEventReceiverSpec<SHTransformSystem>>(this, &SHTransformSystem::ChangeParent) };
|
||||
ReceiverPtr receiver = std::dynamic_pointer_cast<SHEventReceiver>(thisReceiver);
|
||||
SHEventManager::SubscribeTo(SH_SCENEGRAPH_CHANGE_PARENT_EVENT, receiver);
|
||||
std::shared_ptr thisChangeParentReceiver { std::make_shared<SHEventReceiverSpec<SHTransformSystem>>(this, &SHTransformSystem::ChangeParent) };
|
||||
ReceiverPtr changeParentReceiver = std::dynamic_pointer_cast<SHEventReceiver>(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<const SHEventSpec<SHSceneGraphChangeParentEvent>*>(changeParentEvent.get());
|
||||
|
||||
auto* node = eventData->data->node;
|
||||
auto* tf = SHComponentManager::GetComponent_s<SHTransformComponent>(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<SHTransformComponent>(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<const SHEventSpec<SHSceneGraphChangeParentEvent>*>(changeParentEvent.get());
|
||||
|
||||
auto* node = eventData->data->node;
|
||||
auto* tf = SHComponentManager::GetComponent_s<SHTransformComponent>(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<SHTransformComponent>(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
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue