예제 #1
0
        // Credits to https://github.com/jrossignol/WaypointManager/blob/master/source/WaypointManager/CustomWaypointGUI.cs
        // for this code
        public static bool GetBodyRayIntersect(CelestialBody targetBody, bool map, out double latitude, out double longitude, out double altitude)
        {
            latitude  = 0;
            longitude = 0;
            altitude  = 0;
            if (targetBody.pqsController == null)
            {
                return(false);
            }

            Ray mouseRay = map ? PlanetariumCamera.Camera.ScreenPointToRay(Input.mousePosition) : FlightCamera.fetch.mainCamera.ScreenPointToRay(Input.mousePosition);

            if (map) // use scaled space
            {
                mouseRay.origin = ScaledSpace.ScaledToLocalSpace(mouseRay.origin);
            }
            var    bodyToOrigin = mouseRay.origin - targetBody.position;
            double curRadius    = targetBody.pqsController.radiusMax;
            double lastRadius   = 0;
            int    loops        = 0;

            while (loops < 10)
            {
                Vector3d relSurfacePosition;
                if (PQS.LineSphereIntersection(bodyToOrigin, mouseRay.direction, curRadius, out relSurfacePosition))
                {
                    var    surfacePoint = targetBody.position + relSurfacePosition;
                    double alt          = targetBody.pqsController.GetSurfaceHeight(
                        QuaternionD.AngleAxis(targetBody.GetLongitude(surfacePoint), Vector3d.down) * QuaternionD.AngleAxis(targetBody.GetLatitude(surfacePoint), Vector3d.forward) * Vector3d.right);
                    double error = Math.Abs(curRadius - alt);
                    if (error < (targetBody.pqsController.radiusMax - targetBody.pqsController.radiusMin) / 500)
                    {
                        latitude  = targetBody.GetLatitude(surfacePoint);
                        longitude = targetBody.GetLongitude(surfacePoint);
                        altitude  = targetBody.TerrainAltitude(latitude, longitude);
                        return(true);
                    }
                    else
                    {
                        lastRadius = curRadius;
                        curRadius  = 0.5 * alt + 0.5 * curRadius;
                        loops++;
                    }
                }
                else
                {
                    if (loops == 0)
                    {
                        break;
                    }
                    // Went too low, needs to try higher
                    else
                    {
                        curRadius = (lastRadius * 9 + curRadius) / 10;
                        loops++;
                    }
                }
            }
            return(true);
        }
예제 #2
0
        }         // So many ifs.....

        // Cinically stolen from Waypoint Manager source code :D
        private void PlaceTargetAtCursor()
        {
            CelestialBody targetBody = this.vessel.mainBody;

            if (targetBody.pqsController == null)
            {
                return;
            }

            Ray mouseRay = PlanetariumCamera.Camera.ScreenPointToRay(Input.mousePosition);

            mouseRay.origin = ScaledSpace.ScaledToLocalSpace(mouseRay.origin);
            var    bodyToOrigin = mouseRay.origin - targetBody.position;
            double curRadius    = targetBody.pqsController.radiusMax;
            double lastRadius   = 0;
            int    loops        = 0;

            while (loops < 50)
            {
                Vector3d relSurfacePosition;
                if (PQS.LineSphereIntersection(bodyToOrigin, mouseRay.direction, curRadius, out relSurfacePosition))
                {
                    var    surfacePoint = targetBody.position + relSurfacePosition;
                    double alt          = targetBody.pqsController.GetSurfaceHeight(
                        QuaternionD.AngleAxis(targetBody.GetLongitude(surfacePoint), Vector3d.down) * QuaternionD.AngleAxis(targetBody.GetLatitude(surfacePoint), Vector3d.forward) * Vector3d.right);
                    double error = Math.Abs(curRadius - alt);
                    if (error < (targetBody.pqsController.radiusMax - targetBody.pqsController.radiusMin) / 100)
                    {
                        targetLatitude  = (targetBody.GetLatitude(surfacePoint) + 360) % 360;
                        targetLongitude = (targetBody.GetLongitude(surfacePoint) + 360) % 360;

/*						this.distanceToTarget = GeoUtils.GetDistance(
 *                                                      this.vessel.latitude, this.vessel.longitude, this.targetLatitude, this.targetLongitude, this.vessel.mainBody.Radius
 *                                              );
 *                                              this.distanceTravelled = 0;*/
                        return;
                    }
                    else
                    {
                        lastRadius = curRadius;
                        curRadius  = alt;
                        loops++;
                    }
                }
                else
                {
                    if (loops == 0)
                    {
                        break;
                    }
                    // Went too low, needs to try higher
                    else
                    {
                        curRadius = (lastRadius * 9 + curRadius) / 10;
                        loops++;
                    }
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Place target at cursor in the map mode. Borrowed Waypoint Manager and changed.
        /// Returns latitude and longitude of a target or double.MinValue, if target is not valid
        /// </summary>
        /// <param name="targetBody"></param>
        /// <returns>[latitude, longitude]</returns>
        internal static double[] PlaceTargetAtCursor(CelestialBody targetBody)
        {
            if (targetBody.pqsController == null)
            {
                return new double[2] {
                           double.MinValue, double.MinValue
                }
            }
            ;

            Ray mouseRay = PlanetariumCamera.Camera.ScreenPointToRay(Input.mousePosition);

            mouseRay.origin = ScaledSpace.ScaledToLocalSpace(mouseRay.origin);
            var    bodyToOrigin = mouseRay.origin - targetBody.position;
            double curRadius    = targetBody.pqsController.radiusMax;
            double lastRadius   = 0;
            int    loops        = 0;

            while (loops < 50)
            {
                Vector3d relSurfacePosition;

                if (PQS.LineSphereIntersection(bodyToOrigin, mouseRay.direction, curRadius, out relSurfacePosition))
                {
                    var    surfacePoint = targetBody.position + relSurfacePosition;
                    double alt          = targetBody.pqsController.GetSurfaceHeight(QuaternionD.AngleAxis(targetBody.GetLongitude(surfacePoint), Vector3d.down) * QuaternionD.AngleAxis(targetBody.GetLatitude(surfacePoint), Vector3d.forward) * Vector3d.right);
                    double error        = Math.Abs(curRadius - alt);
                    if (error < (targetBody.pqsController.radiusMax - targetBody.pqsController.radiusMin) / 100)
                    {
                        return(new double[2] {
                            (targetBody.GetLatitude(surfacePoint) + 360) % 360,
                            (targetBody.GetLongitude(surfacePoint) + 360) % 360
                        });
                    }
                    else
                    {
                        lastRadius = curRadius;
                        curRadius  = alt;
                        loops++;
                    }
                }
                else
                {
                    if (loops == 0)
                    {
                        break;
                    }
                    else // Went too low, needs to try higher
                    {
                        curRadius = (lastRadius * 9 + curRadius) / 10;
                        loops++;
                    }
                }
            }
            return(new double[2] {
                double.MinValue, double.MinValue
            });
        }
예제 #4
0
        private static void PlaceWaypointAtCursor()
        {
            if (targetBody.pqsController == null)
            {
                return;
            }

            Ray mouseRay = PlanetariumCamera.Camera.ScreenPointToRay(Input.mousePosition);

            mouseRay.origin = ScaledSpace.ScaledToLocalSpace(mouseRay.origin);
            var    bodyToOrigin = mouseRay.origin - targetBody.position;
            double curRadius    = targetBody.pqsController.radiusMax;
            double lastRadius   = 0;
            int    loops        = 0;

            while (loops < 50)
            {
                Vector3d relSurfacePosition;
                if (PQS.LineSphereIntersection(bodyToOrigin, mouseRay.direction, curRadius, out relSurfacePosition))
                {
                    var    surfacePoint = targetBody.position + relSurfacePosition;
                    double alt          = targetBody.pqsController.GetSurfaceHeight(
                        QuaternionD.AngleAxis(targetBody.GetLongitude(surfacePoint), Vector3d.down) * QuaternionD.AngleAxis(targetBody.GetLatitude(surfacePoint), Vector3d.forward) * Vector3d.right);
                    double error = Math.Abs(curRadius - alt);
                    if (error < (targetBody.pqsController.radiusMax - targetBody.pqsController.radiusMin) / 100)
                    {
                        latitude  = targetBody.GetLatitude(surfacePoint).ToString();
                        longitude = targetBody.GetLongitude(surfacePoint).ToString();
                        return;
                    }
                    else
                    {
                        lastRadius = curRadius;
                        curRadius  = alt;
                        loops++;
                    }
                }
                else
                {
                    if (loops == 0)
                    {
                        break;
                    }
                    // Went too low, needs to try higher
                    else
                    {
                        curRadius = (lastRadius * 9 + curRadius) / 10;
                        loops++;
                    }
                }
            }
        }
예제 #5
0
        static Coordinates Search(CelestialBody body, Ray mouseRay)
        {
            if (body == null || body.pqsController == null)
            {
                return(null);
            }
            Vector3d relSurfacePosition;
            Vector3d relOrigin  = mouseRay.origin - body.position;
            double   curRadius  = body.pqsController.radiusMax;
            double   lastRadius = 0;
            double   error      = 0;
            int      loops      = 0;
            float    st         = Time.time;

            while (loops < 50)
            {
                if (PQS.LineSphereIntersection(relOrigin, mouseRay.direction, curRadius, out relSurfacePosition))
                {
                    var alt = body.pqsController.GetSurfaceHeight(relSurfacePosition);
                    if (body.ocean && alt < body.Radius)
                    {
                        alt = body.Radius;
                    }
                    error = Math.Abs(curRadius - alt);
                    if (error < (body.pqsController.radiusMax - body.pqsController.radiusMin) / 100)
                    {
                        return(Coordinates.SurfacePoint(body.position + relSurfacePosition, body));
                    }
                    else
                    {
                        lastRadius = curRadius;
                        curRadius  = alt;
                        loops++;
                    }
                }
                else
                {
                    if (loops == 0)
                    {
                        break;
                    }
                    else
                    {                     // Went too low, needs to try higher
                        curRadius = (lastRadius * 9 + curRadius) / 10;
                        loops++;
                    }
                }
            }
            return(null);
        }
예제 #6
0
        public static Coordinates GetMouseCoordinates(CelestialBody body)
        {
            Ray mouseRay = PlanetariumCamera.Camera.ScreenPointToRay(Input.mousePosition);

            mouseRay.origin = ScaledSpace.ScaledToLocalSpace(mouseRay.origin);
            Vector3d relOrigin = mouseRay.origin - body.position;
            Vector3d relSurfacePosition;
            double   curRadius  = body.pqsController.radiusMax;
            double   lastRadius = 0;
            double   error      = 0;
            int      loops      = 0;
            float    st         = Time.time;

            while (loops < 50)
            {
                if (PQS.LineSphereIntersection(relOrigin, mouseRay.direction, curRadius, out relSurfacePosition))
                {
                    Vector3d surfacePoint = body.position + relSurfacePosition;
                    double   alt          = body.pqsController.GetSurfaceHeight(QuaternionD.AngleAxis(body.GetLongitude(surfacePoint), Vector3d.down) * QuaternionD.AngleAxis(body.GetLatitude(surfacePoint), Vector3d.forward) * Vector3d.right);
                    error = Math.Abs(curRadius - alt);
                    if (error < (body.pqsController.radiusMax - body.pqsController.radiusMin) / 100)
                    {
                        return(new Coordinates(body.GetLatitude(surfacePoint), MuUtils.ClampDegrees180(body.GetLongitude(surfacePoint))));
                    }
                    else
                    {
                        lastRadius = curRadius;
                        curRadius  = alt;
                        loops++;
                    }
                }
                else
                {
                    if (loops == 0)
                    {
                        break;
                    }
                    else
                    { // Went too low, needs to try higher
                        curRadius = (lastRadius * 9 + curRadius) / 10;
                        loops++;
                    }
                }
            }

            return(null);
        }
예제 #7
0
        public static Coordinates GetMouseCoordinates(CelestialBody body)
        {
            Ray mouseRay = PlanetariumCamera.Camera.ScreenPointToRay(Input.mousePosition);

            mouseRay.origin = ScaledSpace.ScaledToLocalSpace(mouseRay.origin);
            Vector3d relOrigin = mouseRay.origin - body.position;
            Vector3d relSurfacePosition;

            if (PQS.LineSphereIntersection(relOrigin, mouseRay.direction, body.Radius, out relSurfacePosition))
            {
                Vector3d surfacePoint = body.position + relSurfacePosition;
                return(new Coordinates(body.GetLatitude(surfacePoint), MuUtils.ClampDegrees180(body.GetLongitude(surfacePoint))));
            }
            else
            {
                return(null);
            }
        }
        public override void OnUpdate()
        {
            if (picking_waypoint)
            {
                if (!HighLogic.LoadedSceneIsFlight || !MapView.MapIsEnabled)
                {
                    // we left map without picking
                    MessageManager.post_quick_message("Cancelled");
                    picking_waypoint = false;
                    AtmosphereAutopilot.Instance.mainMenuGUIUpdate();
                    return;
                }
                // Thanks MechJeb!
                if (Input.GetMouseButtonDown(0) && !window.Contains(Input.mousePosition))
                {
                    Ray mouseRay = PlanetariumCamera.Camera.ScreenPointToRay(Input.mousePosition);
                    mouseRay.origin = ScaledSpace.ScaledToLocalSpace(mouseRay.origin);
                    Vector3d relOrigin = mouseRay.origin - vessel.mainBody.position;
                    Vector3d relSurfacePosition;
                    double   curRadius = vessel.mainBody.pqsController.radiusMax;
                    if (PQS.LineSphereIntersection(relOrigin, mouseRay.direction, curRadius, out relSurfacePosition))
                    {
                        Vector3d surfacePoint = vessel.mainBody.position + relSurfacePosition;
                        current_waypt.longitude = vessel.mainBody.GetLongitude(surfacePoint);
                        current_waypt.latitude  = vessel.mainBody.GetLatitude(surfacePoint);
                        picking_waypoint        = false;

                        desired_latitude.Value  = (float)current_waypt.latitude;
                        desired_longitude.Value = (float)current_waypt.longitude;

                        dist_to_dest = Vector3d.Distance(surfacePoint, vessel.ReferenceTransform.position);
                        AtmosphereAutopilot.Instance.mainMenuGUIUpdate();
                        WaypointMode = true;
                        MessageManager.post_quick_message("Picked");
                    }
                    else
                    {
                        MessageManager.post_quick_message("Missed");
                    }
                }
            }
            else
            {
                if (Input.GetKeyDown(switch_key_mode))
                {
                    use_keys = !use_keys;
                    MessageManager.post_status_message(use_keys ? "CF key input mode enabled" : "CF key input mode disabled");
                }

                if (Input.GetKeyDown(vertical_control_key))
                {
                    vertical_control = !vertical_control;
                    MessageManager.post_status_message(use_keys ? "Vertical motion control enabled" : "Vertical motion control disabled");
                }

                if (Input.GetKeyDown(toggle_vertical_setpoint_type_key))
                {
                    AltitudeMode = !AltitudeMode;
                    MessageManager.post_status_message(AltitudeMode ? "Altitude control" : "Vertical speed control");
                }

                // input shenanigans
                if (use_keys && !FlightDriver.Pause && InputLockManager.IsUnlocked(ControlTypes.PITCH) &&
                    InputLockManager.IsUnlocked(ControlTypes.YAW))
                {
                    bool  pitch_key_pressed = false;
                    float pitch_change_sign = 0.0f;
                    // Pitch
                    if (GameSettings.PITCH_UP.GetKey() && !GameSettings.MODIFIER_KEY.GetKey())
                    {
                        pitch_change_sign = 1.0f;
                        pitch_key_pressed = true;
                    }
                    else if (GameSettings.PITCH_DOWN.GetKey() && !GameSettings.MODIFIER_KEY.GetKey())
                    {
                        pitch_change_sign = -1.0f;
                        pitch_key_pressed = true;
                    }

                    if (pitch_key_pressed)
                    {
                        if (height_mode == HeightMode.Altitude)
                        {
                            float setpoint     = desired_altitude;
                            float new_setpoint = setpoint + pitch_change_sign * hotkey_altitude_sens * Time.deltaTime * setpoint;
                            desired_altitude.Value = new_setpoint;
                        }
                        else
                        {
                            float setpoint      = desired_vertspeed;
                            float magnetic_mult = Mathf.Abs(desired_vertspeed) < 10.0f ? 0.3f : 1.0f;
                            float new_setpoint  = setpoint + pitch_change_sign * hotkey_vertspeed_sens * Time.deltaTime * magnetic_mult;
                            desired_vertspeed.Value = new_setpoint;
                        }
                        need_to_show_altitude   = true;
                        altitude_change_counter = 0.0f;
                        AtmosphereAutopilot.Instance.mainMenuGUIUpdate();
                    }

                    // Yaw (Course)
                    bool  yaw_key_pressed = false;
                    float yaw_change_sign = 0.0f;
                    if (GameSettings.YAW_RIGHT.GetKey() && !GameSettings.MODIFIER_KEY.GetKey())
                    {
                        yaw_key_pressed = true;
                        yaw_change_sign = 1.0f;
                    }
                    else if (GameSettings.YAW_LEFT.GetKey() && !GameSettings.MODIFIER_KEY.GetKey())
                    {
                        yaw_key_pressed = true;
                        yaw_change_sign = -1.0f;
                    }

                    if (yaw_key_pressed)
                    {
                        float setpoint     = desired_course;
                        float new_setpoint = setpoint + yaw_change_sign * hotkey_course_sens * Time.deltaTime;
                        if (new_setpoint > 360.0f)
                        {
                            new_setpoint -= 360.0f;
                        }
                        if (new_setpoint < 0.0f)
                        {
                            new_setpoint = 360.0f + new_setpoint;
                        }
                        desired_course.Value  = new_setpoint;
                        need_to_show_course   = true;
                        course_change_counter = 0.0f;
                    }

                    if (need_to_show_course)
                    {
                        course_change_counter += Time.deltaTime;
                    }
                    if (course_change_counter > 1.0f)
                    {
                        course_change_counter = 0;
                        need_to_show_course   = false;
                    }

                    if (need_to_show_altitude)
                    {
                        altitude_change_counter += Time.deltaTime;
                        if (height_mode == HeightMode.VerticalSpeed && altitude_change_counter > 0.2f)
                        {
                            if (Mathf.Abs(desired_vertspeed) < hotkey_vertspeed_snap)
                            {
                                desired_vertspeed.Value = 0.0f;
                            }
                        }
                    }
                    if (altitude_change_counter > 1.0f)
                    {
                        altitude_change_counter = 0;
                        need_to_show_altitude   = false;
                    }
                }
                else
                {
                    need_to_show_altitude   = false;
                    altitude_change_counter = 0;

                    need_to_show_course   = false;
                    course_change_counter = 0;
                }
            }
        }
예제 #9
0
        public void OnGUI()
        {
            if (Event.current.type == EventType.MouseDown)
            {
                PluginLogger.logDebug("OnGUI");

                PluginLogger.logDebug("removing old");
                removeGameObject("MouseRayLine");

                Camera  camera = Camera.main;
                Ray     mouseRay;
                Vector3 worldStart;
                Vector3 worldDirection;
                if (MapView.MapIsEnabled)
                {
                    body   = Planetarium.fetch.CurrentMainBody;
                    camera = PlanetariumCamera.Camera;

                    mouseRay        = camera.ScreenPointToRay(Input.mousePosition);
                    mouseRay.origin = mouseRay.origin;

                    PluginLogger.logDebug(mouseRay);

                    Vector3 toDrawStart = mouseRay.origin;
                    Vector3 toDrawEnd   = mouseRay.origin + mouseRay.direction * (float)body.Radius;

                    PluginLogger.logDebug(toDrawStart + "->" + toDrawEnd);
                    PluginLogger.logDebug(ScaledSpace.LocalToScaledSpace(body.position));


                    GameObject lineObj = addGameObject(new GameObject("MouseRayLine"));
                    lineObj.layer = 9;
                    LineRenderer line = lineObj.AddComponent <LineRenderer>();
                    line.useWorldSpace              = true;
                    line.transform.localPosition    = Vector3.zero;
                    line.transform.localEulerAngles = Vector3.zero;

                    // Make it render a red to yellow triangle, 1 meter wide and 2 meters long
                    line.material = new Material(Shader.Find("Particles/Additive"));
                    line.SetColors(Color.green, Color.red);
                    line.SetWidth((float)10 / 1000 * PlanetariumCamera.fetch.Distance, (float)10 / 1000 * PlanetariumCamera.fetch.Distance);

                    line.SetVertexCount(2);
                    //line.SetPosition(0, ScaledSpace.LocalToScaledSpace(body.position + new Vector3(1, 0, 0) * (float)body.Radius *5));
                    //line.SetPosition(1, ScaledSpace.LocalToScaledSpace(body.position));

                    //line.SetPosition(0, toDrawStart);
                    line.SetPosition(0, toDrawStart + new Vector3(0, -1, 0));
                    line.SetPosition(1, toDrawEnd);

                    worldStart     = ScaledSpace.ScaledToLocalSpace(mouseRay.origin);
                    worldDirection = mouseRay.direction;
                }
                else
                {
                    //Input.mousePosition = new Vector2(Event.current.mousePosition.x, Screen.height - Event.current.mousePosition.y)
                    mouseRay = camera.ScreenPointToRay(Input.mousePosition);

                    PluginLogger.logDebug(Input.mousePosition);
                    PluginLogger.logDebug(camera.ScreenToWorldPoint(Event.current.mousePosition));
                    PluginLogger.logDebug(mouseRay);

                    PluginLogger.logDebug(camera.transform.position);



                    //mouseRay.origin = ScaledSpace.ScaledToLocalSpace(mouseRay.origin);

                    GameObject   lineObj = addGameObject(new GameObject("MouseRayLine"));
                    LineRenderer line    = lineObj.AddComponent <LineRenderer>();
                    line.useWorldSpace              = true;
                    line.transform.localPosition    = Vector3.zero;
                    line.transform.localEulerAngles = Vector3.zero;

                    // Make it render a red to yellow triangle, 1 meter wide and 2 meters long
                    line.material = new Material(Shader.Find("Particles/Additive"));
                    line.SetColors(Color.red, Color.red);
                    line.SetWidth(1, 1);

                    line.SetVertexCount(2);
                    line.SetPosition(0, mouseRay.origin);
                    line.SetPosition(1, mouseRay.origin + mouseRay.direction * 1000);

                    worldStart     = mouseRay.origin;
                    worldDirection = mouseRay.direction;
                }



                Vector3d intersectionPoint = new Vector3d();
                Vector3d bodyToMouse       = worldStart - body.position;
                float    radius            = (float)body.pqsController.radiusMax;
                //if (body.pqsController.RayIntersection(worldStart, worldDirection, out intersectionPoint)) {
                if (PQS.LineSphereIntersection(bodyToMouse, mouseRay.direction, radius, out intersectionPoint))
                {
                    PluginLogger.logDebug("intersect!");
                }
                else
                {
                    PluginLogger.logDebug("No hit!");
                }

                //mouseRay.origin = ScaledSpace.ScaledToLocalSpace(mouseRay.origin);
            }
        }