#include #include "Viewport/SceneViewportInteractionResolver.h" using XCEngine::Editor::ResolveSceneViewportInteraction; using XCEngine::Editor::SceneViewportGizmoAxis; using XCEngine::Editor::SceneViewportHudOverlayHitKind; using XCEngine::Editor::SceneViewportHudOverlayHitResult; using XCEngine::Editor::SceneViewportInteractionKind; using XCEngine::Editor::SceneViewportInteractionResolveRequest; using XCEngine::Editor::SceneViewportOrientationAxis; using XCEngine::Editor::SceneViewportOverlayFrameData; using XCEngine::Editor::SceneViewportOverlayHandleHitResult; using XCEngine::Editor::SceneViewportOverlayHandleKind; using XCEngine::Editor::SceneViewportOverlayHandleRecord; using XCEngine::Editor::SceneViewportOverlayHandleShape; using XCEngine::Math::Vector2; TEST(SceneViewportInteractionResolverTest, ReturnsNoHitWhenBothSourcesAreEmpty) { const auto interaction = ResolveSceneViewportInteraction( SceneViewportOverlayHandleHitResult{}, SceneViewportHudOverlayHitResult{}); EXPECT_FALSE(interaction.HasHit()); EXPECT_EQ(interaction.kind, SceneViewportInteractionKind::None); } TEST(SceneViewportInteractionResolverTest, PrefersTransformHandleOverHudOrientationByPriority) { SceneViewportOverlayHandleHitResult overlayHandleHit = {}; overlayHandleHit.kind = SceneViewportOverlayHandleKind::MoveAxis; overlayHandleHit.handleId = static_cast(SceneViewportGizmoAxis::X); overlayHandleHit.priority = 322; overlayHandleHit.distanceSq = 4.0f; overlayHandleHit.depth = 3.0f; SceneViewportHudOverlayHitResult hudHit = {}; hudHit.kind = SceneViewportHudOverlayHitKind::OrientationAxis; hudHit.orientationAxis = SceneViewportOrientationAxis::PositiveX; const auto interaction = ResolveSceneViewportInteraction(overlayHandleHit, hudHit); ASSERT_TRUE(interaction.HasHit()); EXPECT_EQ(interaction.kind, SceneViewportInteractionKind::MoveGizmo); EXPECT_EQ(interaction.moveAxis, SceneViewportGizmoAxis::X); EXPECT_EQ(interaction.orientationAxis, SceneViewportOrientationAxis::None); } TEST(SceneViewportInteractionResolverTest, PrefersHudOrientationOverSceneIconByPriority) { SceneViewportOverlayHandleHitResult overlayHandleHit = {}; overlayHandleHit.kind = SceneViewportOverlayHandleKind::SceneIcon; overlayHandleHit.entityId = 99; overlayHandleHit.priority = 100; overlayHandleHit.distanceSq = 0.0f; overlayHandleHit.depth = 0.0f; SceneViewportHudOverlayHitResult hudHit = {}; hudHit.kind = SceneViewportHudOverlayHitKind::OrientationAxis; hudHit.orientationAxis = SceneViewportOrientationAxis::PositiveY; const auto interaction = ResolveSceneViewportInteraction(overlayHandleHit, hudHit); ASSERT_TRUE(interaction.HasHit()); EXPECT_EQ(interaction.kind, SceneViewportInteractionKind::OrientationGizmo); EXPECT_EQ(interaction.orientationAxis, SceneViewportOrientationAxis::PositiveY); EXPECT_EQ(interaction.entityId, 0u); } TEST(SceneViewportInteractionResolverTest, RequestPathDelegatesToOverlayHandleHitTesting) { SceneViewportOverlayFrameData frameData = {}; frameData.overlay.valid = true; SceneViewportOverlayHandleRecord& record = frameData.handleRecords.emplace_back(); record.kind = SceneViewportOverlayHandleKind::SceneIcon; record.entityId = 77; record.shape = SceneViewportOverlayHandleShape::ScreenRect; record.priority = 100; record.screenCenter = Vector2(80.0f, 60.0f); record.screenHalfSize = Vector2(12.0f, 10.0f); SceneViewportInteractionResolveRequest request = {}; request.overlayFrameData = &frameData; request.viewportSize = Vector2(200.0f, 150.0f); request.localMousePosition = Vector2(80.0f, 60.0f); const auto interaction = ResolveSceneViewportInteraction(request); ASSERT_TRUE(interaction.HasHit()); EXPECT_EQ(interaction.kind, SceneViewportInteractionKind::SceneIcon); EXPECT_EQ(interaction.entityId, 77u); }