Formalize scene viewport HUD overlay
This commit is contained in:
@@ -0,0 +1,89 @@
|
|||||||
|
# SceneViewport Overlay/Gizmo Rework Checkpoint
|
||||||
|
|
||||||
|
## Update 2026-04-03
|
||||||
|
|
||||||
|
### Phase 4 Completed
|
||||||
|
|
||||||
|
- Formalized a dedicated HUD overlay API via `SceneViewportHudOverlay.{h,cpp}`.
|
||||||
|
- `SceneViewPanel` no longer calls the orientation gizmo draw/hit helpers directly.
|
||||||
|
- HUD hit testing now flows through `HitTestSceneViewportHudOverlay(...)`.
|
||||||
|
- World overlay remains on the formal overlay/pass path; HUD stays on the ImGui/UI path.
|
||||||
|
- Removed the legacy `SceneViewportOverlayRenderer.*` shim.
|
||||||
|
|
||||||
|
### Verification
|
||||||
|
|
||||||
|
- `cmake --build build --config Debug --target editor_tests -- /p:BuildProjectReferences=false`
|
||||||
|
- `build/tests/Editor/Debug/editor_tests.exe --gtest_filter=SceneViewportOverlayRenderer_Test.*:SceneViewportOverlayProviderRegistryTest.*:ViewportRenderFlowUtilsTest.*`
|
||||||
|
- `cmake --build build --config Debug --target XCEditor`
|
||||||
|
|
||||||
|
All commands completed successfully in `Debug`.
|
||||||
|
|
||||||
|
### Next Step
|
||||||
|
|
||||||
|
- Continue Phase 5 cleanup: keep shrinking residual viewport/UI glue in `SceneViewPanel` and formalize remaining editor-only overlay/resource entry points behind dedicated services/providers.
|
||||||
|
|
||||||
|
日期:`2026-04-02`
|
||||||
|
|
||||||
|
## 本轮完成
|
||||||
|
|
||||||
|
- `ViewportHostService` 已持有并缓存 scene viewport 的 canonical `SceneViewportOverlayFrameData`
|
||||||
|
- `SceneViewPanel` 不再自己重复构建 scene editor overlay frame data,而是统一从 host service 取
|
||||||
|
- `scene icon` 已接入 `handleRecords`
|
||||||
|
- 新增 `SceneViewportOverlayHitTester.h`,scene icon 的 hover/click 已改为基于 canonical overlay handle 命中
|
||||||
|
- `SceneViewportEditorOverlayData.h` 已扩展为通用 handle record 结构,支持优先级与多种命中形状
|
||||||
|
- 新增 `SceneViewportOverlayHandleBuilder.h`,开始把 move/rotate/scale gizmo 的 draw data 转成 canonical handle records
|
||||||
|
- `SceneViewPanel.cpp` 已改为通过统一 `HitTestSceneViewportOverlayHandles(...)` 解析 transform gizmo 的 hover / click-begin
|
||||||
|
- `SceneViewportEditorOverlayPass` 已新增 screen-space triangle primitive 支持,可直接绘制 transform gizmo 的屏幕空间几何
|
||||||
|
- `ViewportHostService` 已开始在 host 侧构建 transient transform gizmo overlay frame data,`SceneViewPanel.cpp` 只提交 overlay 与 gizmo handle build inputs
|
||||||
|
- transform gizmo 的 handle build inputs 组装 helper 已从 `SceneViewPanel.cpp` 挪到 `SceneViewportOverlayHandleBuilder.h`
|
||||||
|
- `transform gizmo` 的 selection/context/refresh/cancel helper 已从 `SceneViewPanel.cpp` 挪到 `SceneViewportTransformGizmoFrameBuilder.h`
|
||||||
|
- move / rotate / scale gizmo 已不再直接依赖 `DrawSceneViewportOverlay()` 的 ImGui world draw 分支出图
|
||||||
|
- `SceneViewportOverlayRenderer.cpp` 中旧的 gizmo / scene icon / scene line ImGui 绘制逻辑已删除,当前只保留 HUD 类 overlay
|
||||||
|
- `SceneViewPanel.cpp` 中旧的 scene icon 临时命中逻辑已删除
|
||||||
|
- `SceneViewPanel.cpp` 中旧的 gizmo 直接 hit test 入口已从 hover / click-begin 仲裁链上移除
|
||||||
|
- `SceneViewPanel.cpp` 中已经失效的 camera/light world overlay 组装辅助函数已删除,避免 panel 继续承担 world overlay 构建职责
|
||||||
|
- `SceneViewPanel.cpp` 中交互前命中与交互后绘制的 transform gizmo 刷新链路已收敛到同一套 helper,减少重复的 context/update/submit 逻辑
|
||||||
|
- `GetSceneViewInteractionOverlayFrameData(...)` 已改为由 host 按传入的 transform gizmo inputs 现场组合交互 frame,`SceneViewPanel` 不再为命中阶段先写入 transient overlay 缓存
|
||||||
|
- `ViewportHostService` 已改为缓存 transient transform gizmo 的原始 overlay + inputs,并在 render 阶段现场构建 frame data;panel 不再驱动这部分 frame data 的即时生成
|
||||||
|
|
||||||
|
## 当前状态
|
||||||
|
|
||||||
|
- `camera frustum`
|
||||||
|
- `directional light gizmo`
|
||||||
|
- `camera/light scene icon`
|
||||||
|
|
||||||
|
上述内容的绘制数据已经在 overlay builder / overlay frame data 路径上。
|
||||||
|
|
||||||
|
`scene icon` 与 `transform gizmo` 的 hover / click-begin 已经开始走统一 handle 数据。
|
||||||
|
|
||||||
|
目前 `transform gizmo` 尚未完全收口的部分主要是:
|
||||||
|
|
||||||
|
- move gizmo
|
||||||
|
- rotate gizmo
|
||||||
|
- scale gizmo
|
||||||
|
|
||||||
|
它们的 draw data / drag solver 仍然各自保留,且 draw data 仍然由 `SceneViewPanel` 驱动生成。
|
||||||
|
|
||||||
|
另外,`SceneViewPanel` 目前仍要控制 transform gizmo 的最终绘制提交时机;这说明绘制与命中都已经开始收口,但 transform gizmo 还没有完全并入单帧单份的 canonical overlay 数据,也还没有把 draw-state 提交流程完全下沉到 host。
|
||||||
|
|
||||||
|
## 本轮验证
|
||||||
|
|
||||||
|
以下翻译单元已在 `Debug` 下单独编译通过:
|
||||||
|
|
||||||
|
- `editor/src/panels/SceneViewPanel.cpp`
|
||||||
|
- `editor/src/Viewport/SceneViewportTransformGizmoFrameBuilder.h`
|
||||||
|
- `editor/src/Viewport/SceneViewportOverlayBuilder.cpp`
|
||||||
|
- `editor/src/Viewport/Passes/SceneViewportEditorOverlayPass.cpp`
|
||||||
|
- `editor/src/Application.cpp`
|
||||||
|
|
||||||
|
完整 `XCEditor` 整体编译当前仍被与本轮任务无关的 `engine/src/Resources/Shader/ShaderLoader.cpp` 缺失阻塞,因此本轮没有做整包通过确认。
|
||||||
|
|
||||||
|
## 下一步建议
|
||||||
|
|
||||||
|
下一小步应继续沿着统一 handle 数据收口,但先不要动 gizmo drag solver:
|
||||||
|
|
||||||
|
1. 继续把 transform gizmo 的最终绘制提交时机从 `SceneViewPanel` 往 host / canonical builder 收口,减少 panel 对 render-frame orchestration 的直接控制
|
||||||
|
2. 在不改 drag solver 的前提下,把 transform gizmo 的最终 draw-state 提交流程也继续从 `SceneViewPanel` 往 host 下沉,让 panel 只消费统一命中结果和少量 gizmo state
|
||||||
|
3. 等 transform gizmo 的提交/组装职责继续下沉后,再收最后一层 drag begin 之后的求解入口
|
||||||
|
|
||||||
|
目标是先统一“点中了谁”,再统一“如何拖动”。
|
||||||
@@ -82,10 +82,10 @@ add_executable(${PROJECT_NAME} WIN32
|
|||||||
src/Viewport/SceneViewportMoveGizmo.cpp
|
src/Viewport/SceneViewportMoveGizmo.cpp
|
||||||
src/Viewport/SceneViewportRotateGizmo.cpp
|
src/Viewport/SceneViewportRotateGizmo.cpp
|
||||||
src/Viewport/SceneViewportScaleGizmo.cpp
|
src/Viewport/SceneViewportScaleGizmo.cpp
|
||||||
|
src/Viewport/SceneViewportHudOverlay.cpp
|
||||||
src/Viewport/SceneViewportOrientationGizmo.cpp
|
src/Viewport/SceneViewportOrientationGizmo.cpp
|
||||||
src/Viewport/SceneViewportOverlayBuilder.cpp
|
src/Viewport/SceneViewportOverlayBuilder.cpp
|
||||||
src/Viewport/SceneViewportOverlayProviders.cpp
|
src/Viewport/SceneViewportOverlayProviders.cpp
|
||||||
src/Viewport/SceneViewportOverlayRenderer.cpp
|
|
||||||
src/Viewport/Passes/SceneViewportEditorOverlayPass.cpp
|
src/Viewport/Passes/SceneViewportEditorOverlayPass.cpp
|
||||||
src/Viewport/Passes/SceneViewportGridPass.cpp
|
src/Viewport/Passes/SceneViewportGridPass.cpp
|
||||||
src/Viewport/Passes/SceneViewportSelectionOutlinePass.cpp
|
src/Viewport/Passes/SceneViewportSelectionOutlinePass.cpp
|
||||||
|
|||||||
64
editor/src/Viewport/SceneViewportHudOverlay.cpp
Normal file
64
editor/src/Viewport/SceneViewportHudOverlay.cpp
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
#include "SceneViewportHudOverlay.h"
|
||||||
|
|
||||||
|
#include "SceneViewportOrientationGizmo.h"
|
||||||
|
|
||||||
|
namespace XCEngine {
|
||||||
|
namespace Editor {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
bool IsViewportRectValid(const ImVec2& viewportMin, const ImVec2& viewportMax) {
|
||||||
|
return viewportMax.x - viewportMin.x > 1.0f &&
|
||||||
|
viewportMax.y - viewportMin.y > 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void DrawSceneViewportHudOverlay(
|
||||||
|
ImDrawList* drawList,
|
||||||
|
const SceneViewportHudOverlayData& overlay,
|
||||||
|
const ImVec2& viewportMin,
|
||||||
|
const ImVec2& viewportMax) {
|
||||||
|
if (drawList == nullptr ||
|
||||||
|
!overlay.HasVisibleElements() ||
|
||||||
|
!IsViewportRectValid(viewportMin, viewportMax)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
drawList->PushClipRect(viewportMin, viewportMax, true);
|
||||||
|
if (overlay.showOrientationGizmo) {
|
||||||
|
DrawSceneViewportOrientationGizmo(
|
||||||
|
drawList,
|
||||||
|
overlay.sceneOverlay,
|
||||||
|
viewportMin,
|
||||||
|
viewportMax);
|
||||||
|
}
|
||||||
|
drawList->PopClipRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
SceneViewportHudOverlayHitResult HitTestSceneViewportHudOverlay(
|
||||||
|
const SceneViewportHudOverlayData& overlay,
|
||||||
|
const ImVec2& viewportMin,
|
||||||
|
const ImVec2& viewportMax,
|
||||||
|
const ImVec2& mousePosition) {
|
||||||
|
SceneViewportHudOverlayHitResult result = {};
|
||||||
|
if (!overlay.HasVisibleElements() || !IsViewportRectValid(viewportMin, viewportMax)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (overlay.showOrientationGizmo) {
|
||||||
|
const SceneViewportOrientationAxis axis = HitTestSceneViewportOrientationGizmo(
|
||||||
|
overlay.sceneOverlay,
|
||||||
|
viewportMin,
|
||||||
|
viewportMax,
|
||||||
|
mousePosition);
|
||||||
|
if (axis != SceneViewportOrientationAxis::None) {
|
||||||
|
result.kind = SceneViewportHudOverlayHitKind::OrientationAxis;
|
||||||
|
result.orientationAxis = axis;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Editor
|
||||||
|
} // namespace XCEngine
|
||||||
57
editor/src/Viewport/SceneViewportHudOverlay.h
Normal file
57
editor/src/Viewport/SceneViewportHudOverlay.h
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "IViewportHostService.h"
|
||||||
|
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace XCEngine {
|
||||||
|
namespace Editor {
|
||||||
|
|
||||||
|
enum class SceneViewportHudOverlayHitKind : uint8_t {
|
||||||
|
None = 0,
|
||||||
|
OrientationAxis
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SceneViewportHudOverlayHitResult {
|
||||||
|
SceneViewportHudOverlayHitKind kind = SceneViewportHudOverlayHitKind::None;
|
||||||
|
SceneViewportOrientationAxis orientationAxis = SceneViewportOrientationAxis::None;
|
||||||
|
|
||||||
|
bool HasHit() const {
|
||||||
|
return kind != SceneViewportHudOverlayHitKind::None;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SceneViewportHudOverlayData {
|
||||||
|
SceneViewportOverlayData sceneOverlay = {};
|
||||||
|
bool showOrientationGizmo = true;
|
||||||
|
|
||||||
|
bool HasVisibleElements() const {
|
||||||
|
return sceneOverlay.valid && showOrientationGizmo;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline SceneViewportHudOverlayData BuildSceneViewportHudOverlayData(
|
||||||
|
const SceneViewportOverlayData& sceneOverlay,
|
||||||
|
bool showOrientationGizmo = true) {
|
||||||
|
SceneViewportHudOverlayData data = {};
|
||||||
|
data.sceneOverlay = sceneOverlay;
|
||||||
|
data.showOrientationGizmo = showOrientationGizmo;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawSceneViewportHudOverlay(
|
||||||
|
ImDrawList* drawList,
|
||||||
|
const SceneViewportHudOverlayData& overlay,
|
||||||
|
const ImVec2& viewportMin,
|
||||||
|
const ImVec2& viewportMax);
|
||||||
|
|
||||||
|
SceneViewportHudOverlayHitResult HitTestSceneViewportHudOverlay(
|
||||||
|
const SceneViewportHudOverlayData& overlay,
|
||||||
|
const ImVec2& viewportMin,
|
||||||
|
const ImVec2& viewportMax,
|
||||||
|
const ImVec2& mousePosition);
|
||||||
|
|
||||||
|
} // namespace Editor
|
||||||
|
} // namespace XCEngine
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
#include "SceneViewportOverlayRenderer.h"
|
|
||||||
|
|
||||||
#include "SceneViewportOrientationGizmo.h"
|
|
||||||
|
|
||||||
namespace XCEngine {
|
|
||||||
namespace Editor {
|
|
||||||
|
|
||||||
void DrawSceneViewportOverlay(
|
|
||||||
ImDrawList* drawList,
|
|
||||||
const SceneViewportOverlayData& overlay,
|
|
||||||
const ImVec2& viewportMin,
|
|
||||||
const ImVec2& viewportMax,
|
|
||||||
const ImVec2& viewportSize) {
|
|
||||||
if (drawList == nullptr || viewportSize.x <= 1.0f || viewportSize.y <= 1.0f) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
drawList->PushClipRect(viewportMin, viewportMax, true);
|
|
||||||
if (overlay.valid) {
|
|
||||||
DrawSceneViewportOrientationGizmo(drawList, overlay, viewportMin, viewportMax);
|
|
||||||
}
|
|
||||||
drawList->PopClipRect();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Editor
|
|
||||||
} // namespace XCEngine
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "IViewportHostService.h"
|
|
||||||
|
|
||||||
#include <imgui.h>
|
|
||||||
|
|
||||||
namespace XCEngine {
|
|
||||||
namespace Editor {
|
|
||||||
|
|
||||||
void DrawSceneViewportOverlay(
|
|
||||||
ImDrawList* drawList,
|
|
||||||
const SceneViewportOverlayData& overlay,
|
|
||||||
const ImVec2& viewportMin,
|
|
||||||
const ImVec2& viewportMax,
|
|
||||||
const ImVec2& viewportSize);
|
|
||||||
|
|
||||||
} // namespace Editor
|
|
||||||
} // namespace XCEngine
|
|
||||||
@@ -4,11 +4,10 @@
|
|||||||
#include "Core/ISelectionManager.h"
|
#include "Core/ISelectionManager.h"
|
||||||
#include "SceneViewPanel.h"
|
#include "SceneViewPanel.h"
|
||||||
#include "Viewport/SceneViewportEditorOverlayData.h"
|
#include "Viewport/SceneViewportEditorOverlayData.h"
|
||||||
|
#include "Viewport/SceneViewportHudOverlay.h"
|
||||||
#include "Viewport/SceneViewportOverlayHandleBuilder.h"
|
#include "Viewport/SceneViewportOverlayHandleBuilder.h"
|
||||||
#include "Viewport/SceneViewportOverlayHitTester.h"
|
#include "Viewport/SceneViewportOverlayHitTester.h"
|
||||||
#include "Viewport/SceneViewportMath.h"
|
#include "Viewport/SceneViewportMath.h"
|
||||||
#include "Viewport/SceneViewportOrientationGizmo.h"
|
|
||||||
#include "Viewport/SceneViewportOverlayRenderer.h"
|
|
||||||
#include "Viewport/SceneViewportTransformGizmoFrameBuilder.h"
|
#include "Viewport/SceneViewportTransformGizmoFrameBuilder.h"
|
||||||
#include "ViewportPanelContent.h"
|
#include "ViewportPanelContent.h"
|
||||||
#include "Platform/Win32Utf8.h"
|
#include "Platform/Win32Utf8.h"
|
||||||
@@ -139,6 +138,17 @@ SceneViewportInteractionCandidate BuildOrientationGizmoInteractionCandidate(
|
|||||||
return candidate;
|
return candidate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SceneViewportInteractionCandidate BuildHudOverlayInteractionCandidate(
|
||||||
|
const SceneViewportHudOverlayHitResult& hitResult) {
|
||||||
|
switch (hitResult.kind) {
|
||||||
|
case SceneViewportHudOverlayHitKind::OrientationAxis:
|
||||||
|
return BuildOrientationGizmoInteractionCandidate(hitResult.orientationAxis);
|
||||||
|
case SceneViewportHudOverlayHitKind::None:
|
||||||
|
default:
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SceneViewportInteractionCandidate BuildOverlayHandleInteractionCandidate(
|
SceneViewportInteractionCandidate BuildOverlayHandleInteractionCandidate(
|
||||||
const SceneViewportOverlayHandleHitResult& hitResult) {
|
const SceneViewportOverlayHandleHitResult& hitResult) {
|
||||||
SceneViewportInteractionCandidate candidate = {};
|
SceneViewportInteractionCandidate candidate = {};
|
||||||
@@ -549,6 +559,8 @@ void SceneViewPanel::Render() {
|
|||||||
activeGizmoKind = SceneViewportActiveGizmoKind::None;
|
activeGizmoKind = SceneViewportActiveGizmoKind::None;
|
||||||
}
|
}
|
||||||
const bool gizmoActive = activeGizmoKind != SceneViewportActiveGizmoKind::None;
|
const bool gizmoActive = activeGizmoKind != SceneViewportActiveGizmoKind::None;
|
||||||
|
const SceneViewportHudOverlayData interactionHudOverlay =
|
||||||
|
BuildSceneViewportHudOverlayData(overlay);
|
||||||
SceneViewportInteractionCandidate hoveredInteraction = {};
|
SceneViewportInteractionCandidate hoveredInteraction = {};
|
||||||
const bool canResolveViewportInteraction =
|
const bool canResolveViewportInteraction =
|
||||||
hasInteractiveViewport &&
|
hasInteractiveViewport &&
|
||||||
@@ -564,9 +576,9 @@ void SceneViewPanel::Render() {
|
|||||||
hoveredInteraction);
|
hoveredInteraction);
|
||||||
|
|
||||||
AccumulateSceneViewportInteractionCandidate(
|
AccumulateSceneViewportInteractionCandidate(
|
||||||
BuildOrientationGizmoInteractionCandidate(
|
BuildHudOverlayInteractionCandidate(
|
||||||
HitTestSceneViewportOrientationGizmo(
|
HitTestSceneViewportHudOverlay(
|
||||||
overlay,
|
interactionHudOverlay,
|
||||||
content.itemMin,
|
content.itemMin,
|
||||||
content.itemMax,
|
content.itemMax,
|
||||||
io.MousePos)),
|
io.MousePos)),
|
||||||
@@ -812,12 +824,11 @@ void SceneViewPanel::Render() {
|
|||||||
m_scaleGizmo,
|
m_scaleGizmo,
|
||||||
drawGizmoFrameState.scaleContext)));
|
drawGizmoFrameState.scaleContext)));
|
||||||
|
|
||||||
DrawSceneViewportOverlay(
|
DrawSceneViewportHudOverlay(
|
||||||
ImGui::GetWindowDrawList(),
|
ImGui::GetWindowDrawList(),
|
||||||
overlay,
|
BuildSceneViewportHudOverlayData(overlay),
|
||||||
content.itemMin,
|
content.itemMin,
|
||||||
content.itemMax,
|
content.itemMax);
|
||||||
content.availableSize);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,10 @@ set(EDITOR_TEST_SOURCES
|
|||||||
test_editor_console_sink.cpp
|
test_editor_console_sink.cpp
|
||||||
test_editor_script_assembly_builder.cpp
|
test_editor_script_assembly_builder.cpp
|
||||||
test_editor_script_assembly_builder_utils.cpp
|
test_editor_script_assembly_builder_utils.cpp
|
||||||
|
${CMAKE_BINARY_DIR}/_deps/imgui-src/imgui.cpp
|
||||||
|
${CMAKE_BINARY_DIR}/_deps/imgui-src/imgui_draw.cpp
|
||||||
|
${CMAKE_BINARY_DIR}/_deps/imgui-src/imgui_tables.cpp
|
||||||
|
${CMAKE_BINARY_DIR}/_deps/imgui-src/imgui_widgets.cpp
|
||||||
${CMAKE_SOURCE_DIR}/editor/src/Core/EditorConsoleSink.cpp
|
${CMAKE_SOURCE_DIR}/editor/src/Core/EditorConsoleSink.cpp
|
||||||
${CMAKE_SOURCE_DIR}/editor/src/Scripting/EditorScriptAssemblyBuilder.cpp
|
${CMAKE_SOURCE_DIR}/editor/src/Scripting/EditorScriptAssemblyBuilder.cpp
|
||||||
${CMAKE_SOURCE_DIR}/editor/src/Core/UndoManager.cpp
|
${CMAKE_SOURCE_DIR}/editor/src/Core/UndoManager.cpp
|
||||||
@@ -33,6 +37,8 @@ set(EDITOR_TEST_SOURCES
|
|||||||
${CMAKE_SOURCE_DIR}/editor/src/Viewport/SceneViewportMoveGizmo.cpp
|
${CMAKE_SOURCE_DIR}/editor/src/Viewport/SceneViewportMoveGizmo.cpp
|
||||||
${CMAKE_SOURCE_DIR}/editor/src/Viewport/SceneViewportRotateGizmo.cpp
|
${CMAKE_SOURCE_DIR}/editor/src/Viewport/SceneViewportRotateGizmo.cpp
|
||||||
${CMAKE_SOURCE_DIR}/editor/src/Viewport/SceneViewportScaleGizmo.cpp
|
${CMAKE_SOURCE_DIR}/editor/src/Viewport/SceneViewportScaleGizmo.cpp
|
||||||
|
${CMAKE_SOURCE_DIR}/editor/src/Viewport/SceneViewportHudOverlay.cpp
|
||||||
|
${CMAKE_SOURCE_DIR}/editor/src/Viewport/SceneViewportOrientationGizmo.cpp
|
||||||
${CMAKE_SOURCE_DIR}/editor/src/Viewport/SceneViewportOverlayBuilder.cpp
|
${CMAKE_SOURCE_DIR}/editor/src/Viewport/SceneViewportOverlayBuilder.cpp
|
||||||
${CMAKE_SOURCE_DIR}/editor/src/Viewport/SceneViewportOverlayProviders.cpp
|
${CMAKE_SOURCE_DIR}/editor/src/Viewport/SceneViewportOverlayProviders.cpp
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
#include "Viewport/SceneViewportCameraController.h"
|
#include "Viewport/SceneViewportCameraController.h"
|
||||||
|
#include "Viewport/SceneViewportHudOverlay.h"
|
||||||
#include "Viewport/SceneViewportMath.h"
|
#include "Viewport/SceneViewportMath.h"
|
||||||
|
|
||||||
#include <XCEngine/Components/GameObject.h>
|
#include <XCEngine/Components/GameObject.h>
|
||||||
@@ -64,8 +65,12 @@ XCEngine::Rendering::Passes::InfiniteGridPassData ToInfiniteGridPassData(
|
|||||||
|
|
||||||
using XCEngine::Editor::BuildSceneViewportAxisDragPlaneNormal;
|
using XCEngine::Editor::BuildSceneViewportAxisDragPlaneNormal;
|
||||||
using XCEngine::Editor::SceneViewportCameraController;
|
using XCEngine::Editor::SceneViewportCameraController;
|
||||||
|
using XCEngine::Editor::SceneViewportHudOverlayHitKind;
|
||||||
|
using XCEngine::Editor::SceneViewportHudOverlayHitResult;
|
||||||
using XCEngine::Editor::BuildSceneViewportProjectionMatrix;
|
using XCEngine::Editor::BuildSceneViewportProjectionMatrix;
|
||||||
|
using XCEngine::Editor::BuildSceneViewportHudOverlayData;
|
||||||
using XCEngine::Editor::BuildSceneViewportViewMatrix;
|
using XCEngine::Editor::BuildSceneViewportViewMatrix;
|
||||||
|
using XCEngine::Editor::HitTestSceneViewportHudOverlay;
|
||||||
using XCEngine::Editor::ProjectSceneViewportWorldPoint;
|
using XCEngine::Editor::ProjectSceneViewportWorldPoint;
|
||||||
using XCEngine::Editor::SceneViewportOverlayData;
|
using XCEngine::Editor::SceneViewportOverlayData;
|
||||||
using XCEngine::Components::GameObject;
|
using XCEngine::Components::GameObject;
|
||||||
@@ -267,3 +272,38 @@ TEST(SceneViewportOverlayRenderer_Test, BuildSceneViewportAxisDragPlaneNormalFal
|
|||||||
EXPECT_NEAR(Vector3::Dot(planeNormal, Vector3::Right()), 0.0f, 1e-4f);
|
EXPECT_NEAR(Vector3::Dot(planeNormal, Vector3::Right()), 0.0f, 1e-4f);
|
||||||
EXPECT_GT(planeNormal.SqrMagnitude(), 0.5f);
|
EXPECT_GT(planeNormal.SqrMagnitude(), 0.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(SceneViewportOverlayRenderer_Test, BuildSceneViewportHudOverlayDataTracksVisibilityIntent) {
|
||||||
|
SceneViewportOverlayData overlay = {};
|
||||||
|
overlay.valid = true;
|
||||||
|
|
||||||
|
const auto visibleHud = BuildSceneViewportHudOverlayData(overlay);
|
||||||
|
const auto hiddenHud = BuildSceneViewportHudOverlayData(overlay, false);
|
||||||
|
|
||||||
|
EXPECT_TRUE(visibleHud.HasVisibleElements());
|
||||||
|
EXPECT_FALSE(hiddenHud.HasVisibleElements());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SceneViewportOverlayRenderer_Test, HitTestSceneViewportHudOverlaySkipsInvalidOrHiddenOverlay) {
|
||||||
|
const SceneViewportHudOverlayHitResult invalidHit =
|
||||||
|
HitTestSceneViewportHudOverlay({}, ImVec2(0.0f, 0.0f), ImVec2(200.0f, 200.0f), ImVec2(100.0f, 100.0f));
|
||||||
|
EXPECT_EQ(invalidHit.kind, SceneViewportHudOverlayHitKind::None);
|
||||||
|
|
||||||
|
SceneViewportOverlayData overlay = {};
|
||||||
|
overlay.valid = true;
|
||||||
|
overlay.cameraPosition = Vector3(0.0f, 0.0f, -5.0f);
|
||||||
|
overlay.cameraForward = Vector3::Forward();
|
||||||
|
overlay.cameraRight = Vector3::Right();
|
||||||
|
overlay.cameraUp = Vector3::Up();
|
||||||
|
overlay.verticalFovDegrees = 60.0f;
|
||||||
|
overlay.nearClipPlane = 0.03f;
|
||||||
|
overlay.farClipPlane = 2000.0f;
|
||||||
|
|
||||||
|
const SceneViewportHudOverlayHitResult hiddenHit =
|
||||||
|
HitTestSceneViewportHudOverlay(
|
||||||
|
BuildSceneViewportHudOverlayData(overlay, false),
|
||||||
|
ImVec2(0.0f, 0.0f),
|
||||||
|
ImVec2(200.0f, 200.0f),
|
||||||
|
ImVec2(100.0f, 100.0f));
|
||||||
|
EXPECT_EQ(hiddenHit.kind, SceneViewportHudOverlayHitKind::None);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user