diff --git a/.gitmodules b/.gitmodules index 8433ebe..906cce5 100644 --- a/.gitmodules +++ b/.gitmodules @@ -29,3 +29,6 @@ [submodule "Prism/vendor/PhysX"] path = Prism/vendor/PhysX url = https://github.com/NVIDIA-Omniverse/PhysX.git +[submodule "Prism/vendor/ImViewGuizmo"] + path = Prism/vendor/ImViewGuizmo + url = https://github.com/Ka1serM/ImViewGuizmo diff --git a/Editor/Editor/EditorLayer.cpp b/Editor/Editor/EditorLayer.cpp index 4c9acce..d14a0ab 100644 --- a/Editor/Editor/EditorLayer.cpp +++ b/Editor/Editor/EditorLayer.cpp @@ -6,6 +6,9 @@ #include #include +#define IMVIEWGUIZMO_IMPLEMENTATION +#include "ImViewGuizmo.h" + #define GLM_ENABLE_EXPERIMENTAL #include "glm/gtx/matrix_decompose.hpp" @@ -46,7 +49,7 @@ namespace Prism // OpenScene("assets/scenes/FPSDemo.scene"); NewScene(); - m_CurrentScene = m_RuntimeScene; + m_CurrentScene = m_EditorScene; AssetEditorPanel::RegisterDefaultEditors(); FileSystem::StartWatching(); @@ -589,122 +592,272 @@ namespace Prism auto viewportOffset = ImGui::GetCursorPos(); // includes tab bar auto viewportSize = ImGui::GetContentRegionAvail(); - SceneRenderer::SetViewportSize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y); - m_EditorScene->SetViewportSize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y); - if (m_RuntimeScene) - m_RuntimeScene->SetViewportSize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y); - m_EditorCamera.SetProjectionMatrix(glm::perspectiveFov(glm::radians(45.0f), viewportSize.x, viewportSize.y, 0.1f, 10000.0f)); - m_EditorCamera.SetViewportSize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y); - ImGui::Image((ImTextureRef)SceneRenderer::GetFinalColorBufferRendererID(), viewportSize, { 0, 1 }, { 1, 0 }); - - static int counter = 0; - auto windowSize = ImGui::GetWindowSize(); - ImVec2 minBound = ImGui::GetWindowPos(); - minBound.x += viewportOffset.x; - minBound.y += viewportOffset.y; - - ImVec2 maxBound = { minBound.x + windowSize.x, minBound.y + windowSize.y }; - m_ViewportBounds[0] = { minBound.x, minBound.y }; - m_ViewportBounds[1] = { maxBound.x, maxBound.y }; - m_AllowViewportCameraEvents = ImGui::IsMouseHoveringRect(minBound, maxBound); - - // ImGuizmo - if (m_GizmoType != -1 && !m_SelectionContext.empty()) + if (viewportSize.x != 0 && viewportSize.y != 0) { - auto& selection = m_SelectionContext[0]; + SceneRenderer::SetViewportSize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y); + m_EditorScene->SetViewportSize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y); + m_EditorCamera.SetProjectionMatrix(glm::perspectiveFov(glm::radians(45.0f), viewportSize.x, viewportSize.y, 0.1f, 10000.0f)); + m_EditorCamera.SetViewportSize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y); + ImGui::Image((ImTextureRef)SceneRenderer::GetFinalColorBufferRendererID(), viewportSize, { 0, 1 }, { 1, 0 }); - const auto rw = (float)ImGui::GetWindowWidth(); - const auto rh = (float)ImGui::GetWindowHeight(); - ImGuizmo::SetOrthographic(false); - ImGuizmo::SetDrawlist(); - ImGuizmo::SetRect(ImGui::GetWindowPos().x, ImGui::GetWindowPos().y, rw, rh); - bool snap = Input::IsKeyPressed(Key::LEFT_CONTROL); - - TransformComponent& entityTransform = selection.Entity.Transform(); - // glm::mat4 transform = entityTransform.GetTransform(); - glm::mat4 transform = m_CurrentScene->GetTransformRelativeToParent(selection.Entity); - float snapValue = GetSnapValue(); - float snapValues[3] = { snapValue, snapValue, snapValue }; - if (m_SelectionMode == SelectionMode::Entity) + if (ImGui::BeginDragDropTarget()) { - ImGuizmo::Manipulate(glm::value_ptr(m_EditorCamera.GetViewMatrix()), - glm::value_ptr(m_EditorCamera.GetProjectionMatrix()), - (ImGuizmo::OPERATION)m_GizmoType, - ImGuizmo::LOCAL, - glm::value_ptr(transform), - nullptr, - snap ? snapValues : nullptr); - - if (ImGuizmo::IsUsing()) + auto payload = ImGui::AcceptDragDropPayload("asset_payload"); + if (payload) { - glm::vec3 translation, rotation, scale; - Math::DecomposeTransform(transform, translation,rotation,scale); + int count = payload->DataSize / sizeof(AssetHandle); - if (Entity parent = m_CurrentScene->FindEntityByUUID(selection.Entity.GetParentUUID())) + for (int i = 0; i < count; i++) { - glm::vec3 parentTranslation, parentRotation, parentScale; - Math::DecomposeTransform(m_CurrentScene->GetTransformRelativeToParent(parent), parentTranslation, parentRotation, parentScale); + AssetHandle assetHandle = *(((AssetHandle*)payload->Data) + i); + Ref asset = AssetsManager::GetAsset(assetHandle); - glm::vec3 deltaRotation = (rotation - parentRotation) - entityTransform.Rotation; - entityTransform.Translation = translation - parentTranslation; - entityTransform.Rotation += deltaRotation; - entityTransform.Scale = scale; - } - else - { - glm::vec3 deltaRotation = rotation - entityTransform.Rotation; - entityTransform.Translation = translation; - entityTransform.Rotation += deltaRotation; - entityTransform.Scale = scale; + // We can't really support dragging and dropping scenes when we're dropping multiple assets + if (count == 1 && asset->Type == AssetType::Scene) + { + OpenScene(asset->FilePath); + } + + if (asset->Type == AssetType::Mesh) + { + Entity entity = m_EditorScene->CreateEntity(asset->FileName); + entity.AddComponent(Ref(asset)); + SelectEntity(entity); + } } } - }else - { - glm::mat4 transformBase = transform * selection.Mesh->Transform; - ImGuizmo::Manipulate(glm::value_ptr(m_EditorCamera.GetViewMatrix()), - glm::value_ptr(m_EditorCamera.GetProjectionMatrix()), - (ImGuizmo::OPERATION)m_GizmoType, - ImGuizmo::LOCAL, - glm::value_ptr(transformBase), - nullptr, - snap ? snapValues : nullptr); - - if (ImGuizmo::IsUsing()) - { - selection.Mesh->Transform = glm::inverse(entityTransform.GetTransform()) * transformBase; - } + ImGui::EndDragDropTarget(); } - } - if (ImGui::BeginDragDropTarget()) - { - auto payload = ImGui::AcceptDragDropPayload("asset_payload"); - if (payload) + auto windowSize = ImGui::GetWindowSize(); + ImVec2 minBound = ImGui::GetWindowPos(); + minBound.x += viewportOffset.x; + minBound.y += viewportOffset.y; + + ImVec2 maxBound = { minBound.x + windowSize.x, minBound.y + windowSize.y }; + m_ViewportBounds[0] = { minBound.x, minBound.y }; + m_ViewportBounds[1] = { maxBound.x, maxBound.y }; + m_AllowViewportCameraEvents = ImGui::IsMouseHoveringRect(minBound, maxBound); + + // ImGuizmo + if (m_GizmoType != -1 && !m_SelectionContext.empty()) { - int count = payload->DataSize / sizeof(AssetHandle); + auto& selection = m_SelectionContext[0]; - for (int i = 0; i < count; i++) + const auto rw = (float)ImGui::GetWindowWidth(); + const auto rh = (float)ImGui::GetWindowHeight(); + ImGuizmo::SetOrthographic(false); + ImGuizmo::SetDrawlist(); + ImGuizmo::SetRect(ImGui::GetWindowPos().x, ImGui::GetWindowPos().y, rw, rh); + + bool snap = Input::IsKeyPressed(Key::LEFT_CONTROL); + + TransformComponent& entityTransform = selection.Entity.Transform(); + // glm::mat4 transform = entityTransform.GetTransform(); + glm::mat4 transform = m_CurrentScene->GetTransformRelativeToParent(selection.Entity); + float snapValue = GetSnapValue(); + float snapValues[3] = { snapValue, snapValue, snapValue }; + if (m_SelectionMode == SelectionMode::Entity) { - AssetHandle assetHandle = *(((AssetHandle*)payload->Data) + i); - Ref asset = AssetsManager::GetAsset(assetHandle); + ImGuizmo::Manipulate(glm::value_ptr(m_EditorCamera.GetViewMatrix()), + glm::value_ptr(m_EditorCamera.GetProjectionMatrix()), + (ImGuizmo::OPERATION)m_GizmoType, + ImGuizmo::LOCAL, + glm::value_ptr(transform), + nullptr, + snap ? snapValues : nullptr); - // We can't really support dragging and dropping scenes when we're dropping multiple assets - if (count == 1 && asset->Type == AssetType::Scene) + if (ImGuizmo::IsUsing()) { - OpenScene(asset->FilePath); + glm::vec3 translation, rotation, scale; + Math::DecomposeTransform(transform, translation,rotation,scale); + + if (Entity parent = m_CurrentScene->FindEntityByUUID(selection.Entity.GetParentUUID())) + { + glm::vec3 parentTranslation, parentRotation, parentScale; + Math::DecomposeTransform(m_CurrentScene->GetTransformRelativeToParent(parent), parentTranslation, parentRotation, parentScale); + + glm::vec3 deltaRotation = (rotation - parentRotation) - entityTransform.Rotation; + entityTransform.Translation = translation - parentTranslation; + entityTransform.Rotation += deltaRotation; + entityTransform.Scale = scale; + } + else + { + glm::vec3 deltaRotation = rotation - entityTransform.Rotation; + entityTransform.Translation = translation; + entityTransform.Rotation += deltaRotation; + entityTransform.Scale = scale; + } } + }else + { + glm::mat4 transformBase = transform * selection.Mesh->Transform; + ImGuizmo::Manipulate(glm::value_ptr(m_EditorCamera.GetViewMatrix()), + glm::value_ptr(m_EditorCamera.GetProjectionMatrix()), + (ImGuizmo::OPERATION)m_GizmoType, + ImGuizmo::LOCAL, + glm::value_ptr(transformBase), + nullptr, + snap ? snapValues : nullptr); - if (asset->Type == AssetType::Mesh) + if (ImGuizmo::IsUsing()) { - Entity entity = m_EditorScene->CreateEntity(asset->FileName); - entity.AddComponent(Ref(asset)); - SelectEntity(entity); + selection.Mesh->Transform = glm::inverse(entityTransform.GetTransform()) * transformBase; } } } - ImGui::EndDragDropTarget(); + + // ImZmoToolBar + { + const float iconSize = 28.0f; + const float padding = 6.0f; + const ImU32 backgroundColor = IM_COL32(30, 30, 30, 140); + const ImVec4 orangeMain = ImVec4(0.92f, 0.45f, 0.11f, 0.8f); + + + ImGuiChildFlags child_flags = ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_AutoResizeX | ImGuiChildFlags_AutoResizeY; + ImGuiWindowFlags Gizmo_window_flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoSavedSettings | + ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav | + ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoBackground; + + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 6.0f); + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(padding, padding)); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4, 0)); + + ImGui::SetCursorPos(ImVec2(10.0f, viewportOffset.y + 10.0f)); + + if (m_SceneState != SceneState::Play) + { + if (ImGui::BeginChild("GizmoToolbar", ImVec2(0, 0), child_flags, Gizmo_window_flags)) + { + ImDrawList *draw_list = ImGui::GetWindowDrawList(); + draw_list->AddRectFilled(ImGui::GetWindowPos(), + ImVec2(ImGui::GetWindowPos().x + ImGui::GetWindowWidth(), ImGui::GetWindowPos().y + ImGui::GetWindowHeight()), + backgroundColor, 6.0f); + + auto drawGizmoBtn = [&](const char *label, int type, const char *tooltip) + { + bool isActive = (m_GizmoType == type); + if (isActive) + ImGui::PushStyleColor(ImGuiCol_Button, orangeMain); + else + ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0)); + + if (ImGui::Button(label, ImVec2(iconSize, iconSize))) + m_GizmoType = type; + if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayShort)) + ImGui::SetTooltip("%s", tooltip); + ImGui::PopStyleColor(); + }; + + drawGizmoBtn("Q", -1, "Select (Q)"); + ImGui::SameLine(); + drawGizmoBtn("W", (int)ImGuizmo::TRANSLATE, "Translate (W)"); + ImGui::SameLine(); + drawGizmoBtn("E", (int)ImGuizmo::ROTATE, "Rotate (E)"); + ImGui::SameLine(); + drawGizmoBtn("R", (int)ImGuizmo::SCALE, "Scale (R)"); + + } + ImGui::EndChild(); + } + + + float centerX = minBound.x + viewportOffset.x + viewportSize.x * 0.5f; + float topY = minBound.y + 10.0f; + + ImGui::SetNextWindowPos(ImVec2(centerX, topY), ImGuiCond_Always, ImVec2(0.5f, 0.0f)); + if (ImGui::BeginChild("DebugButton", ImVec2(0, 0), child_flags, Gizmo_window_flags)) + { + ImDrawList *draw_list = ImGui::GetWindowDrawList(); + draw_list->AddRectFilled(ImGui::GetWindowPos(), + ImVec2(ImGui::GetWindowPos().x + ImGui::GetWindowWidth(), ImGui::GetWindowPos().y + ImGui::GetWindowHeight()), + backgroundColor, 6.0f); + + + // Scene control buttons + const bool toolbarEnabled = (bool)m_CurrentScene; + ImVec4 tintColor = toolbarEnabled ? ImVec4(1, 1, 1, 1) : ImVec4(1, 1, 1, 0.5f); + + bool isEdit = m_SceneState == SceneState::Edit; + bool isPlay = m_SceneState == SceneState::Play; + // bool isSim = m_SceneState == SceneState::Pause; + + auto drawImgBtn = [&](const char *id, Ref iconRef, ImVec4 bg, auto func) + { + ImGui::PushStyleColor(ImGuiCol_Button, bg); + const auto textureID = (ImTextureID)(uintptr_t)iconRef->GetRendererID(); + if (ImGui::ImageButton(id, textureID, ImVec2(iconSize - 6, iconSize - 6), {0, 0}, {1, 1}, {0, 0, 0, 0}, tintColor)) + { + if (toolbarEnabled) + func(); + } + ImGui::PopStyleColor(); + }; + + if (isEdit) + { + drawImgBtn("##Play", m_PlayButtonTex, ImVec4(0, 0, 0, 0), [this]() + { OnScenePlay(); }); + } + else if (isPlay) + { + drawImgBtn("##Stop", m_StopButtonTex, ImVec4(0.8f, 0.1f, 0.1f, 0.6f), [this]() + { OnSceneStop(); }); + } + } + ImGui::EndChild(); + + ImGui::PopStyleVar(3); + } + + // ImViewGuizmo + if (m_SceneState != SceneState::Play) + { + ImViewGuizmo::BeginFrame(); + + auto &style = ImViewGuizmo::GetStyle(); + style.scale = 0.8f; + + + const float gizmoSize = 256.0f * style.scale; + const float inset = gizmoSize * 0.1f; + + const ImVec2 gizmoCenter = ImVec2( + maxBound.x - gizmoSize * 0.5f + inset, + minBound.y + gizmoSize * 0.5f - inset); + + glm::vec3 cameraPos = m_EditorCamera.GetPosition(); + glm::vec3 focusPosition = m_EditorCamera.GetFocusPosition(); + + float CameraYaw = m_EditorCamera.GetYaw(); + float CameraPitch = -m_EditorCamera.GetPitch(); + + glm::quat qYaw = glm::angleAxis(CameraYaw, glm::vec3(0.0f, 1.0f, 0.0f)); + glm::quat qPitch = glm::angleAxis(CameraPitch, glm::vec3(1.0f, 0.0f, 0.0f)); + glm::quat cameraRot = qYaw * qPitch; + + + if (ImViewGuizmo::Rotate(cameraPos, cameraRot, glm::vec3(0.0f), gizmoCenter)) + { + + glm::vec3 forward = cameraRot * glm::vec3(0.0f, 0.0f, -1.0f); + float newPitch = glm::asin(glm::clamp(-forward.y, -1.0f, 1.0f)); + float newYaw = -glm::atan(forward.x, -forward.z); + + float distance = glm::length(cameraPos - focusPosition); + m_EditorCamera.SetDistance(distance); + m_EditorCamera.SetFocusPosition(focusPosition); + m_EditorCamera.SetYawPitch(newYaw, newPitch); + } + } + + + if (m_RuntimeScene) + m_RuntimeScene->SetViewportSize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y); } } @@ -756,7 +909,7 @@ namespace Prism break; Entity selectedEntity = m_SelectionContext[0].Entity; - m_EditorCamera.Focus(selectedEntity.Transform().Translation); + m_EditorCamera.SetFocusPosition(selectedEntity.Transform().Translation); break; } } @@ -1059,23 +1212,25 @@ namespace Prism m_RuntimeScene = Ref::Create(); m_EditorScene->CopyTo(m_RuntimeScene); - m_RuntimeScene->OnRuntimeStart(); - m_SceneHierarchyPanel->SetContext(m_RuntimeScene); m_CurrentScene = m_RuntimeScene; + + m_SceneHierarchyPanel->SetContext(m_CurrentScene); + m_CurrentScene->OnRuntimeStart(); } void EditorLayer::OnSceneStop() { - m_RuntimeScene->OnRuntimeStop(); + m_CurrentScene->OnRuntimeStop(); m_SceneState = SceneState::Edit; // Unload runtime scene m_RuntimeScene = nullptr; m_SelectionContext.clear(); - ScriptEngine::SetSceneContext(m_EditorScene); - m_SceneHierarchyPanel->SetContext(m_EditorScene); m_CurrentScene = m_EditorScene; + + ScriptEngine::SetSceneContext(m_CurrentScene); + m_SceneHierarchyPanel->SetContext(m_CurrentScene); } float EditorLayer::GetSnapValue() const diff --git a/Editor/assets/shaders/InfiniteGrid.glsl b/Editor/assets/shaders/InfiniteGrid.glsl index b18de1a..2760099 100644 --- a/Editor/assets/shaders/InfiniteGrid.glsl +++ b/Editor/assets/shaders/InfiniteGrid.glsl @@ -12,9 +12,8 @@ uniform mat4 u_Projection; uniform vec3 u_CameraPosition; out CameraData{ - mat4 View; - mat4 Projection; - vec3 CameraPosition; + mat4 ViewProjection; + vec3 Position; }CameraOutput; out vec3 v_NearPoint; @@ -31,9 +30,8 @@ void main() { v_NearPoint = unprojectPoint(a_Position.x, a_Position.y, 0.0); v_FarPoint = unprojectPoint(a_Position.x, a_Position.y, 1.0); - CameraOutput.View = u_View; - CameraOutput.Projection = u_Projection; - CameraOutput.CameraPosition = u_CameraPosition; + CameraOutput.ViewProjection = u_Projection * u_View; + CameraOutput.Position = u_CameraPosition; gl_Position = vec4(a_Position, 1.0); } @@ -47,22 +45,21 @@ in vec3 v_NearPoint; in vec3 v_FarPoint; in CameraData{ - mat4 View; - mat4 Projection; - vec3 CameraPosition; + mat4 ViewProjection; + vec3 Position; }CameraInput; // Grid plane: 0 = XZ (Y up), 1 = XY (Z forward), 2 = YZ (X right) -uniform int u_GridPlane = 0; -uniform float u_GridScale = 1.0; -uniform vec4 u_GridColorThin = vec4(0.5, 0.5, 0.5, 0.4); -uniform vec4 u_GridColorThick = vec4(0.5, 0.5, 0.5, 0.6); -uniform vec4 u_AxisColorX = vec4(0.9, 0.2, 0.2, 1.0); -uniform vec4 u_AxisColorZ = vec4(0.2, 0.2, 0.9, 1.0); -uniform float u_FadeDistance = 500.0; +uniform int u_GridPlane; +uniform float u_GridScale; +uniform vec4 u_GridColorThin; +uniform vec4 u_GridColorThick; +uniform vec4 u_AxisColorX; +uniform vec4 u_AxisColorZ; +uniform float u_FadeDistance; float computeDepth(vec3 pos) { - vec4 clipSpacePos = CameraInput.Projection * CameraInput.View * vec4(pos, 1.0); + vec4 clipSpacePos = CameraInput.ViewProjection * vec4(pos, 1.0); return clipSpacePos.z / clipSpacePos.w; } @@ -155,11 +152,11 @@ void main() { // === Fading === // Radial fade - float dist = length(fragPos3D - CameraInput.CameraPosition); + float dist = length(fragPos3D - CameraInput.Position); float radialFade = 1.0 - smoothstep(u_FadeDistance * 0.3, u_FadeDistance, dist); // Normal fade (view angle) - vec3 viewDir = normalize(fragPos3D - CameraInput.CameraPosition); + vec3 viewDir = normalize(fragPos3D - CameraInput.Position); float viewAngle = getViewAngleComponent(viewDir); float normalFade = smoothstep(0.0, 0.15, viewAngle); @@ -179,7 +176,8 @@ void main() { // LOD blend vec2 deriv1 = fwidth(gridCoord1); - float lodFactor = smoothstep(0.3, 0.6, max(deriv1.x, deriv1.y)); + float lodFactor = smoothstep(20.0, 200.0, dist); +// float lodFactor = smoothstep(0.2, 0.5, max(deriv1.x, deriv1.y)); // Combine grids float gridIntensity = mix(max(grid1, grid10 * 0.7), grid10, lodFactor); diff --git a/Prism/CMakeLists.txt b/Prism/CMakeLists.txt index a6d3d98..40eee3a 100644 --- a/Prism/CMakeLists.txt +++ b/Prism/CMakeLists.txt @@ -45,6 +45,11 @@ file(GLOB IMGUIZMO_SOURCE ${IMGUIZMO_DIR}/*.cpp) list(APPEND SRC_SOURCE ${IMGUIZMO_SOURCE}) + +# ----------- ImViewGuizmo ------------- +set(IMVIEWGUIZMO_DIR vendor/ImViewGuizmo) + + # ------------- NVIDIA PhysX ------------- # PhysX/physx/buildtools/presets/*.xml # PX_GENERATE_STATIC_LIBRARIES=True @@ -117,6 +122,7 @@ set(TARGET_INCLUDE_DIR $ ${IMGUI_DIR} ${IMGUIZMO_DIR} + ${IMVIEWGUIZMO_DIR} ) # ------------- debug Defines ------------- diff --git a/Prism/src/Prism/Editor/EditorCamera.cpp b/Prism/src/Prism/Editor/EditorCamera.cpp index 192b5ba..d8f477f 100644 --- a/Prism/src/Prism/Editor/EditorCamera.cpp +++ b/Prism/src/Prism/Editor/EditorCamera.cpp @@ -33,7 +33,7 @@ namespace Prism UpdateCameraView(); } - void EditorCamera::Focus(const glm::vec3& focusPoint) + void EditorCamera::SetFocusPosition(const glm::vec3& focusPoint) { m_FocalPoint = focusPoint; if (m_Distance > m_MinFocusDistance) diff --git a/Prism/src/Prism/Editor/EditorCamera.h b/Prism/src/Prism/Editor/EditorCamera.h index 46f183a..e8b9c9d 100644 --- a/Prism/src/Prism/Editor/EditorCamera.h +++ b/Prism/src/Prism/Editor/EditorCamera.h @@ -21,7 +21,8 @@ namespace Prism EditorCamera() = default; EditorCamera(const glm::mat4& projectionMatrix); - void Focus(const glm::vec3& focusPoint); + void SetFocusPosition(const glm::vec3& focusPoint); + glm::vec3 GetFocusPosition() const {return m_FocalPoint; } void OnUpdate(TimeStep deltaTime); void OnEvent(Event& e); @@ -42,6 +43,7 @@ namespace Prism float GetPitch() const { return m_Pitch; } + void SetYawPitch(const float yaw, const float pitch) { m_Yaw = yaw; m_Pitch = pitch; } float GetYaw() const { return m_Yaw; } void OnImGuiRender(); diff --git a/Prism/src/Prism/Editor/SceneHierachyPanel.cpp b/Prism/src/Prism/Editor/SceneHierachyPanel.cpp index ee66904..0004e7a 100644 --- a/Prism/src/Prism/Editor/SceneHierachyPanel.cpp +++ b/Prism/src/Prism/Editor/SceneHierachyPanel.cpp @@ -144,7 +144,9 @@ namespace Prism { if (!m_SelectionContext.HasComponent()) { - if (ImGui::Button(componentName)) + + const float buttonWidth = ImGui::GetContentRegionAvail().x; + if (ImGui::Button(componentName, ImVec2(buttonWidth, 0))) { m_SelectionContext.AddComponent(); ImGui::CloseCurrentPopup(); @@ -157,7 +159,8 @@ namespace Prism { if (!m_SelectionContext.HasComponent()) { - if (ImGui::Button(componentName)) + const float buttonWidth = ImGui::GetContentRegionAvail().x; + if (ImGui::Button(componentName, ImVec2(buttonWidth, 0))) { T& component = m_SelectionContext.AddComponent(); function(component); @@ -169,7 +172,7 @@ namespace Prism void SceneHierarchyPanel::OnImGuiRender() { ImGui::Begin("Scene Hierarchy"); - ImRect windowRect = { ImGui::GetWindowContentRegionMin(), ImGui::GetWindowContentRegionMax() }; + const ImRect windowRect = { ImGui::GetWindowContentRegionMin(), ImGui::GetWindowContentRegionMax() }; if (m_Context) { @@ -217,15 +220,19 @@ namespace Prism if (ImGui::BeginMenu("Create")) { + bool isCreated = false; + if (ImGui::MenuItem("Empty Entity")) { auto newEntity = m_Context->CreateEntity("Empty Entity"); + isCreated = true; SetSelected(newEntity); } if (ImGui::MenuItem("Mesh")) { auto newEntity = m_Context->CreateEntity("Mesh"); newEntity.AddComponent(); + isCreated = true; SetSelected(newEntity); } ImGui::Separator(); @@ -233,15 +240,23 @@ namespace Prism { auto newEntity = m_Context->CreateEntity("Directional Light"); newEntity.AddComponent(); + isCreated = true; SetSelected(newEntity); } if (ImGui::MenuItem("Sky Light")) { auto newEntity = m_Context->CreateEntity("Sky Light"); newEntity.AddComponent(); + isCreated = true; SetSelected(newEntity); } ImGui::EndMenu(); + + if (isCreated) + { + if (m_SelectionChangedCallback) + m_SelectionChangedCallback(m_SelectionContext); + } } ImGui::EndPopup(); } @@ -522,20 +537,18 @@ namespace Prism if (ImGui::BeginPopup("AddComponentPanel")) { - AddComponentPopup("Camera"); - AddComponentPopup("Mesh"); - AddComponentPopup("Directional Light"); - AddComponentPopup("sky Light"); - AddComponentPopup("Script"); - AddComponentPopup("SpriteRenderer"); + ImGui::SeparatorText("2D Component"); AddComponentPopup("RigidBody2D"); + AddComponentPopup("SpriteRenderer2D"); AddComponentPopup("BoxCollider2D"); AddComponentPopup("CircleCollider2D"); + + ImGui::SeparatorText("3D Component"); + AddComponentPopup("Mesh"); AddComponentPopup("RigidBody"); AddComponentPopup("BoxCollider"); AddComponentPopup("SphereCollider"); AddComponentPopup("CapsuleCollider"); - AddComponentPopup("MeshCollider", [&](MeshColliderComponent& component) { if (m_SelectionContext.HasComponent()) @@ -545,6 +558,13 @@ namespace Prism } }); + ImGui::SeparatorText("Light Component"); + AddComponentPopup("Directional Light"); + AddComponentPopup("sky Light"); + + ImGui::SeparatorText("Other Component"); + AddComponentPopup("Camera"); + AddComponentPopup("Script"); ImGui::EndPopup(); } diff --git a/Prism/src/Prism/Physics/PhysicsWrappers.cpp b/Prism/src/Prism/Physics/PhysicsWrappers.cpp index 336183a..d6bdd99 100644 --- a/Prism/src/Prism/Physics/PhysicsWrappers.cpp +++ b/Prism/src/Prism/Physics/PhysicsWrappers.cpp @@ -339,7 +339,7 @@ namespace Prism } glm::vec3 submeshTranslation, submeshRotation, submeshScale; - Math::DecomposeTransform(submesh.LocalTransform, submeshTranslation, submeshRotation, submeshScale); + Math::DecomposeTransform(submesh.Transform, submeshTranslation, submeshRotation, submeshScale); auto triangleGeometry = physx::PxTriangleMeshGeometry(triangleMesh, physx::PxMeshScale(ToPhysXVector(submeshScale * scale))); physx::PxMaterial* material = s_Physics->createMaterial(0, 0, 0); // Dummy material, will be replaced at runtime. diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLShader.cpp b/Prism/src/Prism/Platform/OpenGL/OpenGLShader.cpp index 75d51bd..8bdbc18 100644 --- a/Prism/src/Prism/Platform/OpenGL/OpenGLShader.cpp +++ b/Prism/src/Prism/Platform/OpenGL/OpenGLShader.cpp @@ -20,7 +20,6 @@ namespace Prism m_Name = found != std::string::npos ? m_Name.substr(0, found) : m_Name; OpenGLShader::Reload(); - } Ref OpenGLShader::CreateFromString(const std::string& source) @@ -60,6 +59,7 @@ namespace Prism } m_Loaded = true; + PM_CORE_INFO("shader loaded: {}", m_Name); }); } diff --git a/Prism/src/Prism/Renderer/SceneRenderer.cpp b/Prism/src/Prism/Renderer/SceneRenderer.cpp index 880cbe8..9f26f72 100644 --- a/Prism/src/Prism/Renderer/SceneRenderer.cpp +++ b/Prism/src/Prism/Renderer/SceneRenderer.cpp @@ -1130,8 +1130,26 @@ namespace Prism if (UI::BeginTreeNode("Grid Config", false)) { + // Grid plane: 0 = XZ (Y up), 1 = XY (Z forward), 2 = YZ (X right) + const char* projTypeStrings[] = { "XZ (Y up)", "XY (Z forward)", "YZ (X right)" }; + const char* currentMode = projTypeStrings[s_Data.GridData.GridPlane]; + if (ImGui::BeginCombo("Grid Plane Mode", currentMode)) + { + for (int type = 0; type < 3; type++) + { + const bool is_selected = (currentMode == projTypeStrings[type]); + if (ImGui::Selectable(projTypeStrings[type], is_selected)) + { + currentMode = projTypeStrings[type]; + s_Data.GridData.GridPlane = type; + } + if (is_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + UI::BeginPropertyGrid(); - UI::PropertySlider("GridPlane", s_Data.GridData.GridPlane, 0, 2); UI::Property("GridScale", s_Data.GridData.GridScale); UI::PropertyColor("GridColorThin", s_Data.GridData.GridColorThin); UI::PropertyColor("GridColorThick", s_Data.GridData.GridColorThick); diff --git a/Prism/vendor/ImViewGuizmo b/Prism/vendor/ImViewGuizmo new file mode 160000 index 0000000..d4e0130 --- /dev/null +++ b/Prism/vendor/ImViewGuizmo @@ -0,0 +1 @@ +Subproject commit d4e0130c18f631e2fb66e933f820f6d68ad57d78