Ejemplo n.º 1
0
        /// <summary>
        ///     Updates the details by recalculating if requested.
        /// </summary>
        public void Update()
        {
            ITargetable    target = null;
            global::Vessel vessel = null;

            landedSamePlanet = false;
            isLanded         = false;
            overrideANDN     = false;
            overrideANDNRev  = false;

            if (HighLogic.LoadedSceneIsFlight)
            {
                if (FlightGlobals.fetch == null ||
                    FlightGlobals.fetch.VesselTarget == null ||
                    FlightGlobals.ActiveVessel == null ||
                    FlightGlobals.ActiveVessel.targetObject == null ||
                    FlightGlobals.ActiveVessel.targetObject.GetOrbit() == null ||
                    FlightGlobals.ship_orbit == null ||
                    FlightGlobals.ship_orbit.referenceBody == null)
                {
                    ShowDetails = false;
                    return;
                }
                else
                {
                    target = FlightGlobals.ActiveVessel.targetObject;
                    vessel = FlightGlobals.ActiveVessel;
                }
                TrackingStationSource = null;
            }
            else if (HighLogic.LoadedScene == GameScenes.TRACKSTATION)
            {
                if (PlanetariumCamera.fetch.target.type == MapObject.ObjectType.CelestialBody)
                {
                    target = PlanetariumCamera.fetch.target.celestialBody;
                }
                else if (PlanetariumCamera.fetch.target.type == MapObject.ObjectType.Vessel)
                {
                    target = PlanetariumCamera.fetch.target.vessel;
                }

                if (TrackingStationSource != null)
                {
                    vessel = TrackingStationSource.GetVessel();
                }
                else
                {
                    TrackingStationSource = target;
                }
            }

            activeTarget = target;

            if (target == null)
            {
                ShowDetails = false;
                return;
            }

            ShowDetails = true;

            var actualSourceOrbit = vessel != null ? vessel.orbit : TrackingStationSource.GetOrbit();
            var actualTargetOrbit = target.GetOrbit();

            if (target is global::Vessel)
            {
                targetVessel = (global::Vessel)target;
            }
            else
            {
                targetVessel = null;
            }

            activeVessel = vessel;

            if (actualSourceOrbit == null)
            {
                //  Debug.Log("Source orbit is null!");
                TrackingStationSource = null;
                ShowDetails           = false;
                return;
            }

            if (actualTargetOrbit == null)
            {
                // Debug.Log("Target orbit is null!");
                ShowDetails = false;
                return;
            }

            isLanded = vessel != null && vessel.LandedOrSplashed;
            bool targetLanded = (target is global::Vessel && ((global::Vessel)target).LandedOrSplashed);

            landedSamePlanet = isLanded && targetLanded && actualSourceOrbit.referenceBody == actualTargetOrbit.referenceBody;

            var originOrbit = isLanded ? actualSourceOrbit.referenceBody.orbit : actualSourceOrbit;
            var targetOrbit = targetLanded ? actualTargetOrbit.referenceBody.orbit : actualTargetOrbit;

            if ((!isLanded && !targetLanded) || (actualSourceOrbit.referenceBody != actualTargetOrbit.referenceBody))
            {
                findConcentricParents(ref originOrbit, ref targetOrbit);
            }

            if (originOrbit == targetOrbit && !landedSamePlanet)
            {
                targetOrbit = actualTargetOrbit;
                originOrbit = null;
            }

            { //These are not 'rendezvous' calculations, just raw data about the target object.
                AltitudeSeaLevel    = targetOrbit.altitude;
                ApoapsisHeight      = targetOrbit.ApA;
                PeriapsisHeight     = targetOrbit.PeA;
                TimeToApoapsis      = targetOrbit.timeToAp;
                TimeToPeriapsis     = targetOrbit.timeToPe;
                SemiMajorAxis       = targetOrbit.semiMajorAxis;
                SemiMinorAxis       = targetOrbit.semiMinorAxis;
                OrbitalPeriod       = targetOrbit.period;
                RelativeInclination = targetOrbit.inclination;
            }

            { //Set everything else 0 incase some are not valid.
                TimeToAscendingNode   = 0;
                TimeToDescendingNode  = 0;
                AngleToAscendingNode  = 0;
                AngleToDescendingNode = 0;

                RelativeVelocity    = 0;
                RelativeSpeed       = 0;
                PhaseAngle          = 0;
                InterceptAngle      = 0;
                TimeToTransferAngle = 0;

                AngleToPlane[0] = 0;
                TimeToPlane[0]  = 0;
                AngleToPlane[1] = 0;
                TimeToPlane[1]  = 0;
                Distance        = 0;

                TimeTilEncounter      = double.NaN;
                SeparationAtEncounter = double.NaN;
                SpeedAtEncounter      = double.NaN;

                Orbital.ManoeuvreNode.ManoeuvreProcessor.PostBurnRelativeInclination = 0;
            }


            if (originOrbit != null)   //Actually calculating an encounter with 2 different things.

            {
                overrideANDN       = isLanded && actualSourceOrbit.referenceBody == targetOrbit.referenceBody;
                overrideANDNRev    = targetLanded && !isLanded && actualTargetOrbit.referenceBody == actualSourceOrbit.referenceBody && target.GetVessel() != null;
                bodyRotationPeriod = actualSourceOrbit.referenceBody.rotationPeriod;

                if (landedSamePlanet)   //this should only occur when landed targeting something else landed on same body.

                {
                    AltitudeSeaLevel = target.GetVessel().altitude;
                    ApoapsisHeight   = 0;
                    PeriapsisHeight  = 0;
                    TimeToApoapsis   = 0;
                    TimeToPeriapsis  = 0;
                    SemiMajorAxis    = 0;
                    SemiMinorAxis    = 0;
                    Distance         = Vector3d.Distance(target.GetVessel().GetWorldPos3D(), vessel.GetWorldPos3D());
                    OrbitalPeriod    = bodyRotationPeriod;
                }
                else if (overrideANDN)    //launching

                {
                    if (vessel != null)
                    {
                        AngleToPlane   = CalcAngleToPlane(vessel.GetOrbit().referenceBody, vessel.latitude, vessel.longitude, targetOrbit);
                        TimeToPlane[0] = (AngleToPlane[0] / 360) * vessel.GetOrbit().referenceBody.rotationPeriod;
                        TimeToPlane[1] = (AngleToPlane[1] / 360) * vessel.GetOrbit().referenceBody.rotationPeriod;
                    }

                    RelativeInclination = targetOrbit.inclination;
                    PhaseAngle          = OrbitExtensions.GetPhaseAngle(actualSourceOrbit, actualTargetOrbit); //this works for some reason.
                }
                else if (overrideANDNRev)                                                                      //landing

                {
                    global::Vessel tgt = target.GetVessel();

                    if (vessel != null)
                    {
                        AngleToPlane   = CalcAngleToPlane(vessel.GetOrbit().referenceBody, tgt.latitude, tgt.longitude, originOrbit);
                        TimeToPlane[0] = (AngleToPlane[0] / 360) * vessel.GetOrbit().referenceBody.rotationPeriod;
                        TimeToPlane[1] = (AngleToPlane[1] / 360) * vessel.GetOrbit().referenceBody.rotationPeriod;
                    }

                    RelativeInclination = originOrbit.inclination;
                    Distance            = Vector3d.Distance(target.GetVessel().GetWorldPos3D(), vessel.GetWorldPos3D());
                    AltitudeSeaLevel    = tgt.altitude;
                    PhaseAngle          = OrbitExtensions.GetPhaseAngle(actualSourceOrbit, actualTargetOrbit); //this works for some reason.
                }
                else                                                                                           //standard 2 orbits

                {
                    RelativeInclination = OrbitExtensions.GetRelativeInclination(originOrbit, targetOrbit);



                    if (FlightGlobals.ActiveVessel == null || FlightGlobals.ActiveVessel.patchedConicSolver == null ||
                        FlightGlobals.ActiveVessel.patchedConicSolver.maneuverNodes == null ||
                        FlightGlobals.ActiveVessel.patchedConicSolver.maneuverNodes.Count == 0)
                    {
                    }
                    else
                    {
                        var node = FlightGlobals.ActiveVessel.patchedConicSolver.maneuverNodes[0];
                        if (node != null && node.nextPatch != null)
                        {
                            Orbital.ManoeuvreNode.ManoeuvreProcessor.PostBurnRelativeInclination = OrbitExtensions.GetRelativeInclination(node.nextPatch, FlightGlobals.ActiveVessel.targetObject.GetOrbit());
                        }
                    }



                    RelativeSpeed    = originOrbit.GetRelativeVel().magnitude - target.GetObtVelocity().magnitude;
                    RelativeVelocity = (originOrbit.GetRelativeVel() - target.GetObtVelocity()).magnitude;

                    // FlightGlobals.ship_tgtVelocity = FlightGlobals.ship_obtVelocity - this.VesselTarget.GetObtVelocity();
                    // FlightGlobals.ship_tgtSpeed = FlightGlobals.ship_tgtVelocity.magnitude;

                    PhaseAngle     = OrbitExtensions.GetPhaseAngle(originOrbit, targetOrbit);
                    InterceptAngle = CalcInterceptAngle(targetOrbit, originOrbit);

                    double tspd = 360 / targetOrbit.period;
                    double sspd = 360 / originOrbit.period;

                    if (PhaseAngle < 0)
                    {
                        double diff = InterceptAngle - PhaseAngle;
                        if (diff < 0)
                        {
                            diff += 360;
                        }
                        if (diff > 340)
                        {
                            diff -= 360;
                        }
                        TimeToTransferAngle = sspd == tspd ? 0 : diff / (tspd - sspd);
                    }
                    else
                    {
                        double diff = PhaseAngle - InterceptAngle;
                        if (diff < 0)
                        {
                            diff += 360;
                        }
                        if (diff > 340)
                        {
                            diff -= 360;
                        }
                        TimeToTransferAngle = sspd == tspd ? 0 : diff / (sspd - tspd);
                    }


                    TimeToAscendingNode   = OrbitExtensions.GetTimeToVector(originOrbit, GetAscendingNode(targetOrbit, originOrbit));
                    TimeToDescendingNode  = OrbitExtensions.GetTimeToVector(originOrbit, GetDescendingNode(targetOrbit, originOrbit));
                    AngleToAscendingNode  = OrbitExtensions.GetAngleToVector(originOrbit, GetAscendingNode(targetOrbit, originOrbit));
                    AngleToDescendingNode = OrbitExtensions.GetAngleToVector(originOrbit, GetDescendingNode(targetOrbit, originOrbit));

                    Distance = Vector3d.Distance(targetOrbit.pos, originOrbit.pos);


                    //From OrbitTargeter
                    double tOne = 0;
                    if (target is CelestialBody)
                    {
                        Vector3d relativePositionAtUT  = originOrbit.getRelativePositionAtUT(originOrbit.closestTgtApprUT);
                        Vector3d relativePositionAtUT2 = targetOrbit.getRelativePositionAtUT(originOrbit.closestTgtApprUT);
                        double   separation            = (relativePositionAtUT - relativePositionAtUT2).magnitude;
                        tOne = originOrbit.closestTgtApprUT;
                    }
                    else
                    {
                        double num3       = 0.0;
                        double num4       = 0.0;
                        double num5       = 0.0;
                        double eVs        = 0.0;
                        double num6       = 0.0;
                        double eVs2       = 0.0;
                        int    iterations = 0;
                        int    num7       = Orbit.FindClosestPoints(originOrbit, targetOrbit, ref num3, ref num4, ref num5, ref eVs, ref num6, ref eVs2, 0.0001, 20, ref iterations);
                        tOne = originOrbit.StartUT + originOrbit.GetDTforTrueAnomaly(num5, 0.0);
                        double tTwo = originOrbit.StartUT + originOrbit.GetDTforTrueAnomaly(num6, 0.0);
                        if (tOne > tTwo)
                        {
                            UtilMath.SwapValues(ref tOne, ref tTwo);
                            UtilMath.SwapValues(ref num5, ref num6);
                            UtilMath.SwapValues(ref eVs, ref eVs2);
                        }
                    }

                    if (tOne > originOrbit.StartUT)
                    {
                        TimeTilEncounter      = tOne - originOrbit.StartUT;
                        SeparationAtEncounter = (originOrbit.getPositionAtUT(tOne) - targetOrbit.getPositionAtUT(tOne)).magnitude;
                        SpeedAtEncounter      = Math.Abs(originOrbit.getOrbitalSpeedAt(tOne) - targetOrbit.getOrbitalSpeedAt(tOne));
                    }
                }
            }

            if (actualTargetOrbit != targetOrbit)
            {
                targetDisplay = findNameForOrbit(targetOrbit, target);
            }
            else
            {
                targetDisplay = null;
            }

            if (originOrbit == null)
            {
                sourceDisplay = "N/A";
            }
            else if (actualSourceOrbit != originOrbit || HighLogic.LoadedScene == GameScenes.TRACKSTATION)
            {
                sourceDisplay = findNameForOrbit(originOrbit, vessel != null ? vessel : TrackingStationSource);
            }
            else
            {
                sourceDisplay = null;
            }
        }
        /// <summary>
        ///     Updates the details by recalculating if requested.
        /// </summary>
        public void Update()
        {
            ITargetable    target = null;
            global::Vessel vessel = null;

            if (HighLogic.LoadedSceneIsFlight)
            {
                if (FlightGlobals.fetch == null ||
                    FlightGlobals.fetch.VesselTarget == null ||
                    FlightGlobals.ActiveVessel == null ||
                    FlightGlobals.ActiveVessel.targetObject == null ||
                    FlightGlobals.ActiveVessel.targetObject.GetOrbit() == null ||
                    FlightGlobals.ship_orbit == null ||
                    FlightGlobals.ship_orbit.referenceBody == null)
                {
                    ShowDetails = false;
                    return;
                }
                else
                {
                    target = FlightGlobals.ActiveVessel.targetObject;
                    vessel = FlightGlobals.ActiveVessel;
                }
            }
            else if (HighLogic.LoadedScene == GameScenes.TRACKSTATION)
            {
                if (PlanetariumCamera.fetch.target.type == MapObject.ObjectType.CelestialBody)
                {
                    target = PlanetariumCamera.fetch.target.celestialBody;
                }
                else if (PlanetariumCamera.fetch.target.type == MapObject.ObjectType.Vessel)
                {
                    target = PlanetariumCamera.fetch.target.vessel;
                }

                if (TrackingStationSource != null)
                {
                    vessel = TrackingStationSource.GetVessel();
                }
                else
                {
                    TrackingStationSource = target;
                }
            }

            activeTarget = target;

            if (target == null)
            {
                ShowDetails = false;
                return;
            }

            ShowDetails = true;

            var actualSourceOrbit = vessel != null ? vessel.orbit : TrackingStationSource.GetOrbit();
            var actualTargetOrbit = target.GetOrbit();

            if (target is global::Vessel)
            {
                targetVessel = (global::Vessel)target;
            }
            else
            {
                targetVessel = null;
            }

            activeVessel = vessel;

            if (actualSourceOrbit == null)
            {
                //  Debug.Log("Source orbit is null!");
                TrackingStationSource = null;
                ShowDetails           = false;
                return;
            }

            if (actualTargetOrbit == null)
            {
                // Debug.Log("Target orbit is null!");
                ShowDetails = false;
                return;
            }

            isLanded = vessel != null && vessel.LandedOrSplashed;
            bool targetLanded = (target is global::Vessel && ((global::Vessel)target).LandedOrSplashed);

            landedSamePlanet = isLanded && targetLanded && actualSourceOrbit.referenceBody == actualTargetOrbit.referenceBody;

            var originOrbit = isLanded ? actualSourceOrbit.referenceBody.orbit : actualSourceOrbit;
            var targetOrbit = targetLanded ? actualTargetOrbit.referenceBody.orbit : actualTargetOrbit;

            if ((!isLanded && !targetLanded) || (actualSourceOrbit.referenceBody != actualTargetOrbit.referenceBody))
            {
                findConcentricParents(ref originOrbit, ref targetOrbit);
            }

            if (originOrbit == targetOrbit && !landedSamePlanet)
            {
                targetOrbit = actualTargetOrbit;
                originOrbit = null;
            }

            AltitudeSeaLevel    = targetOrbit.altitude;
            ApoapsisHeight      = targetOrbit.ApA;
            PeriapsisHeight     = targetOrbit.PeA;
            TimeToApoapsis      = targetOrbit.timeToAp;
            TimeToPeriapsis     = targetOrbit.timeToPe;
            SemiMajorAxis       = targetOrbit.semiMajorAxis;
            SemiMinorAxis       = targetOrbit.semiMinorAxis;
            OrbitalPeriod       = targetOrbit.period;
            RelativeInclination = targetOrbit.inclination;

            TimeToAscendingNode   = 0;
            TimeToDescendingNode  = 0;
            AngleToAscendingNode  = 0;
            AngleToDescendingNode = 0;

            RelativeVelocity    = 0;
            RelativeSpeed       = 0;
            PhaseAngle          = 0;
            InterceptAngle      = 0;
            TimeToTransferAngle = 0;

            AngleToPlane[0] = 0;
            TimeToPlane[0]  = 0;
            AngleToPlane[1] = 0;
            TimeToPlane[1]  = 0;
            Distance        = 0;

            if (originOrbit != null)
            {
                overrideANDN    = isLanded && actualSourceOrbit.referenceBody == targetOrbit.referenceBody;
                overrideANDNRev = targetLanded && !isLanded && actualTargetOrbit.referenceBody == actualSourceOrbit.referenceBody && target.GetVessel() != null;

                if (landedSamePlanet)   //this should only occur when landed targeting something else landed on same body.

                {
                    AltitudeSeaLevel = target.GetVessel().altitude;
                    ApoapsisHeight   = 0;
                    PeriapsisHeight  = 0;
                    TimeToApoapsis   = 0;
                    TimeToPeriapsis  = 0;
                    SemiMajorAxis    = 0;
                    SemiMinorAxis    = 0;

                    bodyRotationPeriod = actualSourceOrbit.referenceBody.rotationPeriod;

                    Distance = Vector3d.Distance(target.GetVessel().GetWorldPos3D(), vessel.GetWorldPos3D());

                    OrbitalPeriod = bodyRotationPeriod;

                    TimeToRendezvous       = 0;
                    RelativeRadialVelocity = 0;
                }
                else
                {
                    RelativeInclination = originOrbit.GetRelativeInclination(targetOrbit);
                    RelativeSpeed       = originOrbit.orbitalSpeed - targetOrbit.orbitalSpeed;
                    RelativeVelocity    = RelativeSpeed;
                    PhaseAngle          = originOrbit.GetPhaseAngle(targetOrbit);
                    InterceptAngle      = CalcInterceptAngle(targetOrbit, originOrbit);

                    double tspd = 360 / targetOrbit.period;
                    double sspd = 360 / originOrbit.period;


                    if (PhaseAngle < 0)
                    {
                        double diff = InterceptAngle - PhaseAngle;
                        if (diff < 0)
                        {
                            diff += 360;
                        }
                        if (diff > 340)
                        {
                            diff -= 360;
                        }
                        TimeToTransferAngle = sspd == tspd ? 0 : diff / (tspd - sspd);
                    }
                    else
                    {
                        double diff = PhaseAngle - InterceptAngle;
                        if (diff < 0)
                        {
                            diff += 360;
                        }
                        if (diff > 340)
                        {
                            diff -= 360;
                        }
                        TimeToTransferAngle = sspd == tspd ? 0 : diff / (sspd - tspd);
                    }


                    TimeToAscendingNode   = originOrbit.GetTimeToVector(GetAscendingNode(targetOrbit, originOrbit));
                    TimeToDescendingNode  = originOrbit.GetTimeToVector(GetDescendingNode(targetOrbit, originOrbit));
                    AngleToAscendingNode  = originOrbit.GetAngleToVector(GetAscendingNode(targetOrbit, originOrbit));
                    AngleToDescendingNode = originOrbit.GetAngleToVector(GetDescendingNode(targetOrbit, originOrbit));

                    Distance = Vector3d.Distance(targetOrbit.pos, originOrbit.pos);

                    bodyRotationPeriod = actualSourceOrbit.referenceBody.rotationPeriod;

                    // beware that the order/sign of coordinates is inconsistent across different exposed variables
                    // in particular, v below does not equal to FlightGlobals.ship_tgtVelocity
                    Vector3d x  = targetOrbit.pos - originOrbit.pos;
                    Vector3d v  = targetOrbit.vel - originOrbit.vel;
                    double   xv = Vector3d.Dot(x, v);
                    TimeToRendezvous       = -xv / Vector3d.SqrMagnitude(v);
                    RelativeRadialVelocity = xv / Vector3d.Magnitude(x);

                    if (overrideANDN) //calc launch time
                    {
                        if (vessel != null)
                        {
                            AngleToPlane   = CalcAngleToPlane(vessel.GetOrbit().referenceBody, vessel.latitude, vessel.longitude, targetOrbit);
                            TimeToPlane[0] = (AngleToPlane[0] / 360) * vessel.GetOrbit().referenceBody.rotationPeriod;
                            TimeToPlane[1] = (AngleToPlane[1] / 360) * vessel.GetOrbit().referenceBody.rotationPeriod;
                        }

                        RelativeInclination    = targetOrbit.inclination;
                        RelativeRadialVelocity = 0;
                        TimeToRendezvous       = 0;
                        PhaseAngle             = 0;
                        InterceptAngle         = 0;
                        TimeToTransferAngle    = 0;
                    }
                    else if (overrideANDNRev)     //calc land time.
                    {
                        global::Vessel tgt = target.GetVessel();

                        if (vessel != null)
                        {
                            AngleToPlane   = CalcAngleToPlane(vessel.GetOrbit().referenceBody, tgt.latitude, tgt.longitude, originOrbit);
                            TimeToPlane[0] = (AngleToPlane[0] / 360) * vessel.GetOrbit().referenceBody.rotationPeriod;
                            TimeToPlane[1] = (AngleToPlane[1] / 360) * vessel.GetOrbit().referenceBody.rotationPeriod;
                        }

                        RelativeInclination    = originOrbit.inclination;
                        Distance               = Vector3d.Distance(target.GetVessel().GetWorldPos3D(), vessel.GetWorldPos3D());
                        AltitudeSeaLevel       = tgt.altitude;
                        PhaseAngle             = 0;
                        InterceptAngle         = 0;
                        TimeToTransferAngle    = 0;
                        ApoapsisHeight         = 0;
                        PeriapsisHeight        = 0;
                        TimeToApoapsis         = 0;
                        TimeToPeriapsis        = 0;
                        SemiMajorAxis          = 0;
                        SemiMinorAxis          = 0;
                        OrbitalPeriod          = 0;
                        RelativeRadialVelocity = 0;
                        TimeToRendezvous       = 0;
                    }
                }
            }

            if (actualTargetOrbit != targetOrbit)
            {
                targetDisplay = findNameForOrbit(targetOrbit, target);
            }
            else
            {
                targetDisplay = null;
            }

            if (originOrbit == null)
            {
                sourceDisplay = "N/A";
            }
            else if (actualSourceOrbit != originOrbit || HighLogic.LoadedScene == GameScenes.TRACKSTATION)
            {
                sourceDisplay = findNameForOrbit(originOrbit, vessel != null ? vessel : TrackingStationSource);
            }
            else
            {
                sourceDisplay = null;
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Vector from given vessel to north pole of body being orbited, in world space.
        /// </summary>
        static Vector3d ToNorthPole(global::Vessel vessel)
        {
            var parent = vessel.mainBody;

            return(parent.position + ((Vector3d)parent.transform.up) * parent.Radius - (vessel.GetWorldPos3D()));
        }