Jump to content

Finding the orbit under the mouse?


Recommended Posts

I am trying to display contextual information about an orbit just by hovering the mouse above it. Obviously, clicking on an orbit allows you to place a maneuver node at that position, so there must be a way to translate mouse position into orbit + obit UT. The question is how? The OrbitRenderer seems to have some info about that. It has a GetMouseOverNode function and a mouseOver member, but it is not clear what they mean.

Does anyone have any insight on this?

Thanks,
Zentarul

Link to comment
Share on other sites

[KSPAddon(KSPAddon.Startup.Flight, false)]
public class OrbitMouseOver : MonoBehaviour
{
    private bool _mouseOver = false;
    private PatchedConics.PatchCastHit _mousedOverPatch;


    private Rect _popup = new Rect(0f, 0f, 120f, 60f);
    private Texture2D _cross;
    private Rect _crossRect;

    private void Awake()
    {
        _popup.center = new Vector2(Screen.width * 0.5f - _popup.width * 0.5f,
            Screen.height * 0.5f - _popup.height * 0.5f);

        _cross = new Texture2D(32, 32, TextureFormat.ARGB32, false);
        _crossRect = new Rect(0, 0, _cross.width, _cross.height);

        var pixels = Enumerable.Repeat(Color.clear, _cross.width * _cross.height).ToArray();

        for (int i = 0; i < _cross.width; ++i)
            for (int j = 0; j < _cross.height; ++j)
            {
                if (i == j || j == (_cross.width - i))
                    pixels[j * _cross.height + i] = Color.red;
            }

        _cross.SetPixels(pixels);
        _cross.Apply();
    }


    private void Update()
    {
        _mouseOver = MouseOverOrbit(out _mousedOverPatch);

        if (!_mouseOver) return;

        var updatedLocation = _mousedOverPatch.GetUpdatedScreenPoint();

        _popup.center = _crossRect.center = new Vector2(updatedLocation.x, Screen.height - updatedLocation.y);
    }


    private void OnGUI()
    {
        if (!_mouseOver) return;

        GUI.skin = HighLogic.Skin;


        GUILayout.BeginArea(GUIUtility.ScreenToGUIRect(_popup));
        GUILayout.Label("UT: " + KSPUtil.PrintTime((int)(Planetarium.GetUniversalTime() - _mousedOverPatch.UTatTA), 5, true));

        GUILayout.EndArea();

        if (Event.current.type == EventType.Repaint)
            Graphics.DrawTexture(_crossRect, _cross);
    }




    private bool MouseOverOrbit(out PatchedConics.PatchCastHit hit)
    {
        hit = default(PatchedConics.PatchCastHit);

        if (FlightGlobals.ActiveVessel == null) return false;

        var patchRenderer = FlightGlobals.ActiveVessel.patchedConicRenderer;

        if (patchRenderer == null) return false;

        var patches = patchRenderer.solver.maneuverNodes.Any()
            ? patchRenderer.flightPlanRenders
            : patchRenderer.patchRenders;

        return PatchedConics.ScreenCast(Input.mousePosition, patches, out hit);
    }
}

Here's a rough proof of concept. It works on the active vessel's orbit. If you want to include the other orbits (CelestialBodies at least, anyway), you'll probably want to use OrbitRenderer.OrbitCast. I didn't go far on that path other than yes/no type mouseover debug spam since it became apparent that the maneuver node placement was doing something different and the active vessel's orbit wasn't included by that method

Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...