Fix scene move gizmo axis projection

This commit is contained in:
2026-03-30 00:47:31 +08:00
parent 0ea1cb29e6
commit c8f79dfb0f
2 changed files with 175 additions and 15 deletions

View File

@@ -7,6 +7,10 @@
namespace XCEngine::Editor {
namespace {
float HandleLength(const SceneViewportMoveGizmoHandleDrawData& handle) {
return (handle.end - handle.start).Magnitude();
}
class SceneViewportMoveGizmoTest : public ::testing::Test {
protected:
void SetUp() override {
@@ -26,6 +30,19 @@ protected:
return overlay;
}
static SceneViewportOverlayData MakeDownwardTiltedOverlay() {
SceneViewportOverlayData overlay = {};
overlay.valid = true;
overlay.cameraPosition = Math::Vector3(0.0f, 10.0f, -1.0f);
overlay.cameraForward = (Math::Vector3::Zero() - overlay.cameraPosition).Normalized();
overlay.cameraRight = Math::Vector3::Cross(Math::Vector3::Up(), overlay.cameraForward).Normalized();
overlay.cameraUp = Math::Vector3::Cross(overlay.cameraForward, overlay.cameraRight).Normalized();
overlay.verticalFovDegrees = 60.0f;
overlay.nearClipPlane = 0.03f;
overlay.farClipPlane = 2000.0f;
return overlay;
}
static SceneViewportMoveGizmoContext MakeContext(
Components::GameObject* selectedObject,
const Math::Vector2& mousePosition) {
@@ -37,6 +54,18 @@ protected:
return context;
}
static SceneViewportMoveGizmoContext MakeContext(
Components::GameObject* selectedObject,
const Math::Vector2& mousePosition,
const SceneViewportOverlayData& overlay) {
SceneViewportMoveGizmoContext context = {};
context.overlay = overlay;
context.viewportSize = Math::Vector2(800.0f, 600.0f);
context.mousePosition = mousePosition;
context.selectedObject = selectedObject;
return context;
}
SceneManager& GetSceneManager() {
return dynamic_cast<SceneManager&>(m_context.GetSceneManager());
}
@@ -92,5 +121,23 @@ TEST_F(SceneViewportMoveGizmoTest, DraggingXAxisOnlyChangesWorldXAndCreatesUndoS
EXPECT_NEAR(restoredPosition.z, 0.0f, 1e-4f);
}
TEST_F(SceneViewportMoveGizmoTest, AxisNearlyFacingCameraShrinksInsteadOfKeepingFullLength) {
Components::GameObject* target = GetSceneManager().CreateEntity("Target");
ASSERT_NE(target, nullptr);
SceneViewportMoveGizmo gizmo;
gizmo.Update(MakeContext(target, Math::Vector2(400.0f, 300.0f), MakeDownwardTiltedOverlay()));
ASSERT_TRUE(gizmo.GetDrawData().visible);
const float xLength = HandleLength(gizmo.GetDrawData().handles[0]);
const float yLength = HandleLength(gizmo.GetDrawData().handles[1]);
const float zLength = HandleLength(gizmo.GetDrawData().handles[2]);
EXPECT_GT(xLength, 60.0f);
EXPECT_GT(zLength, 60.0f);
EXPECT_LT(yLength, xLength * 0.5f);
EXPECT_LT(yLength, zLength * 0.5f);
}
} // namespace
} // namespace XCEngine::Editor