Example #1
0
        /// <summary>
        /// This is called at destroy
        /// </summary>
        public void OnDisable()
        {
            // Tear down the window (saves the position as a side effect)
            HideMainWindow(false);

            // Save the persistent attributes to our settings file
            Settings.Instance.Save();

            // The "dead" copy of our object will re-add itself if we don't unsubscribe to this!
            GameEvents.onGUIApplicationLauncherReady.Remove(AddLauncher);

            // This event fires when KSP wants mods to remove their toolbar buttons
            GameEvents.onGUIApplicationLauncherDestroyed.Remove(RemoveLauncher);

            // This event fires when switching focus in the tracking station
            GameEvents.onPlanetariumTargetChanged.Remove(TrackingStationTargetChanged);

            // Reset the view when we take off or land, etc.
            GameEvents.onVesselSituationChange.Remove(OnSituationChanged);

            // The launcher destroyed event doesn't always fire when we need it (?)
            RemoveLauncher();

            // This event fires on SOI change
            if (VesselMode)
            {
                OrbitDriver orbDrv = FlightGlobals.ActiveVessel.GetOrbitDriver();
                orbDrv.OnReferenceBodyChange -= SOIChanged;
            }
        }
Example #2
0
 public static void Complex(OrbitDriver currentlyEditing, double inclination, double eccentricity,
     double semiMajorAxis, double longitudeAscendingNode, double argumentOfPeriapsis,
     double meanAnomalyAtEpoch, double epoch, CelestialBody body)
 {
     SetOrbit(currentlyEditing, CreateOrbit(inclination, eccentricity, semiMajorAxis,
         longitudeAscendingNode, argumentOfPeriapsis, meanAnomalyAtEpoch, epoch, body));
 }
Example #3
0
 public static void ForceStart(this OrbitDriver driver)
 {
     if (!driver.Ready())
     {
         OrbitDriverStart.Invoke(driver, null);
     }
 }
Example #4
0
        public static void Graphical(OrbitDriver currentlyEditing, double inclination, double eccentricity,
                                     double periapsis, double longitudeAscendingNode, double argumentOfPeriapsis,
                                     double meanAnomaly, double epoch)
        {
            var body  = currentlyEditing.orbit.referenceBody;
            var soi   = body.Soi();
            var ratio = soi / (body.Radius + body.atmosphereDepth + 1000);

            periapsis  = Math.Pow(ratio, periapsis) / ratio;
            periapsis *= soi;

            eccentricity *= Math.PI / 2 - 0.001;

            eccentricity = Math.Tan(eccentricity);
            var semimajor = periapsis / (1 - eccentricity);

            if (semimajor < 0)
            {
                meanAnomaly -= 0.5;
                meanAnomaly *= eccentricity * 4; // 4 is arbitrary constant
            }

            inclination            *= 360;
            longitudeAscendingNode *= 360;
            argumentOfPeriapsis    *= 360;
            meanAnomaly            *= 2 * Math.PI;

            SetOrbit(currentlyEditing, CreateOrbit(inclination, eccentricity, semimajor, longitudeAscendingNode, argumentOfPeriapsis, meanAnomaly, epoch, body));
        }
Example #5
0
        public static void GetSimple(OrbitDriver currentlyEditing, out double altitude, out CelestialBody body)
        {
            const int min        = 1000;
            const int defaultAlt = 100000;

            body     = currentlyEditing.orbit.referenceBody;
            altitude = currentlyEditing.orbit.semiMajorAxis - body.Radius;
            if (altitude > min)
            {
                return;
            }

            if (currentlyEditing.vessel.Landed)
            {
                altitude = currentlyEditing.vessel.radarAltitude;
                return;
            }
            else
            {
                altitude = currentlyEditing.orbit.ApA;
            }

            if (altitude > min)
            {
                return;
            }

            altitude = defaultAlt;
        }
Example #6
0
        /// <summary>
        /// This is called at creation
        /// </summary>
        public void Start()
        {
            Instance = this;

            // This event fires when KSP is ready for mods to add toolbar buttons
            GameEvents.onGUIApplicationLauncherReady.Add(AddLauncher);

            // This event fires when KSP wants mods to remove their toolbar buttons
            GameEvents.onGUIApplicationLauncherDestroyed.Add(RemoveLauncher);

            // This event fires when switching focus in the tracking station
            GameEvents.onPlanetariumTargetChanged.Add(TrackingStationTargetChanged);

            // Reset the view when we take off or land, etc.
            GameEvents.onVesselSituationChange.Add(OnSituationChanged);

            // This event fires on SOI change
            if (FlightGlobals.ActiveVessel != null)
            {
                VesselMode = true;

                OrbitDriver orbDrv = FlightGlobals.ActiveVessel.GetOrbitDriver();
                orbDrv.OnReferenceBodyChange += SOIChanged;
            }
        }
Example #7
0
 public static void Complex(OrbitDriver currentlyEditing, double inclination, double eccentricity,
                            double semiMajorAxis, double longitudeAscendingNode, double argumentOfPeriapsis,
                            double meanAnomalyAtEpoch, double epoch, CelestialBody body)
 {
     SetOrbit(currentlyEditing, CreateOrbit(inclination, eccentricity, semiMajorAxis,
                                            longitudeAscendingNode, argumentOfPeriapsis, meanAnomalyAtEpoch, epoch, body));
 }
Example #8
0
        private static void TrackRigidbody(OrbitDriver driver, CelestialBody refBody, double fdtOffset, ref double updateUT)
        {
            updateUT = Planetarium.GetUniversalTime();
            if (driver.vessel != null)
            {
                driver.pos = (driver.vessel.CoMD - driver.referenceBody.position).xzy;
            }
            if (driver.vessel != null && driver.vessel.rootPart != null && driver.vessel.rootPart.rb != null) //  && !driver.vessel.rootPart.rb.isKinematic
            {
                updateUT  += fdtOffset;
                driver.vel = driver.vessel.velocityD.xzy + driver.orbit.GetRotFrameVelAtPos(driver.referenceBody, driver.pos);
            }
            else if (driver.updateMode == OrbitDriver.UpdateMode.IDLE)
            {
                driver.vel = driver.orbit.GetRotFrameVel(driver.referenceBody);
            }
            if (refBody != driver.referenceBody)
            {
                if (driver.vessel != null)
                {
                    driver.pos = (driver.vessel.CoMD - refBody.position).xzy;
                }
                driver.vel = driver.vel + (driver.referenceBody.GetFrameVel() - refBody.GetFrameVel());
            }
            driver.lastTrackUT = updateUT;

            //Do not call UpdateFromStateVectors as that would update the orbit data BASED on the current vessel position
            //driver.orbit.UpdateFromStateVectors(driver.pos, driver.vel, refBody, updateUT);
            //driver.pos.Swizzle();
            //driver.vel.Swizzle();
        }
Example #9
0
        public static void GetGraphical(OrbitDriver currentlyEditing, out double inclination, out double eccentricity,
                                        out double periapsis, out double longitudeAscendingNode, out double argumentOfPeriapsis,
                                        out double meanAnomaly, out double epoch)
        {
            inclination            = currentlyEditing.orbit.inclination / 360;
            inclination            = inclination.Mod(1);
            longitudeAscendingNode = currentlyEditing.orbit.LAN / 360;
            longitudeAscendingNode = longitudeAscendingNode.Mod(1);
            argumentOfPeriapsis    = currentlyEditing.orbit.argumentOfPeriapsis / 360;
            argumentOfPeriapsis    = argumentOfPeriapsis.Mod(1);
            var eTemp = Math.Atan(currentlyEditing.orbit.eccentricity);

            eccentricity = eTemp / (Math.PI / 2 - 0.001);
            var soi       = currentlyEditing.orbit.referenceBody.Soi();
            var ratio     = soi / (currentlyEditing.orbit.referenceBody.Radius + currentlyEditing.orbit.referenceBody.atmosphereDepth + 1000);
            var semimajor = currentlyEditing.orbit.semiMajorAxis * (1 - currentlyEditing.orbit.eccentricity);

            semimajor   /= soi;
            semimajor   *= ratio;
            semimajor    = Math.Log(semimajor, ratio);
            periapsis    = semimajor;
            meanAnomaly  = currentlyEditing.orbit.meanAnomalyAtEpoch;
            meanAnomaly /= (2 * Math.PI);
            if (currentlyEditing.orbit.semiMajorAxis < 0)
            {
                meanAnomaly /= currentlyEditing.orbit.eccentricity * 4;
                meanAnomaly += 0.5;
            }
            epoch = currentlyEditing.orbit.epoch;
        }
Example #10
0
        private static void HardsetOrbit(OrbitDriver orbitDriver, Orbit newOrbit)
        {
            Log.Info("HardsetOrbit");
            var orbit = orbitDriver.orbit;

            orbit.inclination         = newOrbit.inclination;
            orbit.eccentricity        = newOrbit.eccentricity;
            orbit.semiMajorAxis       = newOrbit.semiMajorAxis;
            orbit.LAN                 = newOrbit.LAN;
            orbit.argumentOfPeriapsis = newOrbit.argumentOfPeriapsis;
            orbit.meanAnomalyAtEpoch  = newOrbit.meanAnomalyAtEpoch;
            orbit.epoch               = newOrbit.epoch;
            orbit.referenceBody       = newOrbit.referenceBody;
            orbit.Init();
            orbit.UpdateFromUT(Planetarium.GetUniversalTime());
            if (orbit.referenceBody != newOrbit.referenceBody)
            {
                if (orbitDriver.OnReferenceBodyChange != null)
                {
                    orbitDriver.OnReferenceBodyChange(newOrbit.referenceBody);
                }
            }
            RateLimitedLogger.Log(HardsetOrbitLogObject,
                                  string.Format("Orbit \"{0}\" changed to: inc={1} ecc={2} sma={3} lan={4} argpe={5} mep={6} epoch={7} refbody={8}",
                                                orbitDriver.OrbitDriverToString(), orbit.inclination, orbit.eccentricity, orbit.semiMajorAxis,
                                                orbit.LAN, orbit.argumentOfPeriapsis, orbit.meanAnomalyAtEpoch, orbit.epoch, orbit.referenceBody.CbToString()));
        }
Example #11
0
 public static void GetGraphical(OrbitDriver currentlyEditing, out double inclination, out double eccentricity,
     out double periapsis, out double longitudeAscendingNode, out double argumentOfPeriapsis,
     out double meanAnomaly, out double epoch)
 {
     inclination = currentlyEditing.orbit.inclination / 360;
     inclination = inclination.Mod(1);
     longitudeAscendingNode = currentlyEditing.orbit.LAN / 360;
     longitudeAscendingNode = longitudeAscendingNode.Mod(1);
     argumentOfPeriapsis = currentlyEditing.orbit.argumentOfPeriapsis / 360;
     argumentOfPeriapsis = argumentOfPeriapsis.Mod(1);
     var eTemp = Math.Atan(currentlyEditing.orbit.eccentricity);
     eccentricity = eTemp / (Math.PI / 2 - 0.001);
     var soi = currentlyEditing.orbit.referenceBody.Soi();
     var ratio = soi / (currentlyEditing.orbit.referenceBody.Radius + currentlyEditing.orbit.referenceBody.atmosphereDepth + 1000);
     var semimajor = currentlyEditing.orbit.semiMajorAxis * (1 - currentlyEditing.orbit.eccentricity);
     semimajor /= soi;
     semimajor *= ratio;
     semimajor = Math.Log(semimajor, ratio);
     periapsis = semimajor;
     meanAnomaly = currentlyEditing.orbit.meanAnomalyAtEpoch;
     meanAnomaly /= (2 * Math.PI);
     if (currentlyEditing.orbit.semiMajorAxis < 0)
     {
         meanAnomaly /= currentlyEditing.orbit.eccentricity * 4;
         meanAnomaly += 0.5;
     }
     epoch = currentlyEditing.orbit.epoch;
 }
Example #12
0
        /// <summary>
        /// This is called at creation
        /// </summary>
        public void Start()
        {
            // This event fires when KSP is ready for mods to add toolbar buttons
            GameEvents.onGUIApplicationLauncherReady.Add(AddLauncher);

            // This event fires when KSP wants mods to remove their toolbar buttons
            GameEvents.onGUIApplicationLauncherDestroyed.Add(RemoveLauncher);

            // This event fires when switching focus in the tracking station
            GameEvents.onPlanetariumTargetChanged.Add(TrackingStationTargetChanged);

            // Reset the view when we take off or land, etc.
            GameEvents.onVesselSituationChange.Add(OnSituationChanged);

            // Save window position before Unity pre-emptively destroys it
            GameEvents.onGameSceneSwitchRequested.Add(BeforeSceneChange);

            // Reset the view when craft changes
            GameEvents.onVesselStandardModification.Add(OnVesselStandardModification);

            // Recalculate model when delta V numbers are updated
            GameEvents.onDeltaVCalcsCompleted.Add(OnDeltaVCalcsCompleted);

            // This event fires on SOI change
            if (FlightGlobals.ActiveVessel != null)
            {
                VesselMode = true;

                OrbitDriver orbDrv = FlightGlobals.ActiveVessel.GetOrbitDriver();
                orbDrv.OnReferenceBodyChange += SOIChanged;
            }
        }
Example #13
0
 /// <summary>
 /// Old school style override of PatchedConics.CheckEncounter, set up in Start and reset at destroy.
 /// We prevent any encounter with our starting body, and otherwise hand off to the default implementation.
 /// </summary>
 /// <param name="p">The patch currently being analyzed</param>
 /// <param name="nextPatch">The next patch to be analyzed</param>
 /// <param name="startEpoch">The time when the vessel reaches p</param>
 /// <param name="sec">The driver of the orbit to check for an encounter; this is the only parameter that we actually use here rather than passing along to the default implementation</param>
 /// <param name="targetBody">The user's currently selected target</param>
 /// <param name="pars">Stuff that controls how the solver works</param>
 /// <param name="logErrors">true to print things to the log, false otherwise</param>
 /// <returns>
 /// true if encounter found, false otherwise (or if one would have been found for our starting body)
 /// </returns>
 private bool MyCheckEncounter(
     Orbit p, Orbit nextPatch, double startEpoch, OrbitDriver sec,
     CelestialBody targetBody, PatchedConics.SolverParameters pars, bool logErrors = true)
 {
     // Suppress encounters with our starting body, because it makes the solver put NaN orbits in the flight plan
     return(sec?.celestialBody == editingNode?.origin
                         ? false
                         : originalCheckEncounter(p, nextPatch, startEpoch, sec, targetBody, pars, logErrors));
 }
Example #14
0
        private static void HardsetOrbit(OrbitDriver orbitDriver, Orbit newOrbit)
        {
            var orbit = orbitDriver.orbit;

            HardsetOrbit(orbit, newOrbit);
            if (orbit.referenceBody != newOrbit.referenceBody)
            {
                orbitDriver.OnReferenceBodyChange?.Invoke(newOrbit.referenceBody);
            }
        }
Example #15
0
 public static void Rendezvous(OrbitDriver currentlyEditing, double leadTime, Vessel target)
 {
     SetOrbit(currentlyEditing, CreateOrbit(
                  target.orbit.inclination,
                  target.orbit.eccentricity,
                  target.orbit.semiMajorAxis,
                  target.orbit.LAN,
                  target.orbit.argumentOfPeriapsis,
                  target.orbit.meanAnomalyAtEpoch,
                  target.orbit.epoch - leadTime,
                  target.orbit.referenceBody));
 }
        private static void UpdateOrbit(OrbitDriver driver, bool offset, ref bool ready, ref double fdtLast, ref bool isHyperbolic)
        {
            if (!ready)
            {
                return;
            }
            driver.lastMode = driver.updateMode;

            //Always call updateFromParameters so the vessel is positioned based on the orbital data
            if ((VesselPositionSystem.Singleton.VesselHavePositionUpdatesQueued(driver.vessel.id) && driver.updateMode == OrbitDriver.UpdateMode.TRACK_Phys) ||
                driver.updateMode == OrbitDriver.UpdateMode.UPDATE)
            {
                driver.updateFromParameters();
                if (driver.vessel)
                {
                    driver.CheckDominantBody(driver.referenceBody.position + driver.pos);
                }
            }

            if (driver.vessel && driver.vessel.rootPart && driver.vessel.rootPart.rb)
            {
                if (!offset)
                {
                    fdtLast = 0;
                }
                if (!driver.CheckDominantBody(driver.vessel.CoMD))
                {
                    driver.TrackRigidbody(driver.referenceBody, -fdtLast);
                }
            }

            fdtLast = (double)TimeWarp.fixedDeltaTime;
            if (isHyperbolic && driver.orbit.eccentricity < 1)
            {
                isHyperbolic = false;
                if (driver.vessel != null)
                {
                    GameEvents.onVesselOrbitClosed.Fire(driver.vessel);
                }
            }
            if (!isHyperbolic && driver.orbit.eccentricity > 1)
            {
                isHyperbolic = true;
                if (driver.vessel != null)
                {
                    GameEvents.onVesselOrbitEscaped.Fire(driver.vessel);
                }
            }
            if (driver.drawOrbit)
            {
                driver.orbit.DrawOrbit();
            }
        }
        private static void PostfixTrackRigidbody(OrbitDriver __instance, bool __state)
        {
            if (MainSystem.NetworkState < ClientState.Connected)
            {
                return;
            }

            if (__instance.vessel && __instance.vessel.rootPart && __instance.vessel.rootPart.rb && !__instance.vessel.rootPart.rb.isKinematic && __state)
            {
                __instance.vessel.rootPart.rb.isKinematic = true;
            }
        }
Example #18
0
 public static void GetComplex(OrbitDriver currentlyEditing, out double inclination, out double eccentricity,
                               out double semiMajorAxis, out double longitudeAscendingNode, out double argumentOfPeriapsis,
                               out double meanAnomalyAtEpoch, out double epoch, out CelestialBody body)
 {
     inclination            = currentlyEditing.orbit.inclination;
     eccentricity           = currentlyEditing.orbit.eccentricity;
     semiMajorAxis          = currentlyEditing.orbit.semiMajorAxis;
     longitudeAscendingNode = currentlyEditing.orbit.LAN;
     argumentOfPeriapsis    = currentlyEditing.orbit.argumentOfPeriapsis;
     meanAnomalyAtEpoch     = currentlyEditing.orbit.meanAnomalyAtEpoch;
     epoch = currentlyEditing.orbit.epoch;
     body  = currentlyEditing.orbit.referenceBody;
 }
Example #19
0
 public static void GetComplex(OrbitDriver currentlyEditing, out double inclination, out double eccentricity,
     out double semiMajorAxis, out double longitudeAscendingNode, out double argumentOfPeriapsis,
     out double meanAnomalyAtEpoch, out double epoch, out CelestialBody body)
 {
     inclination = currentlyEditing.orbit.inclination;
     eccentricity = currentlyEditing.orbit.eccentricity;
     semiMajorAxis = currentlyEditing.orbit.semiMajorAxis;
     longitudeAscendingNode = currentlyEditing.orbit.LAN;
     argumentOfPeriapsis = currentlyEditing.orbit.argumentOfPeriapsis;
     meanAnomalyAtEpoch = currentlyEditing.orbit.meanAnomalyAtEpoch;
     epoch = currentlyEditing.orbit.epoch;
     body = currentlyEditing.orbit.referenceBody;
 }
Example #20
0
        public static void DynamicSetOrbit(this OrbitDriver orbit, Orbit newOrbit)
        {
            Log.Info("DynamicSetOrbit");
            var vessel = orbit.vessel;

            if (vessel != null)
            {
                vessel.SetOrbit(newOrbit);
            }
            else
            {
                HardsetOrbit(orbit, newOrbit);
            }
        }
        private static bool PrefixUpdateOrbit(OrbitDriver __instance, bool offset)
        {
            if (MainSystem.NetworkState < ClientState.Connected)
            {
                return(true);
            }

            if (SettingsSystem.CurrentSettings.OverrideIntegrator && __instance?.vessel != null)
            {
                return(LockSystem.LockQuery.UpdateLockBelongsToPlayer(__instance.vessel.id, SettingsSystem.CurrentSettings.PlayerName));
            }

            return(true);
        }
Example #22
0
        /// <summary>
        /// This is called at destroy
        /// </summary>
        public void OnDisable()
        {
            // Tear down the window (saves the position as a side effect)
            HideMainWindow(false);

            // Save the persistent attributes to our settings file
            Settings.Instance.Save();

            if (loader != null)
            {
                // Tell the loader we don't need data anymore;
                // prevents new threads from starting
                loader.OnDisplayClosed();

                // Clean up the timer and thread
                loader.Dispose();
            }

            // The "dead" copy of our object will re-add itself if we don't unsubscribe to this!
            GameEvents.onGUIApplicationLauncherReady.Remove(AddLauncher);

            // This event fires when KSP wants mods to remove their toolbar buttons
            GameEvents.onGUIApplicationLauncherDestroyed.Remove(RemoveLauncher);

            // This event fires when switching focus in the tracking station
            GameEvents.onPlanetariumTargetChanged.Remove(TrackingStationTargetChanged);

            // Reset the view when we take off or land, etc.
            GameEvents.onVesselSituationChange.Remove(OnSituationChanged);

            // Save window position before Unity pre-emptively destroys it
            GameEvents.onGameSceneSwitchRequested.Remove(BeforeSceneChange);

            // Reset the view when craft changes
            GameEvents.onVesselStandardModification.Remove(OnVesselStandardModification);

            // Recalculate model when delta V numbers are updated
            GameEvents.onDeltaVCalcsCompleted.Remove(OnDeltaVCalcsCompleted);

            // The launcher destroyed event doesn't always fire when we need it (?)
            RemoveLauncher();

            // This event fires on SOI change
            if (VesselMode)
            {
                OrbitDriver orbDrv = FlightGlobals.ActiveVessel.GetOrbitDriver();
                orbDrv.OnReferenceBodyChange -= SOIChanged;
            }
        }
Example #23
0
        private static bool PrefixUpdateOrbit(OrbitDriver __instance, bool offset, ref bool ___ready, ref double ___fdtLast, ref bool ___isHyperbolic)
        {
            if (MainSystem.NetworkState < ClientState.Connected)
            {
                return(true);
            }
            if (__instance.vessel == null)
            {
                return(true);
            }

            UpdateOrbit(__instance, offset, ref ___ready, ref ___fdtLast, ref ___isHyperbolic);

            return(false);
        }
        private static bool PrefixUpdateFromParameters(OrbitDriver __instance, ref double ___updateUT)
        {
            if (MainSystem.NetworkState < ClientState.Connected)
            {
                return(true);
            }
            if (__instance.vessel == null)
            {
                return(true);
            }

            UpdateFromParameters(__instance, ref ___updateUT);

            return(false);
        }
        private static bool PrefixTrackRigidbody(OrbitDriver __instance, CelestialBody refBody, double fdtOffset, ref double ___updateUT)
        {
            if (MainSystem.NetworkState < ClientState.Connected)
            {
                return(true);
            }
            if (__instance.vessel == null)
            {
                return(true);
            }

            TrackRigidbody(__instance, refBody, fdtOffset, ref ___updateUT);

            return(false);
        }
Example #26
0
            private void MakeOrbit(OrbitDriver driver, CelestialBody reference)
            {
                Debug.Log("Jumping to " + partnerBody);

                CelestialBody oldBody = driver.referenceBody;

                FlightGlobals.overrideOrbit = true;
                FlightGlobals.fetch.Invoke("disableOverride", 2f);
                driver.vessel.Landed   = false;
                driver.vessel.Splashed = false;
                driver.vessel.SetLandedAt("");
                driver.vessel.KillPermanentGroundContact();
                driver.vessel.ResetGroundContact();
                FlightGlobals.currentMainBody = reference;
                OrbitPhysicsManager.SetDominantBody(reference);

                // Pack vessels
                foreach (Vessel vessel in FlightGlobals.Vessels)
                {
                    if (!vessel.packed)
                    {
                        vessel.GoOnRails();
                    }
                }

                // Disable inverse rotation
                foreach (CelestialBody body in PSystemManager.Instance.localBodies)
                {
                    body.inverseRotation = false;
                }

                driver.orbit.referenceBody = reference;
                driver.updateFromParameters();

                // Finalize Vessel Movement
                CollisionEnhancer.bypass = true;
                FloatingOrigin.SetOffset(driver.vessel.transform.position);
                OrbitPhysicsManager.CheckReferenceFrame();
                OrbitPhysicsManager.HoldVesselUnpack(10);
                if (reference != oldBody)
                {
                    GameEvents.onVesselSOIChanged.Fire(
                        new GameEvents.HostedFromToAction <Vessel, CelestialBody>(driver.vessel, oldBody,
                                                                                  reference));
                }

                driver.vessel.IgnoreGForces(20);
            }
        private static void UpdateFromParameters(OrbitDriver driver, ref double updateUT)
        {
            updateUT = Planetarium.GetUniversalTime();
            driver.orbit.UpdateFromUT(updateUT);
            driver.pos = driver.orbit.pos;
            driver.vel = driver.orbit.vel;
            driver.pos.Swizzle();
            driver.vel.Swizzle();
            if (double.IsNaN(driver.pos.x))
            {
                MonoBehaviour.print(string.Concat(new object[] { "ObT : ", driver.orbit.ObT, "\nM : ", driver.orbit.meanAnomaly, "\nE : ", driver.orbit.eccentricAnomaly, "\nV : ", driver.orbit.trueAnomaly, "\nRadius: ", driver.orbit.radius, "\nvel: ", driver.vel.ToString(), "\nAN: ", driver.orbit.an.ToString(), "\nperiod: ", driver.orbit.period, "\n" }));
                if (driver.vessel)
                {
                    Debug.LogWarning(string.Concat("[LMP - OrbitDriver Warning!]: ", driver.vessel.vesselName, " had a NaN Orbit and was removed."));
                    driver.vessel.Unload();

                    VesselRemoveSystem.Singleton.MessageSender.SendVesselRemove(driver.vessel.id, true);
                    VesselRemoveSystem.Singleton.KillVessel(driver.vessel.id, true, "Corrupt vessel orbit");

                    return;
                }
            }
            if (driver.reverse)
            {
                driver.referenceBody.position = (!driver.celestialBody ? (Vector3d)driver.driverTransform.position : driver.celestialBody.position) - driver.pos;
            }
            else if (driver.vessel)
            {
                if (VesselPositionSystem.Singleton.VesselHavePositionUpdatesQueued(driver.vessel.id))
                {
                    //DO NOT update the vessel position here. The VesselPositioningSystem takes care of that
                    return;
                }
                else
                {
                    Vector3d vector3d = driver.driverTransform.rotation * driver.vessel.localCoM;
                    driver.vessel.SetPosition((driver.referenceBody.position + driver.pos) - vector3d);
                }
            }
            else if (!driver.celestialBody)
            {
                driver.driverTransform.position = driver.referenceBody.position + driver.pos;
            }
            else
            {
                driver.celestialBody.position = driver.referenceBody.position + driver.pos;
            }
        }
Example #28
0
        private bool MouseOverTargetable(ITargetable targetable)
        {
            bool result = false;

            OrbitDriver targetDriver = targetable.GetOrbitDriver();

            OrbitRenderer.OrbitCastHit rendererHit = default(OrbitRenderer.OrbitCastHit);
            if (targetDriver != null && targetDriver.Renderer.OrbitCast(Input.mousePosition, out rendererHit))
            {
                result          = true;
                _hitOrbit       = rendererHit.or.driver.orbit;
                _hitScreenPoint = rendererHit.GetScreenSpacePoint();
                _hitUT          = rendererHit.UTatTA;
            }

            return(result);
        }
Example #29
0
        public static void DynamicSetOrbit(this OrbitDriver orbit, Orbit newOrbit)
        {
            var vessel = orbit.vessel;
            var body   = orbit.celestialBody;

            if (vessel != null)
            {
                vessel.SetOrbit(newOrbit);
            }
            else if (body != null)
            {
                body.SetOrbit(newOrbit);
            }
            else
            {
                HardsetOrbit(orbit, newOrbit);
            }
        }
Example #30
0
 public override void Cache()
 {
     if (!IsSun())
     {
         orbit             = planet.GetOrbit();
         orbitData         = OrbitDataFromOrbit(orbit);
         orbitDriver       = planet.orbitDriver;
         referenceBody     = orbit.referenceBody;
         referenceBodyData = solarSystem.GetPlanetByCelestialBody(referenceBody);
     }
     else
     {
         referenceBody     = solarSystem.sun;
         referenceBodyData = solarSystem.sunData;
     }
     gravity           = planet.gravParameter;
     sphereOfInfluence = planet.sphereOfInfluence;
 }
Example #31
0
        private static void HardsetOrbit(OrbitDriver orbitDriver, Orbit newOrbit)
        {
            var orbit = orbitDriver.orbit;

            orbit.inclination         = newOrbit.inclination;
            orbit.eccentricity        = newOrbit.eccentricity;
            orbit.semiMajorAxis       = newOrbit.semiMajorAxis;
            orbit.LAN                 = newOrbit.LAN;
            orbit.argumentOfPeriapsis = newOrbit.argumentOfPeriapsis;
            orbit.meanAnomalyAtEpoch  = newOrbit.meanAnomalyAtEpoch;
            orbit.epoch               = newOrbit.epoch;
            orbit.referenceBody       = newOrbit.referenceBody;
            orbit.Init();
            orbit.UpdateFromUT(Planetarium.GetUniversalTime());
            if (orbit.referenceBody != newOrbit.referenceBody)
            {
                orbitDriver.OnReferenceBodyChange?.Invoke(newOrbit.referenceBody);
            }
        }
Example #32
0
 public static string OrbitDriverToString(this OrbitDriver driver)
 {
     if (driver == null)
     {
         return(null);
     }
     if (driver.celestialBody != null)
     {
         return(driver.celestialBody.bodyName);
     }
     if (driver.vessel != null)
     {
         return(driver.vessel.VesselToString());
     }
     if (!string.IsNullOrEmpty(driver.name))
     {
         return(driver.name);
     }
     return("Unknown");
 }
Example #33
0
        private static void HardsetOrbit(OrbitDriver orbitDriver, Orbit newOrbit)
        {
            var orbit = orbitDriver.orbit;

            orbit.inclination         = newOrbit.inclination;
            orbit.eccentricity        = newOrbit.eccentricity;
            orbit.semiMajorAxis       = newOrbit.semiMajorAxis;
            orbit.LAN                 = newOrbit.LAN;
            orbit.argumentOfPeriapsis = newOrbit.argumentOfPeriapsis;
            orbit.meanAnomalyAtEpoch  = newOrbit.meanAnomalyAtEpoch;
            orbit.epoch               = newOrbit.epoch;
            orbit.referenceBody       = newOrbit.referenceBody;
            orbit.Init();
            orbit.UpdateFromUT(Planetarium.GetUniversalTime());
            if (orbit.referenceBody != newOrbit.referenceBody)
            {
                orbitDriver.OnReferenceBodyChange?.Invoke(newOrbit.referenceBody);
            }
            RateLimitedLogger.Log(HardsetOrbitLogObject,
                                  $"Orbit \"{orbitDriver.OrbitDriverToString()}\" changed to: inc={orbit.inclination} ecc={orbit.eccentricity} sma={orbit.semiMajorAxis} lan={orbit.LAN} argpe={orbit.argumentOfPeriapsis} mep={orbit.meanAnomalyAtEpoch} epoch={orbit.epoch} refbody={orbit.referenceBody.CbToString()}");
        }
Example #34
0
 public static void Simple(OrbitDriver currentlyEditing, double altitude, CelestialBody body)
 {
     SetOrbit(currentlyEditing, CreateOrbit(0 , 0, altitude + body.Radius, 0, 0, 0, 0, body));
 }
Example #35
0
        // Show exit orbital predictions
        private void showExitOrbit(Vessel near, Vessel far, string model)
        {
            // Recenter map, save previous state.
            wasInMapView = MapView.MapIsEnabled;
            if (!MapView.MapIsEnabled) MapView.EnterMapView();
            print("Finding target.");
            MapObject farTarget = findVesselBody(far);
            if (farTarget != null) MapView.MapCamera.SetTarget(farTarget);

            // Initialize projection stuff.
            print("Beginning orbital projection.");
            Vector3d exitTraj = getJumpOffset(near, far, model);
            oPredictDriver = new OrbitDriver();
            oPredictDriver.orbit = new Orbit();
            oPredictDriver.orbit.referenceBody = far.mainBody;
            oPredictDriver.referenceBody = far.mainBody;
            oPredictDriver.upperCamVsSmaRatio = 999999;  // Took forever to figure this out - this sets at what zoom level the orbit appears.  Was causing it not to appear at small bodies.
            oPredictDriver.lowerCamVsSmaRatio = 0.0001f;
            oPredictDriver.orbit.UpdateFromStateVectors(far.orbit.pos, exitTraj, far.mainBody, Planetarium.GetUniversalTime());
            oPredictDriver.orbit.Init();
            Vector3d p = oPredictDriver.orbit.getRelativePositionAtUT(Planetarium.GetUniversalTime());
            Vector3d v = oPredictDriver.orbit.getOrbitalVelocityAtUT(Planetarium.GetUniversalTime());
            oPredictDriver.orbit.h = Vector3d.Cross(p, v);
            oPredict = MapView.MapCamera.gameObject.AddComponent<OrbitRenderer>();
            oPredict.upperCamVsSmaRatio = 999999;
            oPredict.lowerCamVsSmaRatio = 0.0001f;
            oPredict.celestialBody = far.mainBody;
            oPredict.driver = oPredictDriver;
            oPredictDriver.Renderer = oPredict;

            // Splash some color on it.
            print("Displaying orbital projection.");
            oPredict.driver.drawOrbit = true;
            oPredict.driver.orbitColor = Color.red;
            oPredict.orbitColor = Color.red;
            oPredict.drawIcons = OrbitRenderer.DrawIcons.OBJ_PE_AP;
            oPredict.drawMode = OrbitRenderer.DrawMode.REDRAW_AND_RECALCULATE;

            // Directional indicator.
            oDirObj = new GameObject("Indicator");
            oDirObj.layer = 10; // Map layer!
            oDirection = oDirObj.AddComponent<LineRenderer>();
            oDirection.useWorldSpace = false;
            oOrigin = null;
            foreach (Transform sstr in ScaledSpace.Instance.scaledSpaceTransforms)
            {
                if (sstr.name == far.mainBody.name)
                {
                    oOrigin = sstr;
                    print("Found origin: " + sstr.name);
                    break;
                }
            }
            oDirection.transform.parent = oOrigin;
            oDirection.transform.position = ScaledSpace.LocalToScaledSpace(far.transform.position);
            oDirection.material = new Material(Shader.Find("Particles/Additive"));
            oDirection.SetColors(Color.clear, Color.red);
            oDirection.SetWidth(20.0f, 0.01f);
            oDirection.SetVertexCount(2);
            oDirection.SetPosition(0, Vector3d.zero + exitTraj.xzy.normalized * 10);
            oDirection.SetPosition(1, exitTraj.xzy.normalized * 50);
            oDirection.enabled = true;
            // */
        }
 public static void SetNewOrbit(OrbitDriver driver, Orbit oldOrbit)
 {
     var orbit = driver.orbit;
         orbit.inclination = driver.orbit.inclination;
         orbit.eccentricity = driver.orbit.eccentricity;
         orbit.semiMajorAxis = (driver.orbit.semiMajorAxis - DecayValue);
         orbit.LAN = driver.orbit.LAN;
         orbit.argumentOfPeriapsis = driver.orbit.argumentOfPeriapsis;
         orbit.meanAnomalyAtEpoch = driver.orbit.meanAnomalyAtEpoch;
         orbit.epoch = driver.orbit.epoch;
         orbit.referenceBody = driver.orbit.referenceBody;
         orbit.Init();
         orbit.UpdateFromUT(Planetarium.GetUniversalTime());
         if (orbit.referenceBody != driver.orbit.referenceBody)
         {
             if (driver.OnReferenceBodyChange != null)
                 driver.OnReferenceBodyChange(driver.orbit.referenceBody);
         }
 }
        public static void StationKeeping(OrbitDriver driver, Vessel vessel)
        {
            // Background resource processing

            bool ResourceFound = true;

            double MaxDecayInfluence = vessel.orbitDriver.orbit.referenceBody.Radius * 10;
            double AtmosphereMultiplier;

            if (vessel.orbitDriver.orbit.referenceBody.atmosphere)
            {
                AtmosphereMultiplier = vessel.orbitDriver.orbit.referenceBody.atmospherePressureSeaLevel / 101.325;
            }
            else
            {
                AtmosphereMultiplier = 0.5;
            }

            if (vessel.orbitDriver.orbit.semiMajorAxis + 50 < MaxDecayInfluence)
            {
                double Lambda = 0.000000000133913 * UI.DifficultySetting;
                double Sigma = MaxDecayInfluence - vessel.orbitDriver.orbit.altitude;
                DecayValue = (double)TimeWarp.CurrentRate * Sigma * vessel.orbitDriver.orbit.referenceBody.GeeASL * AtmosphereMultiplier * Lambda;
            }
            else
            {
                DecayValue = 0;
            }

            foreach (Part part in vessel.Parts)
            {
                if (part.Resources.Count != 0)
                {
                    foreach (PartResource resource in part.Resources)
                    {
                        if (resource.name == "ElectricCharge" && resource.amount > DecayValue)
                        {
                            ResourceFound = true;
                            part.RequestResource("ElectricCharge", DecayValue);
                            VesselData.CanStationKeep.Remove(vessel.id);
                            VesselData.CanStationKeep.Add(vessel.id, true);
                            break;

                        }
                    }
                }
            }

                    if (ResourceFound == false)
                    {
                        ScreenMessages.PostScreenMessage("Warning: " + vessel.name + " has run out of Mono-Propellant, stationkeeping stopped");
                        VesselData.CanStationKeep.Remove(vessel.id);
                        VesselData.CanStationKeep.Add(vessel.id, false);
                    }
        }
        public static void CalculateOrbit(Vessel vessel, Orbit oldOrbit, OrbitDriver driver)
        {
            VesselDied = false;

            if (!VesselData.Message.ContainsKey(vessel.id))
            {
                VesselData.Message.Add(vessel.id, false);
                VesselData.DisplayedMessage = false;
            }
            else
            {
                VesselData.Message.TryGetValue(vessel.id, out VesselData.DisplayedMessage);
            }

            vessel.GoOnRails();

            var oldBody = vessel.orbitDriver.orbit.referenceBody;

               // The ISS decays at about 2km/month = 2000/30*24*60*60 == 7.7x10^-4 m/s

            double BodyGravityConstant = vessel.orbitDriver.orbit.referenceBody.GeeASL;
            double AtmosphereMultiplier;
            double MaxDecayInfluence = vessel.orbitDriver.orbit.referenceBody.Radius * 10;
            if (vessel.orbitDriver.orbit.referenceBody.atmosphere)
            {
                AtmosphereMultiplier = vessel.orbitDriver.orbit.referenceBody.atmospherePressureSeaLevel / 101.325;
            }
            else
            {
                 AtmosphereMultiplier = 0.5;
            }

            if (vessel.orbitDriver.orbit.semiMajorAxis + 50 < MaxDecayInfluence )
            {
                double Lambda = 0.000000000133913 * UI.DifficultySetting;                           //0.000000000133913;
                double Sigma = MaxDecayInfluence - vessel.orbitDriver.orbit.altitude;
                DecayValue = (double)TimeWarp.CurrentRate * Sigma * BodyGravityConstant * AtmosphereMultiplier * Lambda;

                if (vessel.orbitDriver.orbit.referenceBody.atmosphere)
                {
                    if (vessel.orbitDriver.orbit.PeA < vessel.orbitDriver.orbit.referenceBody.atmosphereDepth)
                    {
                        DecayValue = DecayValue * (Math.Pow(Math.E, vessel.orbitDriver.orbit.referenceBody.atmosphereDepth - vessel.orbitDriver.orbit.PeA)); // Have it increase alot more as we enter the hard atmosphere
                    }

                    //EstimatedTimeUntilDeorbit = (float)(vessel.orbitDriver.orbit.altitude - (float)vessel.orbitDriver.orbit.referenceBody.atmosphereDepth) / (float)DecayValue;
                     MaxDecayValue = ((vessel.orbitDriver.orbit.referenceBody.Radius + vessel.orbitDriver.orbit.referenceBody.atmosphereDepth) * BodyGravityConstant * AtmosphereMultiplier * Lambda);
                     EstimatedTimeUntilDeorbit = ((float)(vessel.orbitDriver.orbit.semiMajorAxis - (float)vessel.orbitDriver.orbit.referenceBody.atmosphereDepth)) / (float)MaxDecayValue;
                   // EstimatedTimeUntilDeorbit = (float)(vessel.orbitDriver.orbit.PeA - (((vessel.orbitDriver.referenceBody.atmosphereDepth)/((MaxDecayValue+DecayValue)/2) - vessel.orbitDriver.orbit.PeA)) *((MaxDecayValue + DecayValue) / 2));
                }
                else
                {
                   //EstimatedTimeUntilDeorbit = (float)(vessel.orbitDriver.orbit.altitude - 100) / (float)DecayValue;
                    MaxDecayValue = ((vessel.orbitDriver.orbit.referenceBody.Radius + 100) * BodyGravityConstant * AtmosphereMultiplier * Lambda);
                    EstimatedTimeUntilDeorbit = ((float)(vessel.orbitDriver.orbit.semiMajorAxis - (float)vessel.orbitDriver.orbit.referenceBody.atmosphereDepth)) / (float)MaxDecayValue;
                }
                if (VesselData.DecayTimes.ContainsKey(vessel.id))
                {
                    VesselData.DecayTimes.Remove(vessel.id);
                    VesselData.DecayTimes.Add(vessel.id, EstimatedTimeUntilDeorbit);
                }
                else
                {
                    VesselData.DecayTimes.Add(vessel.id, EstimatedTimeUntilDeorbit);
                }

               // print(vessel.name + " Semi major axis reduced by: " + (DecayValue));
            }
            else
            {
                DecayValue = 0;

                if (VesselData.DecayTimes.ContainsKey(vessel.id))
                {
                    VesselData.DecayTimes.Remove(vessel.id);
                    VesselData.DecayTimes.Add(vessel.id, 0.5f);
                }
                else
                {
                    VesselData.DecayTimes.Add(vessel.id, 0.5f);
                }
            }

            if (VesselDied == false)         // Just Incase the vessel is destroyed part way though the check.
            {
                if (vessel.orbitDriver.orbit.referenceBody.GetInstanceID() != 0 || vessel.orbitDriver.orbit.semiMajorAxis > vessel.orbitDriver.orbit.referenceBody.Radius + 5)
                {
                    SetNewOrbit(driver, oldOrbit);
                }
            }

            if (vessel.orbitDriver.orbit.referenceBody.atmosphere) // Big problem ( Jool, Eve, Duna, Kerbin, Laythe)
            {
                if (vessel.orbitDriver.orbit.semiMajorAxis < vessel.orbitDriver.orbit.referenceBody.Radius + vessel.orbitDriver.referenceBody.atmosphereDepth + 500)
                {
                    FlightDriver.SetPause(true);
                    TimeWarp.SetRate(1, true);
                    FlightDriver.SetPause(false);
                    print("Warning: " + vessel.name + " is approaching " + oldOrbit.referenceBody.name + "'s hard atmosphere");
                    ScreenMessages.PostScreenMessage("Warning: " + vessel.name + " is approaching " + oldOrbit.referenceBody.name + "'s hard atmosphere");
                    VesselData.Message.Remove(vessel.id);
                    VesselData.Message.Add(vessel.id, true);
                }

                if (vessel.orbitDriver.orbit.semiMajorAxis < vessel.orbitDriver.orbit.referenceBody.Radius + vessel.orbitDriver.referenceBody.atmosphereDepth + 5)
                {
                    VesselDied = true;
                }
            }
            else // Moon Smaller Problem
            {
                if (vessel.orbitDriver.orbit.semiMajorAxis < vessel.orbitDriver.orbit.referenceBody.Radius + 5000)
                {
                    FlightDriver.SetPause(true);
                    TimeWarp.SetRate(1, true);
                    FlightDriver.SetPause(false);
                    print("Warning: " + vessel.name + " is approaching " + oldOrbit.referenceBody.name + "'s surface");
                    ScreenMessages.PostScreenMessage("Warning: " + vessel.name + " is approaching " + oldOrbit.referenceBody.name + "'s surface");
                    VesselData.Message.Remove(vessel.id);
                    VesselData.Message.Add(vessel.id, true);
                }

                if (vessel.orbitDriver.orbit.semiMajorAxis < vessel.orbitDriver.orbit.referenceBody.Radius + 100)
                {
                    VesselDied = true;
                }

            }

            if (VesselDied == false)
            {
                vessel.orbitDriver.pos = vessel.orbit.pos.xzy;
                vessel.orbitDriver.vel = vessel.orbit.vel;
                var newBody = vessel.orbitDriver.orbit.referenceBody;
                if (newBody != oldBody)
                {
                    var evnt = new GameEvents.HostedFromToAction<Vessel, CelestialBody>(vessel, oldBody, newBody);
                    GameEvents.onVesselSOIChanged.Fire(evnt);
                }
            }

            if (VesselDied == true)
            {
                vessel.Die();
                VesselData.CanStationKeep.Remove(vessel.id);
                VesselData.DecayTimes.Remove(vessel.id);
                VesselData.DisplayedDecayTimes.Remove(vessel);
                VesselData.StationKeeping.Remove(vessel.id);

            }
        }
        private void setup()
        {
            generator = new System.Random(this.Root.MissionSeed);

            iconWaypoints = new List<Waypoint>();

            for (int cardinals = 0; cardinals < 4; cardinals++)
            {
                bool addedWaypoint = false;

                switch (cardinals)
                {
                    case 0:
                        if (HighLogic.LoadedSceneIsFlight)
                        {
                            iconWaypoints.Add(new Waypoint());
                            iconWaypoints[iconWaypoints.Count - 1].waypointType = WaypointType.ASCENDINGNODE;
                            addedWaypoint = true;
                        }
                        break;
                    case 1:
                        if (HighLogic.LoadedSceneIsFlight)
                        {
                            iconWaypoints.Add(new Waypoint());
                            iconWaypoints[iconWaypoints.Count - 1].waypointType = WaypointType.DESCENDINGNODE;
                            addedWaypoint = true;
                        }
                        break;
                    case 2:
                        iconWaypoints.Add(new Waypoint());
                        iconWaypoints[iconWaypoints.Count - 1].waypointType = WaypointType.APOAPSIS;
                        addedWaypoint = true;
                        break;
                    case 3:
                        iconWaypoints.Add(new Waypoint());
                        iconWaypoints[iconWaypoints.Count - 1].waypointType = WaypointType.PERIAPSIS;
                        addedWaypoint = true;
                        break;
                }

                if (addedWaypoint)
                {
                    iconWaypoints[iconWaypoints.Count - 1].celestialName = targetBody.GetName();
                    iconWaypoints[iconWaypoints.Count - 1].isOnSurface = false;
                    iconWaypoints[iconWaypoints.Count - 1].isNavigatable = false;
                    iconWaypoints[iconWaypoints.Count - 1].seed = Root.MissionSeed;
                    WaypointManager.AddWaypoint(iconWaypoints[iconWaypoints.Count - 1]);
                }
            }

            for (int x = 0; x < numSpinners; x++)
            {
                iconWaypoints.Add(new Waypoint());
                iconWaypoints[iconWaypoints.Count - 1].celestialName = targetBody.GetName();
                iconWaypoints[iconWaypoints.Count - 1].waypointType = WaypointType.ORBITAL;
                iconWaypoints[iconWaypoints.Count - 1].isOnSurface = false;
                iconWaypoints[iconWaypoints.Count - 1].isNavigatable = false;
                iconWaypoints[iconWaypoints.Count - 1].seed = Root.MissionSeed;
                WaypointManager.AddWaypoint(iconWaypoints[iconWaypoints.Count - 1]);
            }

            orbitDriver = new OrbitDriver();
            orbitDriver.orbit = new Orbit();
            orbitDriver.orbit.referenceBody = targetBody;
            orbitDriver.orbit.semiMajorAxis = sma;
            orbitDriver.orbit.eccentricity = eccentricity;
            orbitDriver.orbit.argumentOfPeriapsis = argumentOfPeriapsis;
            orbitDriver.orbit.inclination = inclination;
            orbitDriver.orbit.LAN = lan;
            orbitDriver.orbit.meanAnomalyAtEpoch = meanAnomalyAtEpoch;
            orbitDriver.orbit.epoch = epoch;
            orbitDriver.orbit.Init();
            //The orbit needs to be post processed in an appropriate scene, or it will be useless.
            Util.PostProcessOrbit(ref orbitDriver.orbit);

            orbitDriver.orbitColor = WaypointManager.RandomColor(Root.MissionSeed);

            orbitRenderer = MapView.MapCamera.gameObject.AddComponent<OrbitRenderer>();
            orbitRenderer.driver = orbitDriver;
            orbitRenderer.drawIcons = OrbitRenderer.DrawIcons.NONE;
            orbitRenderer.drawNodes = false;
            orbitRenderer.orbitColor = WaypointManager.RandomColor(Root.MissionSeed);

            setVisible(true);

            orbitRenderer.celestialBody = targetBody;

            beenSetup = true;
        }
Example #40
0
 private static void SetOrbit(OrbitDriver currentlyEditing, Orbit orbit)
 {
     currentlyEditing.DynamicSetOrbit(orbit);
 }
Example #41
0
 public static void GetSimple(OrbitDriver currentlyEditing, out double altitude, out CelestialBody body)
 {
     const int min = 1000;
     const int defaultAlt = 100000;
     body = currentlyEditing.orbit.referenceBody;
     altitude = currentlyEditing.orbit.semiMajorAxis - body.Radius;
     if (altitude > min)
         return;
     altitude = currentlyEditing.orbit.ApA;
     if (altitude > min)
         return;
     altitude = defaultAlt;
 }
Example #42
0
 private static void HardsetOrbit(OrbitDriver orbitDriver, Orbit newOrbit)
 {
     var orbit = orbitDriver.orbit;
     orbit.inclination = newOrbit.inclination;
     orbit.eccentricity = newOrbit.eccentricity;
     orbit.semiMajorAxis = newOrbit.semiMajorAxis;
     orbit.LAN = newOrbit.LAN;
     orbit.argumentOfPeriapsis = newOrbit.argumentOfPeriapsis;
     orbit.meanAnomalyAtEpoch = newOrbit.meanAnomalyAtEpoch;
     orbit.epoch = newOrbit.epoch;
     orbit.referenceBody = newOrbit.referenceBody;
     orbit.Init();
     orbit.UpdateFromUT(Planetarium.GetUniversalTime());
     if (orbit.referenceBody != newOrbit.referenceBody)
     {
         orbitDriver.OnReferenceBodyChange?.Invoke(newOrbit.referenceBody);
     }
     RateLimitedLogger.Log(HardsetOrbitLogObject,
         $"Orbit \"{orbitDriver.OrbitDriverToString()}\" changed to: inc={orbit.inclination} ecc={orbit.eccentricity} sma={orbit.semiMajorAxis} lan={orbit.LAN} argpe={orbit.argumentOfPeriapsis} mep={orbit.meanAnomalyAtEpoch} epoch={orbit.epoch} refbody={orbit.referenceBody.CbToString()}");
 }
Example #43
0
 public static void Velocity(OrbitDriver currentlyEditing, VelocityChangeDirection direction, double speed)
 {
     Vector3d velocity;
     switch (direction)
     {
         case VelocityChangeDirection.Prograde:
             velocity = currentlyEditing.orbit.getOrbitalVelocityAtUT(Planetarium.GetUniversalTime()).normalized * speed;
             break;
         case VelocityChangeDirection.Normal:
             velocity = currentlyEditing.orbit.GetOrbitNormal().normalized * speed;
             break;
         case VelocityChangeDirection.Radial:
             velocity = Vector3d.Cross(currentlyEditing.orbit.getOrbitalVelocityAtUT(Planetarium.GetUniversalTime()), currentlyEditing.orbit.GetOrbitNormal()).normalized * speed;
             break;
         case VelocityChangeDirection.North:
             var upn = currentlyEditing.orbit.getRelativePositionAtUT(Planetarium.GetUniversalTime()).normalized;
             velocity = Vector3d.Cross(Vector3d.Cross(upn, new Vector3d(0, 0, 1)), upn) * speed;
             break;
         case VelocityChangeDirection.East:
             var upe = currentlyEditing.orbit.getRelativePositionAtUT(Planetarium.GetUniversalTime()).normalized;
             velocity = Vector3d.Cross(new Vector3d(0, 0, 1), upe) * speed;
             break;
         case VelocityChangeDirection.Up:
             velocity = currentlyEditing.orbit.getRelativePositionAtUT(Planetarium.GetUniversalTime()).normalized * speed;
             break;
         default:
             throw new Exception("Unknown VelChangeDir");
     }
     var tempOrbit = currentlyEditing.orbit.Clone();
     tempOrbit.UpdateFromStateVectors(currentlyEditing.orbit.pos, currentlyEditing.orbit.vel + velocity, currentlyEditing.orbit.referenceBody, Planetarium.GetUniversalTime());
     SetOrbit(currentlyEditing, tempOrbit);
 }
Example #44
0
 public static void GetVelocity(OrbitDriver currentlyEditing, out VelocityChangeDirection direction, out double speed)
 {
     direction = VelocityChangeDirection.Prograde;
     speed = 0;
 }
Example #45
0
 public static void Rendezvous(OrbitDriver currentlyEditing, double leadTime, Vessel target)
 {
     SetOrbit(currentlyEditing, CreateOrbit(
         target.orbit.inclination,
         target.orbit.eccentricity,
         target.orbit.semiMajorAxis,
         target.orbit.LAN,
         target.orbit.argumentOfPeriapsis,
         target.orbit.meanAnomalyAtEpoch,
         target.orbit.epoch - leadTime,
         target.orbit.referenceBody));
 }
Example #46
0
        public static void Graphical(OrbitDriver currentlyEditing, double inclination, double eccentricity,
            double periapsis, double longitudeAscendingNode, double argumentOfPeriapsis,
            double meanAnomaly, double epoch)
        {
            var body = currentlyEditing.orbit.referenceBody;
            var soi = body.Soi();
            var ratio = soi / (body.Radius + body.atmosphereDepth + 1000);
            periapsis = Math.Pow(ratio, periapsis) / ratio;
            periapsis *= soi;

            eccentricity *= Math.PI / 2 - 0.001;

            eccentricity = Math.Tan(eccentricity);
            var semimajor = periapsis / (1 - eccentricity);

            if (semimajor < 0)
            {
                meanAnomaly -= 0.5;
                meanAnomaly *= eccentricity * 4; // 4 is arbitrary constant
            }

            inclination *= 360;
            longitudeAscendingNode *= 360;
            argumentOfPeriapsis *= 360;
            meanAnomaly *= 2 * Math.PI;

            SetOrbit(currentlyEditing, CreateOrbit(inclination, eccentricity, semimajor, longitudeAscendingNode, argumentOfPeriapsis, meanAnomaly, epoch, body));
        }
Example #47
0
        private ProtoVessel syncOrbit(KMPVessel kvessel, double fromTick, ProtoVessel protovessel, double LAN)
        {
            KMPClientMain.DebugLog("updating OrbitSnapshot");
            double tick = Planetarium.GetUniversalTime();

            //Update orbit
            Planetarium.SetUniversalTime(fromTick);

            Vector3 orbit_pos = kvessel.translationFromBody;
            Vector3 orbit_vel = kvessel.worldVelocity;

            //Swap the y and z values of the orbital position/velocities
            float temp = orbit_pos.y;
            orbit_pos.y = orbit_pos.z;
            orbit_pos.z = temp;

            temp = orbit_vel.y;
            orbit_vel.y = orbit_vel.z;
            orbit_vel.z = temp;

            OrbitDriver orbitDriver = new OrbitDriver();
            orbitDriver.orbit.UpdateFromStateVectors(orbit_pos, orbit_vel, kvessel.mainBody, fromTick);
            Orbit newOrbit = orbitDriver.orbit;
            newOrbit.LAN = LAN;

            Vessel victim = FlightGlobals.ActiveVessel;
            OrbitDriver oldDriver = victim.orbitDriver;
            victim.orbitDriver = orbitDriver;
            victim.patchedConicSolver.obtDriver = orbitDriver;
            victim.orbitDriver.UpdateOrbit();
            victim.patchedConicSolver.Update();

            newOrbit = victim.patchedConicSolver.orbit;
            if (newOrbit.referenceBody == null) newOrbit.referenceBody = FlightGlobals.Bodies.Find(b => b.name == "Sun");
            if (newOrbit.EndUT > 0)
            {
                double lastEndUT =  newOrbit.EndUT;
                while (newOrbit.EndUT > 0 && newOrbit.EndUT < tick && newOrbit.EndUT > lastEndUT && newOrbit.nextPatch != null)
                {
                    KMPClientMain.DebugLog("orbit EndUT < target: " + newOrbit.EndUT + " vs " + tick);
                    lastEndUT =  newOrbit.EndUT;
                    newOrbit = newOrbit.nextPatch;
                    if (newOrbit.referenceBody == null) newOrbit.referenceBody = FlightGlobals.Bodies.Find(b => b.name == "Sun");
                    KMPClientMain.DebugLog("updated to next patch");
                }
            }

            victim.patchedConicSolver.obtDriver = oldDriver;
            victim.orbitDriver = oldDriver;

            Planetarium.SetUniversalTime(tick);
            protovessel.orbitSnapShot = new OrbitSnapshot(newOrbit);
            KMPClientMain.DebugLog("OrbitSnapshot updated");
            return protovessel;
        }
        private void setup()
        {
            generator = new System.Random(this.Root.MissionSeed);

            iconWaypoints = new List<Waypoint>();

            for (int x = 0; x < 4; x++)
            {
                iconWaypoints.Add(new Waypoint());
                iconWaypoints[iconWaypoints.Count - 1].celestialName = targetBody.GetName();
                iconWaypoints[iconWaypoints.Count - 1].textureName = "orbit";
                iconWaypoints[iconWaypoints.Count - 1].isOrbital = true;
                iconWaypoints[iconWaypoints.Count - 1].seed = Root.MissionSeed;
                WaypointManager.AddWaypoint(iconWaypoints[iconWaypoints.Count - 1]);
            }

            orbitDriver = new OrbitDriver();

            //Start with periapsis at a safe distance and a random eccentricity, weighted towards the bottom.
            //Derive SMA from eccentricity and desired periapsis.
            orbitDriver.orbit = new Orbit();

            switch (this.orbitType)
            {
                case OrbitType.POLAR:
                    setRandomOrbit(difficultyFactor, false, true);
                    break;
                case OrbitType.EQUATORIAL:
                    setRandomOrbit(difficultyFactor, true, false);
                    break;
                case OrbitType.STATIONARY:
                    setSynchronousOrbit(difficultyFactor, true, 0.0);
                    break;
                case OrbitType.SYNCHRONOUS:
                    setSynchronousOrbit(difficultyFactor, false, generator.NextDouble()*(difficultyFactor/2));
                    break;
                case OrbitType.MOLNIYA:
                    setMolniyaOrbit();
                    break;
                case OrbitType.TUNDRA:
                    setTundraOrbit();
                    break;
                default:
                    setRandomOrbit(difficultyFactor, false, false);
                    break;
            }

            orbitDriver.orbitColor = WaypointManager.RandomColor(Root.MissionSeed);

            orbitRenderer = MapView.MapCamera.gameObject.AddComponent<OrbitRenderer>();
            orbitRenderer.driver = orbitDriver;
            orbitRenderer.drawIcons = OrbitRenderer.DrawIcons.NONE;
            orbitRenderer.drawNodes = false;
            orbitRenderer.orbitColor = WaypointManager.RandomColor(Root.MissionSeed);

            setVisible(true);

            orbitRenderer.celestialBody = targetBody;

            beenSetup = true;
        }