Code/UI/Spatial/Node.ToWorld.cs
namespace Nodebox.UI.Spatial;

public partial class Node {
    public float PanelScaleToWorld => WorldPanel.RenderScale / 20f;
    public float PanelScaleToLocal => 1f / PanelScaleToWorld;

    public Vector3? MousePosition {
        get {
            if (NodePanel?.MousePosition is not Vector2 position2d) { return null; }
            return PanelPointToWorld(position2d);
        }
    }

    public Panel GetPinPanel(Flow flow, PinIndex pinIndex) => NodePanel.GetPin(flow, pinIndex);

    public Vector3? PanelToWorldRelativeToPin(Flow flow, PinIndex pinIndex, Vector2 localPosition) {
        var panel = GetPinPanel(flow, pinIndex);
        if (!panel.IsValid()) { return null; }
        var rect = panel.Box.Rect;
        return PanelPointToWorld(rect.TopLeft + rect.Size * localPosition);
    }

    public Vector3 PanelPointToWorld(Vector2 position) {
        return WorldTransform.PointToWorld(new Vector3(
            0f,
            position.x * PanelScaleToWorld,
            -position.y * PanelScaleToWorld
        ));
    }

    public Vector3? PanelPointToWorldScaled(Vector2 position) {
        if (NodePanelRoot?.Panel?.Children?.FirstOrDefault()?.Children?.FirstOrDefault()?.Box?.Rect is not Rect rect) { return null; }
        return PanelPointToWorld(position * new Vector2(rect.Width, rect.Height));
    }
}