From e18298a8cbd7034906cb77dce15a55c7ee56fa97 Mon Sep 17 00:00:00 2001 From: antopilo Date: Wed, 23 Apr 2025 00:47:18 -0400 Subject: [PATCH] Editor animations/optimization --- Editor/AnimatedValue.cpp | 3 + Editor/AnimatedValue.h | 62 +++++++++++++++ .../Source/Editor/Windows/EditorInterface.cpp | 2 + Editor/Source/Editor/Windows/FileSystemUI.cpp | 11 ++- Editor/Source/Editor/Windows/FileSystemUI.h | 2 + .../SceneEditor/Widgets/FileBrowserWidget.cpp | 75 ++++++++++++++----- .../SceneEditor/Widgets/FileBrowserWidget.h | 8 +- .../Widgets/SceneHierarchyWidget.cpp | 27 ++++++- .../Widgets/SceneHierarchyWidget.h | 1 + .../Widgets/SelectionPropertyWidget.cpp | 17 ++++- .../Widgets/SelectionPropertyWidget.h | 4 + .../SceneEditor/Widgets/ViewportWidget.cpp | 48 ++++++++---- .../SceneEditor/Widgets/ViewportWidget.h | 4 + .../Nuake/Rendering/Textures/TextureManager.h | 2 +- Nuake/Source/Nuake/Scene/EditorCamera.h | 6 +- Nuake/Vendors/imgui/imgui.cpp | 7 ++ Nuake/Vendors/imgui/imgui_internal.h | 1 + 17 files changed, 237 insertions(+), 43 deletions(-) create mode 100644 Editor/AnimatedValue.cpp create mode 100644 Editor/AnimatedValue.h diff --git a/Editor/AnimatedValue.cpp b/Editor/AnimatedValue.cpp new file mode 100644 index 00000000..5fe27200 --- /dev/null +++ b/Editor/AnimatedValue.cpp @@ -0,0 +1,3 @@ +#include "AnimatedValue.h" + +std::vector IAnimatedValue::Instances; \ No newline at end of file diff --git a/Editor/AnimatedValue.h b/Editor/AnimatedValue.h new file mode 100644 index 00000000..54edd501 --- /dev/null +++ b/Editor/AnimatedValue.h @@ -0,0 +1,62 @@ +#pragma once +#include + +#include + +class IAnimatedValue +{ +public: + static std::vector Instances; + + static void UpdateAll (float ts) + { + for (auto& instance : Instances) + { + instance->Update(ts); + } + } + + virtual void Update(float ts) = 0; +}; + +template +class AnimatedValue : public IAnimatedValue +{ +public: + T Value; + T TargetValue; + float Speed = 20.0f; + AnimatedValue(T value = T(), T targetValue = T()) + : Value(value), TargetValue(targetValue) + { + IAnimatedValue::Instances.push_back(this); + } + + ~AnimatedValue() + { + auto it = std::remove(Instances.begin(), Instances.end(), this); + IAnimatedValue::Instances.erase(it, Instances.end()); + } + + virtual void Update(float ts) override + { + Value = glm::mix(Value, TargetValue, glm::clamp(Speed * ts, 0.0f, 1.0f)); + } + + void SetValue(T value) + { + Value = value; + TargetValue = value; + } + + operator T() const + { + return Value; + } + + AnimatedValue& operator =(T value) + { + TargetValue = value; + return *this; + } +}; \ No newline at end of file diff --git a/Editor/Source/Editor/Windows/EditorInterface.cpp b/Editor/Source/Editor/Windows/EditorInterface.cpp index 9e763a01..17dc4c50 100644 --- a/Editor/Source/Editor/Windows/EditorInterface.cpp +++ b/Editor/Source/Editor/Windows/EditorInterface.cpp @@ -65,6 +65,7 @@ #include "../Events/EditorRequests.h" #include "../../../../Nuake/Thirdparty/glfw/include/GLFW/glfw3.h" +#include "../../../AnimatedValue.h" namespace Nuake { @@ -2955,6 +2956,7 @@ namespace Nuake { void EditorInterface::Update(float ts) { + Logger::Log("Opacity: " + std::to_string(ts), "UPDATE"); if (!Engine::GetCurrentScene() || Engine::IsPlayMode()) { return; diff --git a/Editor/Source/Editor/Windows/FileSystemUI.cpp b/Editor/Source/Editor/Windows/FileSystemUI.cpp index 8fa30415..4f48edc5 100644 --- a/Editor/Source/Editor/Windows/FileSystemUI.cpp +++ b/Editor/Source/Editor/Windows/FileSystemUI.cpp @@ -339,7 +339,6 @@ namespace Nuake ImGui::EndDragDropSource(); } - Ref textureImage = TextureManager::Get()->GetTexture2("Resources/Images/file_icon.png"); const auto textureMgr = TextureManager::Get(); @@ -355,7 +354,11 @@ namespace Nuake else if (fileType == FileType::Image) { const std::string path = file->GetAbsolutePath(); - textureImage = textureMgr->GetTexture2(path); + if (!textureMgr->IsTextureLoaded2(path) && textureLoadedThisFrame < maxTextureLoadedPerFrame) + { + textureImage = textureMgr->GetTexture2(path); + textureLoadedThisFrame++; + } } else if (fileType == FileType::Project) { @@ -1037,6 +1040,8 @@ namespace Nuake i++; } } + + } DrawContextMenu(); @@ -1049,7 +1054,7 @@ namespace Nuake } ThumbnailManager::Get().OnEndFrame(); - + textureLoadedThisFrame = 0; ImGui::EndChild(); } ImGui::End(); diff --git a/Editor/Source/Editor/Windows/FileSystemUI.h b/Editor/Source/Editor/Windows/FileSystemUI.h index 54fa5f53..34d15e2b 100644 --- a/Editor/Source/Editor/Windows/FileSystemUI.h +++ b/Editor/Source/Editor/Windows/FileSystemUI.h @@ -8,6 +8,8 @@ namespace Nuake { { private: EditorInterface* Editor; + const int maxTextureLoadedPerFrame = 4; + int textureLoadedThisFrame = 0; public: static Ref m_CurrentDirectory; diff --git a/Editor/Source/Editor/Windows/SceneEditor/Widgets/FileBrowserWidget.cpp b/Editor/Source/Editor/Windows/SceneEditor/Widgets/FileBrowserWidget.cpp index 53871786..86c38888 100644 --- a/Editor/Source/Editor/Windows/SceneEditor/Widgets/FileBrowserWidget.cpp +++ b/Editor/Source/Editor/Windows/SceneEditor/Widgets/FileBrowserWidget.cpp @@ -15,7 +15,12 @@ using namespace Nuake; FileBrowserWidget::FileBrowserWidget(EditorContext& inCtx) : IEditorWidget(inCtx) { - currentDirectory = FileSystem::RootDirectory; + SetCurrentDirectory(FileSystem::RootDirectory); +} + +void FileBrowserWidget::SetCurrentDirectory(Ref dir) +{ + queueDirectory = dir; } void FileBrowserWidget::Update(float ts) @@ -27,6 +32,12 @@ void FileBrowserWidget::Draw() { if (BeginWidgetWindow("File Browser")) { + if (queueDirectory != currentDirectory) + { + opacity.SetValue(0.0f); + opacity = 1.0f; + currentDirectory = queueDirectory; + } Ref rootDirectory = FileSystem::GetFileTree(); auto availableSpace = ImGui::GetContentRegionAvail(); @@ -35,7 +46,8 @@ void FileBrowserWidget::Draw() ImVec4* colors = ImGui::GetStyle().Colors; ImGui::PushStyleColor(ImGuiCol_ChildBg, colors[ImGuiCol_TitleBgCollapsed]); ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 8); - + ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2(0, 0)); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, { 0, 0 }); if (ImGui::BeginChild("Tree", ImVec2(splitterSizeLeft, availableSpace.y), true)) { ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_SpanAvailWidth | @@ -54,7 +66,7 @@ void FileBrowserWidget::Draw() bool open = ImGui::TreeNodeEx("PROJECT", base_flags); if (ImGui::IsItemClicked()) { - this->currentDirectory = FileSystem::RootDirectory; + SetCurrentDirectory(FileSystem::RootDirectory); } } @@ -67,6 +79,8 @@ void FileBrowserWidget::Draw() ImGui::TreePop(); } ImGui::PopStyleVar(); + ImGui::PopStyleVar(); + ImGui::PopStyleVar(); ImGui::PopStyleColor(); ImGui::EndChild(); @@ -113,7 +127,7 @@ void FileBrowserWidget::Draw() { if (currentDirectory != FileSystem::RootDirectory) { - currentDirectory = currentDirectory->Parent; + SetCurrentDirectory(currentDirectory->Parent); } } } @@ -127,7 +141,7 @@ void FileBrowserWidget::Draw() { if (editorContext.GetSelection().Type == EditorSelectionType::Directory) { - currentDirectory = editorContext.GetSelection().Directory; + SetCurrentDirectory(editorContext.GetSelection().Directory); } } @@ -160,7 +174,7 @@ void FileBrowserWidget::Draw() if (ImGui::Button(pathLabel.c_str())) { - currentDirectory = paths[i]; + SetCurrentDirectory(paths[i]); } ImGui::SameLine(); @@ -217,6 +231,7 @@ void FileBrowserWidget::Draw() int i = 1; // current amount of item per row. if (ImGui::BeginTable("ssss", amount)) { + ImGui::PushStyleVar(ImGuiStyleVar_Alpha, opacity); // Button to go up a level. //if (m_CurrentDirectory && m_CurrentDirectory != FileSystem::RootDirectory && m_CurrentDirectory->Parent) //{ @@ -274,10 +289,12 @@ void FileBrowserWidget::Draw() } } + ImGui::PopStyleVar(); //DrawContextMenu(); //m_HasClickedOnFile = false; + ImageLoaded = 0; ImGui::EndTable(); } } @@ -308,7 +325,7 @@ void FileBrowserWidget::DrawFiletree(Ref dir) if (ImGui::IsItemClicked()) { - currentDirectory = dir; + SetCurrentDirectory(dir); } if (open) @@ -351,7 +368,7 @@ void FileBrowserWidget::DrawDirectory(Ref directory, uint32_t { if (ImGui::IsMouseDoubleClicked(0)) { - currentDirectory = directory; + SetCurrentDirectory(directory); } } @@ -386,7 +403,7 @@ void FileBrowserWidget::DrawDirectory(Ref directory, uint32_t { if (ImGui::MenuItem("Open")) { - currentDirectory = directory; + SetCurrentDirectory(directory); } ImGui::Separator(); @@ -594,7 +611,25 @@ void FileBrowserWidget::DrawFile(Ref file, uint32_t drawId) else if (fileType == FileType::Image) { const std::string path = file->GetAbsolutePath(); - textureImage = textureMgr->GetTexture2(path); + + int32_t imageNumberToLoadMax = maxImageLoaded; + if (ImGui::IsItemVisible()) + { + imageNumberToLoadMax = 1; + } + + if (ImageLoaded < maxImageLoaded || textureMgr->IsTextureLoaded2(path)) + { + if(!textureMgr->IsTextureLoaded2(path)) + ImageLoaded++; + + textureImage = textureMgr->GetTexture2(path); + } + else + { + + textureImage = textureMgr->GetTexture2("Resources/Images/env_file_icon.png"); + } } else if (fileType == FileType::Project) { @@ -653,7 +688,7 @@ void FileBrowserWidget::DrawFile(Ref file, uint32_t drawId) ImVec2 startOffset = ImVec2(imguiStyle.CellPadding.x / 2.0f, 0); ImVec2 offsetEnd = ImVec2(startOffset.x, imguiStyle.CellPadding.y / 2.0f); - ImU32 rectColor = IM_COL32(255, 255, 255, 16); + ImU32 rectColor = IM_COL32(255, 255, 255, 16 * opacity); ImGui::GetWindowDrawList()->AddRectFilled(prevScreenPos + ImVec2(0, 80) - startOffset, prevScreenPos + totalSize + offsetEnd, rectColor, 1.0f); ImU32 rectColor2 = UI::PrimaryCol; @@ -882,36 +917,38 @@ Color FileBrowserWidget::GetColorByFileType(Nuake::FileType fileType) case Nuake::FileType::Mesh: break; case Nuake::FileType::Script: - return { 1.0, 0.0, 0.0, 1.0 }; + return { 1.0, 0.0, 0.0, 1.0 * opacity }; break; case Nuake::FileType::NetScript: - return { 1.0, 0.0, 0.0, 1.0 }; + return { 1.0, 0.0, 0.0, 1.0 * opacity }; break; case Nuake::FileType::Project: - return Engine::GetProject()->Settings.PrimaryColor; + auto color = Engine::GetProject()->Settings.PrimaryColor ; + color.a *= opacity; + return color; break; case Nuake::FileType::Prefab: break; case Nuake::FileType::Scene: - return { 0, 1.0f, 1.0, 1.0 }; + return { 0, 1.0f, 1.0, 1.0 * opacity }; break; case Nuake::FileType::Wad: break; case Nuake::FileType::Map: - return { 0.0, 1.0, 0.0, 1.0 }; + return { 0.0, 1.0, 0.0, 1.0 * opacity }; break; case Nuake::FileType::Assembly: break; case Nuake::FileType::Solution: break; case Nuake::FileType::Audio: - return { 0.0, 0.0, 1.0, 1.0 }; + return { 0.0, 0.0, 1.0, 1.0 * opacity }; break; case Nuake::FileType::UI: - return { 1.0, 1.0, 0.0, 1.0 }; + return { 1.0, 1.0, 0.0, 1.0 * opacity }; break; case Nuake::FileType::CSS: - return { 1.0, 0.0, 1.0, 1.0 }; + return { 1.0, 0.0, 1.0, 1.0 * opacity }; break; default: break; diff --git a/Editor/Source/Editor/Windows/SceneEditor/Widgets/FileBrowserWidget.h b/Editor/Source/Editor/Windows/SceneEditor/Widgets/FileBrowserWidget.h index b9434d9d..9bcd28b5 100644 --- a/Editor/Source/Editor/Windows/SceneEditor/Widgets/FileBrowserWidget.h +++ b/Editor/Source/Editor/Windows/SceneEditor/Widgets/FileBrowserWidget.h @@ -6,6 +6,8 @@ #include "IEditorWidget.h" +#include "../../../../../AnimatedValue.h" + namespace Nuake { class Directory; @@ -15,10 +17,13 @@ namespace Nuake class FileBrowserWidget : public IEditorWidget { private: + AnimatedValue opacity; float splitterSizeLeft = 300.0f; float splitterSizeRight = 300.0f; - + int maxImageLoaded = 2; + int ImageLoaded = 0; Ref currentDirectory; + Ref queueDirectory; std::string searchQuery; @@ -27,6 +32,7 @@ public: ~FileBrowserWidget() = default; public: + void SetCurrentDirectory(Ref dir); void Update(float ts) override; void Draw() override; diff --git a/Editor/Source/Editor/Windows/SceneEditor/Widgets/SceneHierarchyWidget.cpp b/Editor/Source/Editor/Windows/SceneEditor/Widgets/SceneHierarchyWidget.cpp index f832e287..6ce9dff0 100644 --- a/Editor/Source/Editor/Windows/SceneEditor/Widgets/SceneHierarchyWidget.cpp +++ b/Editor/Source/Editor/Windows/SceneEditor/Widgets/SceneHierarchyWidget.cpp @@ -418,11 +418,36 @@ void SceneHierarchyWidget::DrawEntity(Nuake::Entity entity, bool drawChildrens) editorContext.SetSelection(EditorSelection(entity)); } - if (!isDragging && (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(0)) || Input::IsKeyPressed(Key::F2)) + if (!isDragging && (ImGui::IsItemHovered() && ImGui::IsMouseTripleClicked(0)) || Input::IsKeyPressed(Key::F2)) { isRenaming = true; } + if (!isDragging && (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(0)) || Input::IsKeyPressed(Key::F2)) + { + Ref editorCam = editorContext.GetScene()->m_EditorCamera; + + // Get target object's world position + glm::vec3 targetPos = glm::vec3(entity.GetComponent().GetGlobalTransform()[3]); + + // Choose a direction and distance to place the camera away from the object + glm::vec3 offset = glm::vec3(2.0f, 2.0f, 2.0f); // above and behind + + // Place camera at offset from the target + glm::vec3 camPos = targetPos + offset; + + editorCam->Translation = camPos; + + Vector3 direction = glm::normalize(targetPos - Vector3(camPos)); + float yaw = glm::degrees(atan2(direction.z, direction.x)); + float pitch = glm::degrees(asin(direction.y)); + + editorCam->TargetYaw = yaw; + editorCam->TargetPitch = pitch; + // Set the camera's transform as the inverse of the view matrix + //editorCam->SetTransform(glm::inverse(view)); + } + if (!isRenaming && selection.Type == EditorSelectionType::Entity && Input::IsKeyPressed(Key::DELETE_KEY)) { this->deletionQueue = selection.Entity; diff --git a/Editor/Source/Editor/Windows/SceneEditor/Widgets/SceneHierarchyWidget.h b/Editor/Source/Editor/Windows/SceneEditor/Widgets/SceneHierarchyWidget.h index b03a43ef..bc1a9435 100644 --- a/Editor/Source/Editor/Windows/SceneEditor/Widgets/SceneHierarchyWidget.h +++ b/Editor/Source/Editor/Windows/SceneEditor/Widgets/SceneHierarchyWidget.h @@ -18,6 +18,7 @@ public: private: std::string searchQuery; bool isRenaming; + Nuake::Entity deletionQueue; void DrawSearchBar(); diff --git a/Editor/Source/Editor/Windows/SceneEditor/Widgets/SelectionPropertyWidget.cpp b/Editor/Source/Editor/Windows/SceneEditor/Widgets/SelectionPropertyWidget.cpp index f14e3c93..dcfced7f 100644 --- a/Editor/Source/Editor/Windows/SceneEditor/Widgets/SelectionPropertyWidget.cpp +++ b/Editor/Source/Editor/Windows/SceneEditor/Widgets/SelectionPropertyWidget.cpp @@ -136,6 +136,7 @@ void SelectionPropertyWidget::DrawNone() ImGui::Text(text.c_str()); } +Nuake::Entity lastEntity; void SelectionPropertyWidget::DrawEntity(Nuake::Entity entity) { if (!entity.IsValid()) @@ -143,6 +144,14 @@ void SelectionPropertyWidget::DrawEntity(Nuake::Entity entity) return; } + + if (lastEntity != entity) + { + opacity.SetValue(0.0f); + opacity = 1.0f; + lastEntity = entity; + } + DrawAddComponentMenu(entity); transformPanel.Draw(entity); @@ -1487,6 +1496,8 @@ void SelectionPropertyWidget::DrawFile(Ref file) } } + + void SelectionPropertyWidget::DrawResource(Nuake::Resource resource) { @@ -1758,13 +1769,13 @@ void SelectionPropertyWidget::DrawNetScriptPanel(Ref file) void SelectionPropertyWidget::DrawComponent(Nuake::Entity& entity, entt::meta_any& component) { // Call into custom component drawer if one is available for this component - + ImGui::PushStyleVar(ImGuiStyleVar_Alpha, opacity); const auto componentIdHash = component.type().info().hash(); if (ComponentTypeDrawers.contains(componentIdHash)) { const auto drawerFn = ComponentTypeDrawers[componentIdHash]; drawerFn(entity, component); - + ImGui::PopStyleVar(); return; } @@ -1818,7 +1829,7 @@ void SelectionPropertyWidget::DrawComponent(Nuake::Entity& entity, entt::meta_an ImGui::PopStyleVar(); delete boldFont; } - ImGui::PopStyleVar(); + ImGui::PopStyleVar(2); } void SelectionPropertyWidget::DrawComponentContent(entt::meta_any& component) diff --git a/Editor/Source/Editor/Windows/SceneEditor/Widgets/SelectionPropertyWidget.h b/Editor/Source/Editor/Windows/SceneEditor/Widgets/SelectionPropertyWidget.h index ad310e4e..4b4212b4 100644 --- a/Editor/Source/Editor/Windows/SceneEditor/Widgets/SelectionPropertyWidget.h +++ b/Editor/Source/Editor/Windows/SceneEditor/Widgets/SelectionPropertyWidget.h @@ -2,6 +2,8 @@ #include "IEditorWidget.h" #include "../../EditorSelectionPanel.h" +#include "../../../../../AnimatedValue.h" + class EditorContext; using DrawComponentTypeFn = std::function; @@ -15,6 +17,8 @@ private: SkinnedMeshPanel skinnedMeshPanel; Ref currentFile; Ref selectedResource; + AnimatedValue opacity; + public: SelectionPropertyWidget(EditorContext& inCtx); ~SelectionPropertyWidget() = default; diff --git a/Editor/Source/Editor/Windows/SceneEditor/Widgets/ViewportWidget.cpp b/Editor/Source/Editor/Windows/SceneEditor/Widgets/ViewportWidget.cpp index 5dd8a206..1eb27578 100644 --- a/Editor/Source/Editor/Windows/SceneEditor/Widgets/ViewportWidget.cpp +++ b/Editor/Source/Editor/Windows/SceneEditor/Widgets/ViewportWidget.cpp @@ -26,13 +26,16 @@ IEditorWidget(context), gizmoDrawingMode(GizmoDrawingModes::EditorOnly) { OnSceneChanged(context.GetScene()); + + overlayOpacity.Speed = 10.0f; + overlayOpacity = 1.0f; + outlineSize = Engine::GetProject()->Settings.OutlineRadius; } ViewportWidget::~ViewportWidget() { VkRenderer::Get().RemoveViewport(sceneViewport->GetID()); } - void ViewportWidget::Update(float ts) { editorContext.GetScene()->Update(ts); @@ -58,12 +61,30 @@ void ViewportWidget::Update(float ts) void ViewportWidget::Draw() { + auto oldTarget = overlayOpacity.TargetValue; + overlayOpacity.TargetValue = Engine::GetGameState() == GameState::Playing ? 0.0f : 1.0f; + + if (overlayOpacity.TargetValue == oldTarget) + { + IAnimatedValue::UpdateAll(glm::clamp((float)Engine::GetTimestep(), 0.0f, Engine::GetFixedTimeStep())); + } + else + { + overlayOpacity.Value = (Engine::GetGameState() != GameState::Playing); + overlayOpacity.TargetValue = 1.0f - overlayOpacity.Value; + } + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); if (BeginWidgetWindow(ICON_FA_GAMEPAD + std::string("Viewport"))) { ImGui::PopStyleVar(); - DrawOverlay(); + { + ImGui::PushStyleVar(ImGuiStyleVar_Alpha, overlayOpacity.Value); + Logger::Log("Opacity: " + std::to_string(overlayOpacity.Value), "Animated"); + DrawOverlay(); + ImGui::PopStyleVar(); + } ImGuizmo::BeginFrame(); ImGuizmo::SetOrthographic(false); @@ -109,6 +130,8 @@ void ViewportWidget::Draw() ImGuizmo::AllowAxisFlip(true); ImGuizmo::SetRect(viewportMin.x, viewportMin.y, regionAvail.x, regionAvail.y); + Engine::GetProject()->Settings.OutlineRadius = outlineSize; + // TODO(grid) auto selection = editorContext.GetSelection(); if (selection.Type == EditorSelectionType::Entity && !Engine::IsPlayMode()) @@ -210,11 +233,14 @@ void ViewportWidget::Draw() Nuake::Entity entity = Nuake::Entity((entt::entity)picked, editorContext.GetScene().get()); if (entity.IsValid()) { + outlineSize.SetValue(0.0f); + outlineSize = 7.0f; editorContext.SetSelection(entity); } } else { + outlineSize.SetValue(0.0f); editorContext.SetSelection(EditorSelection()); } }); @@ -508,11 +534,6 @@ void ViewportWidget::OnDebugDraw(DebugCmd& debugCmd) void ViewportWidget::DrawOverlay() { - if (Engine::GetGameState() == GameState::Playing) - { - return; - } - ImGuiIO& io = ImGui::GetIO(); const float DISTANCE = 10.0f; int corner = 0; @@ -528,7 +549,7 @@ void ViewportWidget::DrawOverlay() ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always, window_pos_pivot); ImGui::SetNextWindowViewport(viewport->ID); - ImGui::SetNextWindowBgAlpha(0.35f); // Transparent background + ImGui::SetNextWindowBgAlpha(0.35f * overlayOpacity); // Transparent background ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 32.0f); bool showOverlay = true; @@ -542,7 +563,7 @@ void ViewportWidget::DrawOverlay() if (selectedMode) { Color color = Engine::GetProject()->Settings.PrimaryColor; - ImGui::PushStyleColor(ImGuiCol_Button, { color.r, color.g, color.b, 1.0f }); + ImGui::PushStyleColor(ImGuiCol_Button, { color.r, color.g, color.b, 1.0 }); } if (ImGui::Button(ICON_FA_ARROWS_ALT, ImVec2(30, 28)) || (ImGui::Shortcut(ImGuiKey_W, 0, ImGuiInputFlags_RouteGlobalLow) && !ImGui::IsAnyItemActive() && !IsControllingCamera)) @@ -584,7 +605,7 @@ void ViewportWidget::DrawOverlay() if (selectedMode) { Color color = Engine::GetProject()->Settings.PrimaryColor; - ImGui::PushStyleColor(ImGuiCol_Button, { color.r, color.g, color.b, 1.0f }); + ImGui::PushStyleColor(ImGuiCol_Button, { color.r, color.g, color.b, 1 }); } if (ImGui::Button(ICON_FA_EXPAND_ALT, ImVec2(30, 28)) || (ImGui::Shortcut(ImGuiKey_R, 0, ImGuiInputFlags_RouteGlobalLow) && !ImGui::IsAnyItemActive() && !IsControllingCamera)) @@ -605,7 +626,7 @@ void ViewportWidget::DrawOverlay() if (selectedMode) { Color color = Engine::GetProject()->Settings.PrimaryColor; - ImGui::PushStyleColor(ImGuiCol_Button, { color.r, color.g, color.b, 1.0f }); + ImGui::PushStyleColor(ImGuiCol_Button, { color.r, color.g, color.b, 1 }); } if (ImGui::Button(ICON_FA_GLOBE, ImVec2(30, 28))) @@ -626,7 +647,7 @@ void ViewportWidget::DrawOverlay() if (selectedMode) { Color color = Engine::GetProject()->Settings.PrimaryColor; - ImGui::PushStyleColor(ImGuiCol_Button, { color.r, color.g, color.b, 1.0f }); + ImGui::PushStyleColor(ImGuiCol_Button, { color.r, color.g, color.b, 1 }); } if (ImGui::Button(ICON_FA_CUBE, ImVec2(30, 28))) @@ -646,6 +667,7 @@ void ViewportWidget::DrawOverlay() ImGui::SameLine(); ImGui::PushItemWidth(75); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, { 6, 6 }); + ImGui::DragFloat("##snapping", &CurrentSnapping.x, 0.01f, 0.0f, 100.0f); CurrentSnapping = { CurrentSnapping.x, CurrentSnapping.x, CurrentSnapping.x }; ImGui::PopStyleVar(); @@ -696,7 +718,7 @@ void ViewportWidget::DrawOverlay() ImVec2 end = start + ImGui::GetWindowSize() - ImVec2(0, 16.0); ImVec2 startOffset = ImVec2(start.x, end.y - (normalizedSpeed * (ImGui::GetWindowHeight() - 20.0))); - ImGui::GetWindowDrawList()->AddRectFilled(startOffset + ImVec2(0, 10.0), end + ImVec2(0.0, 20.0), IM_COL32(255, 255, 255, 180), 8.0f, ImDrawFlags_RoundCornersAll); + ImGui::GetWindowDrawList()->AddRectFilled(startOffset + ImVec2(0, 10.0), end + ImVec2(0.0, 20.0), IM_COL32(255, 255, 255, 180 * overlayOpacity), 8.0f, ImDrawFlags_RoundCornersAll); ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 100); ImGui::PopStyleVar(); } diff --git a/Editor/Source/Editor/Windows/SceneEditor/Widgets/ViewportWidget.h b/Editor/Source/Editor/Windows/SceneEditor/Widgets/ViewportWidget.h index f3d6bda5..a169bfab 100644 --- a/Editor/Source/Editor/Windows/SceneEditor/Widgets/ViewportWidget.h +++ b/Editor/Source/Editor/Windows/SceneEditor/Widgets/ViewportWidget.h @@ -3,6 +3,7 @@ #include "IEditorWidget.h" #include +#include "../../../../../AnimatedValue.h" class EditorContext; @@ -26,6 +27,9 @@ private: private: Ref sceneViewport; + AnimatedValue outlineSize; + AnimatedValue overlayOpacity; + // Gizmo GizmoDrawingModes gizmoDrawingMode; diff --git a/Nuake/Source/Nuake/Rendering/Textures/TextureManager.h b/Nuake/Source/Nuake/Rendering/Textures/TextureManager.h index 62e888a5..5b571e8b 100644 --- a/Nuake/Source/Nuake/Rendering/Textures/TextureManager.h +++ b/Nuake/Source/Nuake/Rendering/Textures/TextureManager.h @@ -15,7 +15,6 @@ namespace Nuake static std::map> m_Registry; static std::map> m_Registry2; bool IsTextureLoaded(const std::string path); - bool IsTextureLoaded2(const std::string path); void LoadStaticTextures(); @@ -23,6 +22,7 @@ namespace Nuake static TextureManager* Get(); TextureManager(); + bool IsTextureLoaded2(const std::string path); Ref GetTexture(const std::string path); Ref GetTexture2(const std::string path); diff --git a/Nuake/Source/Nuake/Scene/EditorCamera.h b/Nuake/Source/Nuake/Scene/EditorCamera.h index 1c470dfe..ae02ece2 100644 --- a/Nuake/Source/Nuake/Scene/EditorCamera.h +++ b/Nuake/Source/Nuake/Scene/EditorCamera.h @@ -33,6 +33,10 @@ namespace Nuake void SetPitch(float pitch); bool IsFlying() const { return m_IsFlying; } + + + float TargetYaw = 0.f; + float TargetPitch = 0.0f; private: bool controlled = false; bool firstMouse = false; @@ -42,8 +46,6 @@ namespace Nuake float Yaw = 0.0f; float Pitch = 0.0f; - float TargetYaw = 0.f; - float TargetPitch = 0.0f; void UpdateDirection(); }; } diff --git a/Nuake/Vendors/imgui/imgui.cpp b/Nuake/Vendors/imgui/imgui.cpp index 21cfbbcf..10975840 100644 --- a/Nuake/Vendors/imgui/imgui.cpp +++ b/Nuake/Vendors/imgui/imgui.cpp @@ -9310,6 +9310,13 @@ bool ImGui::IsMouseDoubleClicked(ImGuiMouseButton button, ImGuiID owner_id) return g.IO.MouseClickedCount[button] == 2 && TestKeyOwner(MouseButtonToKey(button), owner_id); } +bool ImGui::IsMouseTripleClicked(ImGuiMouseButton button) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + return g.IO.MouseClickedCount[button] == 3 && TestKeyOwner(MouseButtonToKey(button), ImGuiKeyOwner_Any); +} + int ImGui::GetMouseClickedCount(ImGuiMouseButton button) { ImGuiContext& g = *GImGui; diff --git a/Nuake/Vendors/imgui/imgui_internal.h b/Nuake/Vendors/imgui/imgui_internal.h index 0f509833..f0dbe72b 100644 --- a/Nuake/Vendors/imgui/imgui_internal.h +++ b/Nuake/Vendors/imgui/imgui_internal.h @@ -3485,6 +3485,7 @@ namespace ImGui IMGUI_API bool IsMouseClicked(ImGuiMouseButton button, ImGuiID owner_id, ImGuiInputFlags flags = 0); IMGUI_API bool IsMouseReleased(ImGuiMouseButton button, ImGuiID owner_id); IMGUI_API bool IsMouseDoubleClicked(ImGuiMouseButton button, ImGuiID owner_id); + IMGUI_API bool IsMouseTripleClicked(ImGuiMouseButton button); // [EXPERIMENTAL] Shortcut Routing // - ImGuiKeyChord = a ImGuiKey optionally OR-red with ImGuiMod_Alt/ImGuiMod_Ctrl/ImGuiMod_Shift/ImGuiMod_Super.