#pragma once #include "IViewportHostService.h" #include #include #include #include #include #include namespace XCEngine { namespace Editor { enum class SceneViewportOverlayDepthMode : uint8_t { DepthTested = 0, AlwaysOnTop }; enum class SceneViewportOverlaySpriteTextureKind : uint8_t { Camera = 0, Light = 1 }; enum class SceneViewportOverlayHandleKind : uint8_t { None = 0, SceneIcon, MoveAxis, MovePlane, RotateAxis, ScaleAxis, ScaleUniform }; enum class SceneViewportOverlayHandleShape : uint8_t { None = 0, WorldRect, ScreenSegment, ScreenRect, ScreenQuad }; struct SceneViewportOverlayLinePrimitive { Math::Vector3 startWorld = Math::Vector3::Zero(); Math::Vector3 endWorld = Math::Vector3::Zero(); Math::Color color = Math::Color::White(); float thicknessPixels = 1.0f; SceneViewportOverlayDepthMode depthMode = SceneViewportOverlayDepthMode::AlwaysOnTop; }; struct SceneViewportOverlaySpritePrimitive { Math::Vector3 worldPosition = Math::Vector3::Zero(); Math::Vector2 sizePixels = Math::Vector2::Zero(); Math::Color tintColor = Math::Color::White(); float sortDepth = 0.0f; uint64_t entityId = 0; SceneViewportOverlaySpriteTextureKind textureKind = SceneViewportOverlaySpriteTextureKind::Camera; SceneViewportOverlayDepthMode depthMode = SceneViewportOverlayDepthMode::AlwaysOnTop; }; struct SceneViewportOverlayScreenTriangleVertex { Math::Vector2 screenPosition = Math::Vector2::Zero(); Math::Color color = Math::Color::White(); }; struct SceneViewportOverlayScreenTrianglePrimitive { std::array vertices = {}; SceneViewportOverlayDepthMode depthMode = SceneViewportOverlayDepthMode::AlwaysOnTop; }; struct SceneViewportOverlayHandleRecord { SceneViewportOverlayHandleKind kind = SceneViewportOverlayHandleKind::None; uint64_t handleId = 0; uint64_t entityId = 0; SceneViewportOverlayHandleShape shape = SceneViewportOverlayHandleShape::None; int priority = 0; Math::Vector3 worldPosition = Math::Vector3::Zero(); Math::Vector2 sizePixels = Math::Vector2::Zero(); float sortDepth = 0.0f; Math::Vector2 screenStart = Math::Vector2::Zero(); Math::Vector2 screenEnd = Math::Vector2::Zero(); Math::Vector2 screenCenter = Math::Vector2::Zero(); Math::Vector2 screenHalfSize = Math::Vector2::Zero(); std::array screenQuad = {}; float hitThicknessPixels = 0.0f; }; struct SceneViewportOverlayHandleHitResult { SceneViewportOverlayHandleKind kind = SceneViewportOverlayHandleKind::None; uint64_t handleId = 0; uint64_t entityId = 0; int priority = (std::numeric_limits::min)(); float distanceSq = (std::numeric_limits::max)(); float depth = (std::numeric_limits::max)(); bool HasHit() const { return kind != SceneViewportOverlayHandleKind::None; } }; struct SceneViewportOverlayFrameData { SceneViewportOverlayData overlay = {}; std::vector worldLines = {}; std::vector worldSprites = {}; std::vector screenTriangles = {}; std::vector handleRecords = {}; bool HasOverlayPrimitives() const { return overlay.valid && (!worldLines.empty() || !worldSprites.empty() || !screenTriangles.empty()); } bool HasWorldOverlay() const { return HasOverlayPrimitives(); } }; inline void AppendSceneViewportOverlayFrameData( SceneViewportOverlayFrameData& target, const SceneViewportOverlayFrameData& source) { if (!target.overlay.valid && source.overlay.valid) { target.overlay = source.overlay; } target.worldLines.insert( target.worldLines.end(), source.worldLines.begin(), source.worldLines.end()); target.worldSprites.insert( target.worldSprites.end(), source.worldSprites.begin(), source.worldSprites.end()); target.screenTriangles.insert( target.screenTriangles.end(), source.screenTriangles.begin(), source.screenTriangles.end()); target.handleRecords.insert( target.handleRecords.end(), source.handleRecords.begin(), source.handleRecords.end()); } } // namespace Editor } // namespace XCEngine