Add Editor Features - Transform Gizmo #105
|
@ -149,7 +149,7 @@ namespace Sandbox
|
|||
SHSceneManager::SceneUpdate(0.016f);
|
||||
#endif
|
||||
SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, 0.016f);
|
||||
editor->PollPicking();
|
||||
//editor->PollPicking();
|
||||
}
|
||||
// Finish all graphics jobs first
|
||||
graphicsSystem->AwaitGraphicsExecution();
|
||||
|
|
|
@ -154,7 +154,6 @@ namespace SHADE
|
|||
|
||||
target = SHVec3::RotateY(target, SHMath::DegreesToRadians(camera.yaw));
|
||||
target =SHVec3::RotateX(target, SHMath::DegreesToRadians(camera.pitch));
|
||||
std::cout << "Target vec: " << target.x<<", "<<target.y<<", "<<target.z << std::endl;
|
||||
target += camera.position;
|
||||
////SHVec3::RotateZ(target, SHMath::DegreesToRadians(camera.roll));
|
||||
|
||||
|
|
|
@ -59,4 +59,14 @@ namespace SHADE
|
|||
{
|
||||
return redoStack.size();
|
||||
}
|
||||
|
||||
void SHCommandManager::PopLatestCommandFromRedoStack()
|
||||
{
|
||||
redoStack.pop();
|
||||
}
|
||||
|
||||
void SHCommandManager::PopLatestCommandFromUndoStack()
|
||||
{
|
||||
undoStack.pop();
|
||||
}
|
||||
}//namespace SHADE
|
||||
|
|
|
@ -31,6 +31,9 @@ namespace SHADE
|
|||
static std::size_t GetUndoStackSize();
|
||||
static std::size_t GetRedoStackSize();
|
||||
|
||||
static void PopLatestCommandFromRedoStack();
|
||||
static void PopLatestCommandFromUndoStack();
|
||||
|
||||
private:
|
||||
static CommandStack undoStack;
|
||||
static CommandStack redoStack;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <imgui.h>
|
||||
|
||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
#include "Editor/Command/SHCommandManager.h"
|
||||
#include "FRC/SHFramerateController.h"
|
||||
|
||||
namespace SHADE
|
||||
|
@ -38,6 +39,11 @@ namespace SHADE
|
|||
{
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "ImGuizmo.h"
|
||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
#include "Editor/IconsMaterialDesign.h"
|
||||
#include "Editor/SHEditor.hpp"
|
||||
#include "Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
||||
|
@ -26,12 +27,9 @@ namespace SHADE
|
|||
void SHEditorViewport::Update()
|
||||
{
|
||||
SHEditorWindow::Update();
|
||||
//ImGuizmo::SetDrawlist(ImGui::GetBackgroundDrawList(ImGui::GetMainViewport()));
|
||||
|
||||
ImGuizmo::SetRect(beginCursorPos.x, beginCursorPos.y, beginContentRegionAvailable.x, beginContentRegionAvailable.y);
|
||||
transfromGizmo.Draw();
|
||||
if(Begin())
|
||||
{
|
||||
ImGuizmo::SetDrawlist();
|
||||
DrawMenuBar();
|
||||
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||
auto const& descriptorSet = gfxSystem->GetPostOffscreenRenderSystem()->GetDescriptorSetGroup()->GetVkHandle()[0];
|
||||
|
@ -42,6 +40,8 @@ namespace SHADE
|
|||
|
||||
ImGui::Image((ImTextureID)descriptorSet, {beginContentRegionAvailable.x, beginContentRegionAvailable.y});
|
||||
}
|
||||
ImGuizmo::SetRect(beginCursorPos.x , beginCursorPos.y, beginContentRegionAvailable.x, beginContentRegionAvailable.y);
|
||||
transformGizmo.Draw();
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
|
@ -70,10 +70,45 @@ namespace SHADE
|
|||
SHEditorWindow::OnPosChange();
|
||||
}
|
||||
|
||||
void SHEditorViewport::DrawMenuBar() const noexcept
|
||||
void SHEditorViewport::DrawMenuBar() noexcept
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,12 +21,12 @@ namespace SHADE
|
|||
void Init() override;
|
||||
void Update() override;
|
||||
void Exit() override;
|
||||
SHTransformGizmo transformGizmo;
|
||||
protected:
|
||||
void OnResize() override;
|
||||
void OnPosChange() override;
|
||||
private:
|
||||
void DrawMenuBar() const noexcept;
|
||||
SHTransformGizmo transfromGizmo;
|
||||
void DrawMenuBar() noexcept;
|
||||
SHVec2 beginCursorPos;
|
||||
};//class SHEditorViewport
|
||||
}//namespace SHADE
|
||||
|
|
|
@ -4,45 +4,82 @@
|
|||
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
#include "Editor/SHEditor.hpp"
|
||||
#include "Editor/SHImGuiHelpers.hpp"
|
||||
#include <imgui.h>
|
||||
#include <ImGuizmo.h>
|
||||
|
||||
#include "Camera/SHCameraSystem.h"
|
||||
#include "Editor/Command/SHCommandManager.h"
|
||||
#include "Editor/EditorWindow/ViewportWindow/SHEditorViewport.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
void SHTransformGizmo::Draw()
|
||||
{
|
||||
if(selectedEntityTranformComponent == nullptr)
|
||||
{
|
||||
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)
|
||||
bool justChangedTfm = false;
|
||||
if (!editorCamera)
|
||||
{
|
||||
auto const cameraSystem = SHSystemManager::GetSystem<SHCameraSystem>();
|
||||
editorCamera = cameraSystem->GetEditorCamera();
|
||||
}
|
||||
|
||||
auto viewportWindow = SHEditorWindowManager::GetEditorWindow<SHEditorViewport>();
|
||||
ImGuizmo::SetOrthographic(false);
|
||||
ImGuizmo::SetOrthographic(true);
|
||||
|
||||
SHMatrix view = SHMatrix::Transpose(editorCamera->GetViewMatrix());
|
||||
view(3, 1) = -view(3, 1);
|
||||
SHMatrix proj = SHMatrix::Transpose(editorCamera->GetProjMatrix());
|
||||
SHMatrix mat = selectedEntityTranformComponent->GetTRS();
|
||||
SHMatrix gridMat = SHMatrix::Identity;
|
||||
ImGuizmo::DrawGrid(&view._11, &proj._11, &gridMat._11, 0.1f);
|
||||
//ImGuizmo::ViewManipulate()
|
||||
if(ImGuizmo::Manipulate(&view._11, &proj._11, ImGuizmo::OPERATION::UNIVERSAL, ImGuizmo::MODE::WORLD, &mat._11))
|
||||
proj(1, 1) *= -1;
|
||||
static SHMatrix gridMat = SHMatrix::Translate(0, -0.5f, 0.f) * SHMatrix::Identity;
|
||||
//ImGuizmo::DrawGrid(&view._11, &proj._11, &gridMat._11, 100.f);
|
||||
if (selectedEntityTransformComponent == nullptr)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,9 +7,42 @@ namespace SHADE
|
|||
class SHTransformGizmo
|
||||
{
|
||||
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();
|
||||
bool isManipulating = false;
|
||||
Mode mode = Mode::WORLD;
|
||||
Operation operation = Operation::TRANSLATE;
|
||||
private:
|
||||
SHTransformComponent* selectedEntityTranformComponent{nullptr};
|
||||
SHTransformComponent* selectedEntityTransformComponent{nullptr};
|
||||
SHCameraComponent* editorCamera{nullptr};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -133,6 +133,8 @@ namespace SHADE
|
|||
}
|
||||
}
|
||||
|
||||
PollPicking();
|
||||
|
||||
if(ImGui::IsKeyDown(ImGuiKey_LeftShift) && ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_Z))
|
||||
{
|
||||
SHCommandManager::RedoCommand();
|
||||
|
@ -341,7 +343,7 @@ namespace SHADE
|
|||
if (auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>())
|
||||
{
|
||||
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();
|
||||
if(pickedEID == MAX_EID)
|
||||
|
|
|
@ -43,6 +43,10 @@ namespace SHADE
|
|||
constexpr ImVec4 blue = {0.0f, 0.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[] = {
|
||||
0xBB0000FF, // red
|
||||
0xBB00FF00, // green
|
||||
|
|
Loading…
Reference in New Issue