Refine editor viewport and interaction workflow

This commit is contained in:
2026-03-29 15:12:38 +08:00
parent b0427b7091
commit 2651bad080
42 changed files with 3888 additions and 570 deletions

View File

@@ -0,0 +1,82 @@
#include "SceneViewportOverlayRenderer.h"
#include "SceneViewportMath.h"
namespace XCEngine {
namespace Editor {
namespace {
Math::Matrix4x4 BuildOverlayViewMatrix(const SceneViewportOverlayData& overlay) {
return BuildSceneViewportViewMatrix(overlay);
}
void DrawAxisLabel(ImDrawList* drawList, const ImVec2& position, const char* label, ImU32 color) {
if (drawList == nullptr || label == nullptr) {
return;
}
const ImVec2 labelSize = ImGui::CalcTextSize(label);
drawList->AddText(
ImVec2(position.x - labelSize.x * 0.5f, position.y - labelSize.y * 0.5f),
color,
label);
}
void DrawSceneAxisWidget(
ImDrawList* drawList,
const SceneViewportOverlayData& overlay,
const ImVec2& viewportMin,
const ImVec2& viewportMax) {
if (drawList == nullptr || !overlay.valid) {
return;
}
const Math::Matrix4x4 view = BuildOverlayViewMatrix(overlay);
const ImVec2 center(viewportMax.x - 52.0f, viewportMin.y + 52.0f);
const float radius = 25.0f;
drawList->AddCircleFilled(center, radius + 12.0f, IM_COL32(17, 19, 22, 178), 24);
drawList->AddCircle(center, radius + 12.0f, IM_COL32(255, 255, 255, 30), 24, 1.0f);
struct AxisLine {
Math::Vector3 axis;
const char* label;
ImU32 color;
};
const AxisLine axes[] = {
{ Math::Vector3::Right(), "x", IM_COL32(239, 83, 80, 255) },
{ Math::Vector3::Up(), "y", IM_COL32(102, 187, 106, 255) },
{ Math::Vector3::Forward(), "z", IM_COL32(66, 165, 245, 255) }
};
for (const AxisLine& axis : axes) {
const Math::Vector3 viewAxis = view.MultiplyVector(axis.axis);
const ImVec2 end(
center.x + viewAxis.x * radius,
center.y - viewAxis.y * radius);
drawList->AddLine(center, end, axis.color, 2.0f);
drawList->AddCircleFilled(end, 6.0f, axis.color, 16);
DrawAxisLabel(drawList, end, axis.label, IM_COL32(245, 245, 245, 255));
}
}
} // namespace
void DrawSceneViewportOverlay(
ImDrawList* drawList,
const SceneViewportOverlayData& overlay,
const ImVec2& viewportMin,
const ImVec2& viewportMax,
const ImVec2& viewportSize) {
if (drawList == nullptr || !overlay.valid || viewportSize.x <= 1.0f || viewportSize.y <= 1.0f) {
return;
}
drawList->PushClipRect(viewportMin, viewportMax, true);
DrawSceneAxisWidget(drawList, overlay, viewportMin, viewportMax);
drawList->PopClipRect();
}
} // namespace Editor
} // namespace XCEngine