Add Editor Features - Transform Gizmo #105

Merged
srishamharan merged 14 commits from SP3-4-editor_fix into main 2022-10-21 20:58:48 +08:00
11 changed files with 162 additions and 33 deletions
Showing only changes of commit b3ed320f9b - Show all commits

View File

@ -149,7 +149,7 @@ namespace Sandbox
SHSceneManager::SceneUpdate(0.016f); SHSceneManager::SceneUpdate(0.016f);
#endif #endif
SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, 0.016f); SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, 0.016f);
editor->PollPicking(); //editor->PollPicking();
} }
// Finish all graphics jobs first // Finish all graphics jobs first
graphicsSystem->AwaitGraphicsExecution(); graphicsSystem->AwaitGraphicsExecution();

View File

@ -154,7 +154,6 @@ namespace SHADE
target = SHVec3::RotateY(target, SHMath::DegreesToRadians(camera.yaw)); target = SHVec3::RotateY(target, SHMath::DegreesToRadians(camera.yaw));
target =SHVec3::RotateX(target, SHMath::DegreesToRadians(camera.pitch)); target =SHVec3::RotateX(target, SHMath::DegreesToRadians(camera.pitch));
std::cout << "Target vec: " << target.x<<", "<<target.y<<", "<<target.z << std::endl;
target += camera.position; target += camera.position;
////SHVec3::RotateZ(target, SHMath::DegreesToRadians(camera.roll)); ////SHVec3::RotateZ(target, SHMath::DegreesToRadians(camera.roll));

View File

@ -59,4 +59,14 @@ namespace SHADE
{ {
return redoStack.size(); return redoStack.size();
} }
void SHCommandManager::PopLatestCommandFromRedoStack()
{
redoStack.pop();
}
void SHCommandManager::PopLatestCommandFromUndoStack()
{
undoStack.pop();
}
}//namespace SHADE }//namespace SHADE

View File

@ -31,6 +31,9 @@ namespace SHADE
static std::size_t GetUndoStackSize(); static std::size_t GetUndoStackSize();
static std::size_t GetRedoStackSize(); static std::size_t GetRedoStackSize();
static void PopLatestCommandFromRedoStack();
static void PopLatestCommandFromUndoStack();
private: private:
static CommandStack undoStack; static CommandStack undoStack;
static CommandStack redoStack; static CommandStack redoStack;

View File

@ -3,6 +3,7 @@
#include <imgui.h> #include <imgui.h>
#include "ECS_Base/Managers/SHSystemManager.h" #include "ECS_Base/Managers/SHSystemManager.h"
#include "Editor/Command/SHCommandManager.h"
#include "FRC/SHFramerateController.h" #include "FRC/SHFramerateController.h"
namespace SHADE namespace SHADE
@ -38,6 +39,11 @@ namespace SHADE
{ {
ImGui::PlotLines("DT", frames.data(), static_cast<int>(frames.size()), 0, nullptr, 0.0f, 16.0f); ImGui::PlotLines("DT", frames.data(), static_cast<int>(frames.size()), 0, nullptr, 0.0f, 16.0f);
} }
if(ImGui::CollapsingHeader("Command Manager"))
{
ImGui::Text("Undo: %zu", SHCommandManager::GetUndoStackSize());
ImGui::Text("Redo: %zu", SHCommandManager::GetRedoStackSize());
}
ImGui::End(); ImGui::End();
} }

View File

@ -4,6 +4,7 @@
#include "ImGuizmo.h" #include "ImGuizmo.h"
#include "ECS_Base/Managers/SHSystemManager.h" #include "ECS_Base/Managers/SHSystemManager.h"
#include "Editor/IconsMaterialDesign.h"
#include "Editor/SHEditor.hpp" #include "Editor/SHEditor.hpp"
#include "Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h" #include "Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h"
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
@ -26,12 +27,9 @@ namespace SHADE
void SHEditorViewport::Update() void SHEditorViewport::Update()
{ {
SHEditorWindow::Update(); SHEditorWindow::Update();
//ImGuizmo::SetDrawlist(ImGui::GetBackgroundDrawList(ImGui::GetMainViewport()));
ImGuizmo::SetRect(beginCursorPos.x, beginCursorPos.y, beginContentRegionAvailable.x, beginContentRegionAvailable.y);
transfromGizmo.Draw();
if(Begin()) if(Begin())
{ {
ImGuizmo::SetDrawlist();
DrawMenuBar(); DrawMenuBar();
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>(); auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
auto const& descriptorSet = gfxSystem->GetPostOffscreenRenderSystem()->GetDescriptorSetGroup()->GetVkHandle()[0]; auto const& descriptorSet = gfxSystem->GetPostOffscreenRenderSystem()->GetDescriptorSetGroup()->GetVkHandle()[0];
@ -42,6 +40,8 @@ namespace SHADE
ImGui::Image((ImTextureID)descriptorSet, {beginContentRegionAvailable.x, beginContentRegionAvailable.y}); ImGui::Image((ImTextureID)descriptorSet, {beginContentRegionAvailable.x, beginContentRegionAvailable.y});
} }
ImGuizmo::SetRect(beginCursorPos.x , beginCursorPos.y, beginContentRegionAvailable.x, beginContentRegionAvailable.y);
transformGizmo.Draw();
ImGui::End(); ImGui::End();
} }
@ -70,10 +70,45 @@ namespace SHADE
SHEditorWindow::OnPosChange(); SHEditorWindow::OnPosChange();
} }
void SHEditorViewport::DrawMenuBar() const noexcept void SHEditorViewport::DrawMenuBar() noexcept
{ {
if(ImGui::BeginMenuBar()) if(ImGui::BeginMenuBar())
{ {
bool const isTranslate = transformGizmo.operation == SHTransformGizmo::Operation::TRANSLATE;
ImGui::BeginDisabled(isTranslate);
if(isTranslate)
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetStyle().Colors[ImGuiCol_CheckMark]);
if(ImGui::SmallButton(ICON_MD_OPEN_WITH))
{
transformGizmo.operation = SHTransformGizmo::Operation::TRANSLATE;
}
ImGui::EndDisabled();
if(isTranslate)
ImGui::PopStyleColor();
bool const isRotate = transformGizmo.operation == SHTransformGizmo::Operation::ROTATE;
ImGui::BeginDisabled(isRotate);
if(isRotate)
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetStyle().Colors[ImGuiCol_CheckMark]);
if(ImGui::SmallButton(ICON_MD_AUTORENEW))
{
transformGizmo.operation = SHTransformGizmo::Operation::ROTATE;
}
ImGui::EndDisabled();
if(isRotate)
ImGui::PopStyleColor();
bool const isScale = transformGizmo.operation == SHTransformGizmo::Operation::SCALE;
ImGui::BeginDisabled(isScale);
if(isScale)
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetStyle().Colors[ImGuiCol_CheckMark]);
if(ImGui::SmallButton(ICON_MD_OPEN_IN_FULL))
{
transformGizmo.operation = SHTransformGizmo::Operation::SCALE;
}
ImGui::EndDisabled();
if(isScale)
ImGui::PopStyleColor();
ImGui::EndMenuBar(); ImGui::EndMenuBar();
} }
} }

View File

@ -21,12 +21,12 @@ namespace SHADE
void Init() override; void Init() override;
void Update() override; void Update() override;
void Exit() override; void Exit() override;
SHTransformGizmo transformGizmo;
protected: protected:
void OnResize() override; void OnResize() override;
void OnPosChange() override; void OnPosChange() override;
private: private:
void DrawMenuBar() const noexcept; void DrawMenuBar() noexcept;
SHTransformGizmo transfromGizmo;
SHVec2 beginCursorPos; SHVec2 beginCursorPos;
};//class SHEditorViewport };//class SHEditorViewport
}//namespace SHADE }//namespace SHADE

View File

@ -4,45 +4,82 @@
#include "ECS_Base/Managers/SHComponentManager.h" #include "ECS_Base/Managers/SHComponentManager.h"
#include "ECS_Base/Managers/SHSystemManager.h" #include "ECS_Base/Managers/SHSystemManager.h"
#include "Editor/SHEditor.hpp" #include "Editor/SHEditor.hpp"
#include "Editor/SHImGuiHelpers.hpp"
#include <imgui.h> #include <imgui.h>
#include <ImGuizmo.h> #include <ImGuizmo.h>
#include "Camera/SHCameraSystem.h" #include "Camera/SHCameraSystem.h"
#include "Editor/Command/SHCommandManager.h"
#include "Editor/EditorWindow/ViewportWindow/SHEditorViewport.h" #include "Editor/EditorWindow/ViewportWindow/SHEditorViewport.h"
namespace SHADE namespace SHADE
{ {
void SHTransformGizmo::Draw() void SHTransformGizmo::Draw()
{ {
if(selectedEntityTranformComponent == nullptr) bool justChangedTfm = false;
{ if (!editorCamera)
SHEditor* editor = SHSystemManager::GetSystem<SHEditor>();
if(editor->selectedEntities.empty())
return;
EntityID eid = editor->selectedEntities.back();
selectedEntityTranformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(eid);
}
if(selectedEntityTranformComponent == nullptr)
return;
if(!editorCamera)
{ {
auto const cameraSystem = SHSystemManager::GetSystem<SHCameraSystem>(); auto const cameraSystem = SHSystemManager::GetSystem<SHCameraSystem>();
editorCamera = cameraSystem->GetEditorCamera(); editorCamera = cameraSystem->GetEditorCamera();
} }
auto viewportWindow = SHEditorWindowManager::GetEditorWindow<SHEditorViewport>(); auto viewportWindow = SHEditorWindowManager::GetEditorWindow<SHEditorViewport>();
ImGuizmo::SetOrthographic(false); ImGuizmo::SetOrthographic(true);
SHMatrix view = SHMatrix::Transpose(editorCamera->GetViewMatrix()); SHMatrix view = SHMatrix::Transpose(editorCamera->GetViewMatrix());
view(3, 1) = -view(3, 1);
SHMatrix proj = SHMatrix::Transpose(editorCamera->GetProjMatrix()); SHMatrix proj = SHMatrix::Transpose(editorCamera->GetProjMatrix());
SHMatrix mat = selectedEntityTranformComponent->GetTRS(); proj(1, 1) *= -1;
SHMatrix gridMat = SHMatrix::Identity; static SHMatrix gridMat = SHMatrix::Translate(0, -0.5f, 0.f) * SHMatrix::Identity;
ImGuizmo::DrawGrid(&view._11, &proj._11, &gridMat._11, 0.1f); //ImGuizmo::DrawGrid(&view._11, &proj._11, &gridMat._11, 100.f);
//ImGuizmo::ViewManipulate() if (selectedEntityTransformComponent == nullptr)
if(ImGuizmo::Manipulate(&view._11, &proj._11, ImGuizmo::OPERATION::UNIVERSAL, ImGuizmo::MODE::WORLD, &mat._11))
{ {
SHEditor* editor = SHSystemManager::GetSystem<SHEditor>();
if (editor->selectedEntities.empty())
return;
EntityID eid = editor->selectedEntities.back();
selectedEntityTransformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(eid);
justChangedTfm = true;
}
else
{
SHEditor* editor = SHSystemManager::GetSystem<SHEditor>();
if (editor->selectedEntities.empty())
return;
EntityID eid = editor->selectedEntities.back();
auto tfmComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(eid);
if (selectedEntityTransformComponent != tfmComponent)
{
selectedEntityTransformComponent = tfmComponent;
justChangedTfm = true;
}
}
if (selectedEntityTransformComponent == nullptr)
return;
SHMatrix mat = selectedEntityTransformComponent->GetTRS();
isManipulating = ImGuizmo::Manipulate(&view._11, &proj._11, static_cast<ImGuizmo::OPERATION>(operation), ImGuizmo::MODE::WORLD, &mat._11);
if (!justChangedTfm)
{
if (ImGui::IsItemClicked())
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHMatrix>>(selectedEntityTransformComponent->GetTRS(), mat, [tfm = std::move(selectedEntityTransformComponent)](SHMatrix const& mtx)
{
if (!tfm)
return;
SHVec3 translate{}, rotate{}, scale{};
mtx.Decompose(translate, rotate, scale);
tfm->SetWorldPosition(translate);
tfm->SetWorldRotation(rotate);
tfm->SetWorldScale(scale);
})));
else if (ImGui::IsItemHovered(ImGuiMouseButton_Left) && ImGui::IsMouseDown(ImGuiMouseButton_Left) && isManipulating)
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHMatrix>>(selectedEntityTransformComponent->GetTRS(), mat, [tfm = std::move(selectedEntityTransformComponent)](SHMatrix const& mtx)
{
if (!tfm)
return;
SHVec3 translate{}, rotate{}, scale{};
mtx.Decompose(translate, rotate, scale);
tfm->SetWorldPosition(translate);
tfm->SetWorldRotation(rotate);
tfm->SetWorldScale(scale);
})), true);
} }
} }
} }

View File

@ -7,9 +7,42 @@ namespace SHADE
class SHTransformGizmo class SHTransformGizmo
{ {
public: public:
enum class Mode
{
WORLD,
LOCAL
};
enum class Operation
{
TRANSLATE_X = (1u << 0),
TRANSLATE_Y = (1u << 1),
TRANSLATE_Z = (1u << 2),
ROTATE_X = (1u << 3),
ROTATE_Y = (1u << 4),
ROTATE_Z = (1u << 5),
ROTATE_SCREEN = (1u << 6),
SCALE_X = (1u << 7),
SCALE_Y = (1u << 8),
SCALE_Z = (1u << 9),
BOUNDS = (1u << 10),
SCALE_XU = (1u << 11),
SCALE_YU = (1u << 12),
SCALE_ZU = (1u << 13),
TRANSLATE = TRANSLATE_X | TRANSLATE_Y | TRANSLATE_Z,
ROTATE = ROTATE_X | ROTATE_Y | ROTATE_Z | ROTATE_SCREEN,
SCALE = SCALE_X | SCALE_Y | SCALE_Z,
SCALEU = SCALE_XU | SCALE_YU | SCALE_ZU, // universal
UNIVERSAL = TRANSLATE | ROTATE | SCALEU
};
void Draw(); void Draw();
bool isManipulating = false;
Mode mode = Mode::WORLD;
Operation operation = Operation::TRANSLATE;
private: private:
SHTransformComponent* selectedEntityTranformComponent{nullptr}; SHTransformComponent* selectedEntityTransformComponent{nullptr};
SHCameraComponent* editorCamera{nullptr}; SHCameraComponent* editorCamera{nullptr};
}; };
} }

View File

@ -133,6 +133,8 @@ namespace SHADE
} }
} }
PollPicking();
if(ImGui::IsKeyDown(ImGuiKey_LeftShift) && ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_Z)) if(ImGui::IsKeyDown(ImGuiKey_LeftShift) && ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_Z))
{ {
SHCommandManager::RedoCommand(); SHCommandManager::RedoCommand();
@ -341,7 +343,7 @@ namespace SHADE
if (auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>()) if (auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>())
{ {
auto viewportWindow = SHEditorWindowManager::GetEditorWindow<SHEditorViewport>(); auto viewportWindow = SHEditorWindowManager::GetEditorWindow<SHEditorViewport>();
if (viewportWindow->isWindowHovered && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) if (viewportWindow->isWindowHovered && !viewportWindow->transformGizmo.isManipulating && ImGui::IsMouseReleased(ImGuiMouseButton_Left))
{ {
EntityID pickedEID = gfxSystem->GetMousePickSystem()->GetPickedEntity(); EntityID pickedEID = gfxSystem->GetMousePickSystem()->GetPickedEntity();
if(pickedEID == MAX_EID) if(pickedEID == MAX_EID)

View File

@ -15,7 +15,7 @@
//#==============================================================# //#==============================================================#
#ifndef SH_IM_MATH #ifndef SH_IM_MATH
#define IM_VEC2_CLASS_EXTRA \ #define IM_VEC2_CLASS_EXTRA \
ImVec2(const SHADE::SHVec2& vec) {x = vec.x; y = vec.y;} \ ImVec2(const SHADE::SHVec2& vec) {x = vec.x; y = vec.y;} \
operator SHADE::SHVec2() const {return SHADE::SHVec2(x,y);} operator SHADE::SHVec2() const {return SHADE::SHVec2(x,y);}
#define IM_VEC3_CLASS_EXTRA \ #define IM_VEC3_CLASS_EXTRA \
ImVec3(const SHADE::SHVec3& vec) {x = vec.x; y = vec.y; z = vec.z;} \ ImVec3(const SHADE::SHVec3& vec) {x = vec.x; y = vec.y; z = vec.z;} \
@ -43,6 +43,10 @@ namespace SHADE
constexpr ImVec4 blue = {0.0f, 0.0f, 1.0f, 1.f}; constexpr ImVec4 blue = {0.0f, 0.0f, 1.0f, 1.f};
constexpr ImVec4 white = {1.0f, 1.0f, 1.0f, 1.f}; constexpr ImVec4 white = {1.0f, 1.0f, 1.0f, 1.f};
constexpr int colors_red = 0;
constexpr int colors_green = 1;
constexpr int colors_blue = 2;
constexpr int colors_white = 3;
constexpr ImU32 colors[] = { constexpr ImU32 colors[] = {
0xBB0000FF, // red 0xBB0000FF, // red
0xBB00FF00, // green 0xBB00FF00, // green