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;
|
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()
|
SHEditorInspector::SHEditorInspector()
|
||||||
:SHEditorWindow("Inspector", ImGuiWindowFlags_MenuBar)
|
:SHEditorWindow("Inspector", ImGuiWindowFlags_MenuBar)
|
||||||
{
|
{
|
||||||
|
@ -90,15 +107,13 @@ namespace SHADE
|
||||||
if(ImGui::BeginMenu(std::format("{} Add Component", ICON_MD_LIBRARY_ADD).data()))
|
if(ImGui::BeginMenu(std::format("{} Add Component", ICON_MD_LIBRARY_ADD).data()))
|
||||||
{
|
{
|
||||||
DrawAddComponentButton<SHTransformComponent>(eid);
|
DrawAddComponentButton<SHTransformComponent>(eid);
|
||||||
DrawAddComponentButton<SHRenderable>(eid);
|
|
||||||
DrawAddComponentButton<SHColliderComponent>(eid);
|
// Components that require Transforms
|
||||||
if(DrawAddComponentButton<SHRigidBodyComponent>(eid))
|
|
||||||
{
|
DrawAddComponentWithEnforcedComponentButton<SHRenderable, SHTransformComponent>(eid);
|
||||||
if(SHComponentManager::GetComponent_s<SHTransformComponent>(eid) == nullptr)
|
DrawAddComponentWithEnforcedComponentButton<SHRigidBodyComponent, SHTransformComponent>(eid);
|
||||||
{
|
DrawAddComponentWithEnforcedComponentButton<SHColliderComponent, SHTransformComponent>(eid);
|
||||||
SHComponentManager::AddComponent<SHTransformComponent>(eid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "SHpch.h"
|
#include "SHpch.h"
|
||||||
#include "SHEvent.h"
|
#include "SHEvent.h"
|
||||||
#include "SHEventReceiver.h"
|
#include "SHEventReceiver.h"
|
||||||
|
#include "SH_API.h"
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
INSTRUCTIONS FOR USE:
|
INSTRUCTIONS FOR USE:
|
||||||
|
@ -67,7 +68,7 @@ namespace SHADE
|
||||||
using EventManagerListener = std::function<void(SHEvent)>;
|
using EventManagerListener = std::function<void(SHEvent)>;
|
||||||
|
|
||||||
|
|
||||||
class SHEventManager
|
class SH_API SHEventManager
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -61,9 +61,9 @@ namespace SHADE
|
||||||
|
|
||||||
void SHTransformSystem::Init()
|
void SHTransformSystem::Init()
|
||||||
{
|
{
|
||||||
std::shared_ptr thisReceiver { std::make_shared<SHEventReceiverSpec<SHTransformSystem>>(this, &SHTransformSystem::ChangeParent) };
|
std::shared_ptr thisChangeParentReceiver { std::make_shared<SHEventReceiverSpec<SHTransformSystem>>(this, &SHTransformSystem::ChangeParent) };
|
||||||
ReceiverPtr receiver = std::dynamic_pointer_cast<SHEventReceiver>(thisReceiver);
|
ReceiverPtr changeParentReceiver = std::dynamic_pointer_cast<SHEventReceiver>(thisChangeParentReceiver);
|
||||||
SHEventManager::SubscribeTo(SH_SCENEGRAPH_CHANGE_PARENT_EVENT, receiver);
|
SHEventManager::SubscribeTo(SH_SCENEGRAPH_CHANGE_PARENT_EVENT, changeParentReceiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHTransformSystem::Exit()
|
void SHTransformSystem::Exit()
|
||||||
|
@ -75,50 +75,6 @@ namespace SHADE
|
||||||
/* Private Function Member Definitions */
|
/* 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)
|
void SHTransformSystem::UpdateChildrenLocalTransforms(SHSceneNode* node)
|
||||||
{
|
{
|
||||||
// Structure is similar to update entity, albeit without a queue to do being a forced update
|
// 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();
|
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
|
} // namespace SHADE
|
|
@ -11,9 +11,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// Project Headers
|
// Project Headers
|
||||||
#include "SHTransformComponent.h"
|
|
||||||
#include "Scene/SHSceneGraph.h"
|
|
||||||
#include "ECS_Base/System/SHSystemRoutine.h"
|
#include "ECS_Base/System/SHSystemRoutine.h"
|
||||||
|
#include "Scene/SHSceneGraph.h"
|
||||||
|
#include "SHTransformComponent.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -111,11 +111,14 @@ namespace SHADE
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHEventHandle ChangeParent (SHEventPtr changeParentEvent);
|
|
||||||
static void UpdateChildrenLocalTransforms (SHSceneNode* node);
|
static void UpdateChildrenLocalTransforms (SHSceneNode* node);
|
||||||
|
|
||||||
static void UpdateEntity (const SHSceneNode* node, bool clearDirtyFlag);
|
static void UpdateEntity (const SHSceneNode* node, bool clearDirtyFlag);
|
||||||
static void UpdateTransform (SHTransformComponent& tf, const SHTransformComponent* parent = nullptr);
|
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.")
|
// SHLOG_INFO("Adding a Rigidbody to the Physics World.")
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
auto* physicsObject = CreatePhysicsObject(entityID);
|
auto* physicsObject = EnsurePhysicsObject(entityID);
|
||||||
|
|
||||||
physicsObject->CreateRigidBody
|
physicsObject->CreateRigidBody
|
||||||
(
|
(
|
||||||
|
@ -219,7 +219,7 @@ namespace SHADE
|
||||||
// SHLOG_INFO("Adding a Collider to the Physics World.")
|
// SHLOG_INFO("Adding a Collider to the Physics World.")
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
auto* physicsObject = CreatePhysicsObject(entityID);
|
auto* physicsObject = EnsurePhysicsObject(entityID);
|
||||||
|
|
||||||
physicsObject->CreateCollisionBody
|
physicsObject->CreateCollisionBody
|
||||||
(
|
(
|
||||||
|
@ -359,7 +359,7 @@ namespace SHADE
|
||||||
/* Private Function Member Definitions */
|
/* Private Function Member Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHPhysicsObject* SHPhysicsSystem::CreatePhysicsObject(EntityID entityID) noexcept
|
SHPhysicsObject* SHPhysicsSystem::EnsurePhysicsObject(EntityID entityID) noexcept
|
||||||
{
|
{
|
||||||
const auto it = map.find(entityID);
|
const auto it = map.find(entityID);
|
||||||
if (it == map.end())
|
if (it == map.end())
|
||||||
|
|
|
@ -186,7 +186,7 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
SHPhysicsObject* CreatePhysicsObject (EntityID entityID) noexcept;
|
SHPhysicsObject* EnsurePhysicsObject (EntityID entityID) noexcept;
|
||||||
SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept;
|
SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept;
|
||||||
void DestroyPhysicsObject (EntityID entityID) noexcept;
|
void DestroyPhysicsObject (EntityID entityID) noexcept;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue