/// <summary> /// https://en.wikipedia.org/wiki/Sidereal_time#Sidereal_days_compared_to_solar_days_on_other_planets /// </summary> private static double solarDayLength(CelestialBody b) { if (b.rotationPeriod == b.GetOrbit().period) { // Tidally locked, don't divide by zero return(0); } else { return(b.rotationPeriod / (1 - (b.rotationPeriod / b.GetOrbit().period))); } }
private static Vector3d GetHeadingVectorToTarget(Vessel vessel, double UT, string persistentVesselTargetBodyName, string persistentVesselTargetId) { Guid persistentVesselTargetGuid = new Guid(persistentVesselTargetId); Orbit targetOrbit = null; if (persistentVesselTargetGuid != Guid.Empty) { Vessel targetVessel = FlightGlobals.Vessels.SingleOrDefault(m => m.id == persistentVesselTargetGuid); if (targetVessel != null) { targetOrbit = targetVessel.GetOrbit(); } } else if (!string.IsNullOrEmpty(persistentVesselTargetBodyName)) { CelestialBody body = FlightGlobals.Bodies.SingleOrDefault(m => m.bodyName == persistentVesselTargetBodyName); if (body != null) { targetOrbit = body.GetOrbit(); } } return(targetOrbit != null?targetOrbit.getPositionAtUT(UT) - vessel.orbit.getPositionAtUT(UT) : Vector3d.zero); }
public json getCelestialState(CelestialBody celestial) { Debug.Log ("Collecting: " + celestial.GetName ()); json buffer = new json (); buffer.Add ("type", "celestial"); buffer.Add ("name", celestial.GetName ()); buffer.Add ("ref", celestial.referenceBody.GetName ()); if (celestial.orbitDriver != null) { Orbit orbit = celestial.GetOrbit (); Vector3d r = orbit.getRelativePositionAtUT (0); Vector3d v = orbit.getOrbitalVelocityAtUT (0); List<double> RV = new List<double> (); // Swap coordinate system RV.Add (r.y); RV.Add (r.x); RV.Add (r.z); RV.Add (v.y); RV.Add (v.x); RV.Add (v.z); buffer.Add ("rv", RV); } else { List<double> RV = new List<double> (); RV.Add (0.0); RV.Add (0.0); RV.Add (0.0); RV.Add (0.0); RV.Add (0.0); RV.Add (0.0); buffer.Add ("rv", RV); } buffer.Add ("mu", celestial.gravParameter); buffer.Add ("radius", celestial.Radius); buffer.Add ("soi", celestial.sphereOfInfluence); if (celestial.atmosphere == true) { buffer.Add ("alt_atm", celestial.maxAtmosphereAltitude); } else { buffer.Add ("alt_atm", 0); } // Angular velocity data buffer.Add ("ang_v", celestial.zUpAngularVelocity.magnitude); buffer.Add ("initial_rotation", celestial.initialRotation); buffer.Add ("rotation_angle", celestial.rotationAngle); buffer.Add ("rotation_t0", Planetarium.GetUniversalTime ()); return buffer; }
public static void MovePlanet(PlanetDefinition planet, string targetSystem) { if (StarSystem.CBDict.ContainsKey(planet.Name)) { CelestialBody planetCB = StarSystem.CBDict[planet.Name]; string parent_name; try { parent_name = planetCB.GetOrbit().referenceBody.GetName(); if (parent_name.StartsWith("Black")) //DANGER: HACK { parent_name = "Sun"; } } catch (Exception) { parent_name = "Sun"; } Debug.Log("moving Planet " + planet.Name + " from: " + parent_name + " to " + targetSystem); if (StarSystem.CBDict[parent_name].orbitingBodies.Contains(planetCB)) { if (StarSystem.CBDict.ContainsKey(targetSystem)) { StarSystem.CBDict[targetSystem].orbitingBodies.Add(planetCB); StarSystem.CBDict[parent_name].orbitingBodies.Remove(planetCB); if (planet.orbit != null) // we have a new orbit specification for this dude. { planetCB.orbitDriver.orbit = planet.orbit.getOrbit(StarSystem.CBDict[targetSystem]); } planetCB.orbitDriver.referenceBody = StarSystem.CBDict[targetSystem]; planetCB.orbitDriver.UpdateOrbit(); StarSystem.CBDict[parent_name].CBUpdate(); StarSystem.CBDict[targetSystem].CBUpdate(); Debug.Log(planet.Name + " moved to " + targetSystem); } else { Debug.Log("Could not find CelestialBody " + targetSystem); } } else { Debug.Log("Couldn't find " + planet.Name + " in " + parent_name + "'s orbit. Was it moved already?"); } } else { Debug.Log("Planet " + planet.Name + " does not exist!"); } }
private int orbitFactor(CelestialBody celestialBody) { if (celestialBody.isHomeWorld) { return(-1); } if (celestialBody.GetName() == "Sun") { return(0); } return(orbitFactor(celestialBody.GetOrbit().referenceBody) + 1); }
private static double CalculateGravitation(CelestialBody body, double altitude) { double retValue = body.gravParameter / (altitude * altitude); var orbit = body.GetOrbit(); if (orbit != null) { if (orbit.referenceBody != null) { retValue += CalculateGravitation(orbit.referenceBody, orbit.altitude + orbit.referenceBody.Radius); } } return(retValue); }
public static Vector3d GetWorldVelocity(this CelestialBody body) { if (body != body.referenceBody) { // Body orbits something return(body.GetOrbit().GetVel()); } else { // Body does not orbit anything // Get a body that orbits the sun var orbitingBody = FlightGlobals.Bodies.Find(b => b.name != "Sun" && b.GetOrbit().referenceBody == body); var orbit = orbitingBody.GetOrbit(); // Compute the velocity of the sun in world space from this body // Can't be done for from the sun object as it has no orbit object return(orbit.GetVel() - orbit.GetRelativeVel()); } }
/// <summary> /// Gets the orbit of this body around the sun. /// </summary> /// <returns>If the Sun, returns <c>null</c>. If a planet, returns its orbit. If a moon, /// returns its planet's orbit.</returns> /// <param name="body">The object whose motion around the Sun is desired.</param> private static Orbit getHeliocentricOrbit(CelestialBody body) { if (body.GetOrbitDriver() == null) { return(null); } else { Orbit orbit = body.GetOrbit(); Orbit parentOrbit = getHeliocentricOrbit(orbit.referenceBody); if (parentOrbit == null) { return(orbit); } else { return(parentOrbit); } } }
// Update the menu body void UpdateMenu() { // Grab the main body CelestialBody planetCB = PSystemManager.Instance.localBodies.Find(b => b.bodyName == Templates.menuBody); PSystemBody planet = Utility.FindBody(PSystemManager.Instance.systemPrefab.rootBody, Templates.menuBody); if (planetCB == null || planet == null) { planet = Utility.FindHomeBody(PSystemManager.Instance.systemPrefab.rootBody); planetCB = PSystemManager.Instance.localBodies.Find(b => b.isHomeWorld); } if (planet == null || planetCB == null) { Debug.LogError("[Kopernicus]: Could not find homeworld!"); return; } // Get the MainMenu-Logic MainMenu main = FindObjectOfType <MainMenu>(); if (main == null) { Debug.LogError("[Kopernicus]: No main menu object!"); return; } MainMenuEnvLogic logic = main.envLogic; // Set it to Space, because the Mun-Area won't work with sth else than Mun if (logic.areas.Length < 2) { Debug.LogError("[Kopernicus]: Not enough bodies"); return; } logic.areas[0].SetActive(false); logic.areas[1].SetActive(true); // Get our active Space GameObject space = logic.areas[1]; // Deactivate Kerbins Transform Transform kerbin = space.transform.Find("Kerbin"); if (kerbin == null) { Debug.LogError("[Kopernicus]: No Kerbin transform!"); return; } kerbin.gameObject.SetActive(false); // Deactivate Muns Transform Transform mun = space.transform.Find("MunPivot"); if (mun == null) { Debug.LogError("[Kopernicus]: No MunPivot transform!"); return; } mun.gameObject.SetActive(false); // Clone the scaledVersion and attach it to the Scene GameObject menuPlanet = Instantiate(planet.scaledVersion) as GameObject; menuPlanet.transform.parent = space.transform; // Destroy stuff DestroyImmediate(menuPlanet.GetComponent <ScaledSpaceFader>()); DestroyImmediate(menuPlanet.GetComponent <SphereCollider>()); DestroyImmediate(menuPlanet.GetComponentInChildren <AtmosphereFromGround>()); DestroyImmediate(menuPlanet.GetComponent <MaterialSetDirection>()); // That sounds funny Rotato planetRotato = menuPlanet.AddComponent <Rotato>(); Rotato planetRefRotato = kerbin.GetComponent <Rotato>(); planetRotato.speed = (planetRefRotato.speed / 9284.50070356553f) * (float)planetCB.orbitDriver.orbit.orbitalSpeed; // calc.exe for the win // Scale the body menuPlanet.transform.localScale = kerbin.localScale; menuPlanet.transform.localPosition = kerbin.localPosition; menuPlanet.transform.position = kerbin.position; // And set it to layer 0 menuPlanet.layer = 0; // Patch the material, because Mods like TextureReplacer run post spawn, and we'd overwrite their changes menuPlanet.GetComponent <Renderer>().sharedMaterial = planetCB.scaledBody.GetComponent <Renderer>().sharedMaterial; // Copy EVE 7.4 clouds / Rings for (int i = 0; i < planetCB.scaledBody.transform.childCount; i++) { // Just clone everything Transform t = planetCB.scaledBody.transform.GetChild(i); GameObject newT = Instantiate(t.gameObject) as GameObject; newT.transform.parent = menuPlanet.transform; newT.layer = 0; newT.transform.localPosition = Vector3.zero; newT.transform.localRotation = Quaternion.identity; newT.transform.localScale = (float)(1008 / planetCB.Radius) * Vector3.one; } // And now, create the moons foreach (PSystemBody moon in planet.children) { // Grab the CeletialBody of the moon CelestialBody moonCB = PSystemManager.Instance.localBodies.Find(b => b.GetTransform().name == moon.name); // Create the Rotation-Transforms GameObject menuMoonPivot = new GameObject(moon.name + " Pivot"); menuMoonPivot.gameObject.layer = 0; menuMoonPivot.transform.position = menuPlanet.transform.position; // Still funny... Rotato munRotato = menuMoonPivot.AddComponent <Rotato>(); Rotato refRotato = mun.GetComponent <Rotato>(); munRotato.speed = (refRotato.speed / 542.494239600754f) * (float)moonCB.GetOrbit().getOrbitalSpeedAtDistance(moonCB.GetOrbit().semiMajorAxis); // Clone the scaledVersion and attach it to the pivot GameObject menuMoon = Instantiate(moon.scaledVersion) as GameObject; menuMoon.transform.parent = menuMoonPivot.transform; // Move and scale the menuMoon correctly menuMoon.transform.localPosition = new Vector3(-5000f * (float)(moonCB.GetOrbit().semiMajorAxis / 12000000.0), 0f, 0f); menuMoon.transform.localScale *= 7f; // Destroy stuff DestroyImmediate(menuMoon.GetComponent <ScaledSpaceFader>()); DestroyImmediate(menuMoon.GetComponent <SphereCollider>()); DestroyImmediate(menuMoon.GetComponentInChildren <AtmosphereFromGround>()); DestroyImmediate(menuMoon.GetComponent <MaterialSetDirection>()); // More Rotato Rotato moonRotato = menuMoon.AddComponent <Rotato>(); moonRotato.speed = -0.005f / (float)(moonCB.rotationPeriod / 400.0); // Apply orbital stuff menuMoon.transform.Rotate(0f, (float)moonCB.orbitDriver.orbit.LAN, 0f); menuMoon.transform.Rotate(0f, 0f, (float)moonCB.orbitDriver.orbit.inclination); menuMoon.transform.Rotate(0f, (float)moonCB.orbitDriver.orbit.argumentOfPeriapsis, 0f); // And set the layer to 0 menuMoon.layer = 0; // Patch the material, because Mods like TextureReplacer run post spawn, and we'd overwrite their changes menuMoon.GetComponent <Renderer>().sharedMaterial = moonCB.scaledBody.GetComponent <Renderer>().sharedMaterial; // Copy EVE 7.4 clouds / Rings for (int i = 0; i < moonCB.scaledBody.transform.childCount; i++) { Transform t = moonCB.scaledBody.transform.GetChild(i); GameObject newT = Instantiate(t.gameObject) as GameObject; newT.transform.parent = menuMoon.transform; newT.layer = 0; newT.transform.localPosition = Vector3.zero; newT.transform.localRotation = Quaternion.identity; newT.transform.localScale = (float)(1008 / moonCB.Radius) * Vector3.one; } } }
/// <summary> /// Returns the desired property of a known celestial body. /// </summary> /// /// <param name="planet">The exact, case-sensitive name of the celestial body. Assumes all /// loaded celestial bodies have unique names.</param> /// <param name="property">The short name of the property to recover. Must be one /// of ("rad", "soi", "sma", "per", "apo", "ecc", "inc", "ape", "lan", "mna0", "mnl0", /// "prot", "psun", "porb", "vesc", "vorb", "vmin", or "vmax"). /// The only properties supported for Sun are "rad", "soi", "prot", and "vesc".</param> /// <returns>The value of <c>property</c> appropriate for <c>planet</c>. Distances are given /// in meters, angles are given in degrees.</returns> /// /// <exception cref="ArgumentException">Thrown if no planet named <c>name</c> exists, or if /// <c>property</c> does not have one of the allowed values. The program state shapp remain /// unchanged in the event of an exception.</exception> protected static double getPlanetProperty(string planet, string property) { CelestialBody body = AsteroidManager.getPlanetByName(planet); switch (property.ToLower()) { case "rad": return(body.Radius); case "soi": return(body.sphereOfInfluence); case "prot": return(body.rotates ? body.rotationPeriod : double.PositiveInfinity); case "psol": if (body.solarRotationPeriod) { return(body.solarDayLength); } else { throw new ArgumentException( Localizer.Format("#autoLOC_CustomAsteroids_ErrorPlanetNoDay", planet), nameof(property)); } case "vesc": return(Math.Sqrt(2 * body.gravParameter / body.Radius)); default: if (body.GetOrbitDriver() == null) { throw new ArgumentException( Localizer.Format("#autoLOC_CustomAsteroids_ErrorPlanetNoOrbit", planet), nameof(planet)); } Orbit orbit = body.GetOrbit(); switch (property.ToLower()) { case "sma": return(orbit.semiMajorAxis); case "per": return(orbit.PeR); case "apo": return(orbit.ApR); case "ecc": return(orbit.eccentricity); case "inc": return(orbit.inclination); case "ape": return(orbit.argumentOfPeriapsis); case "lpe": // Ignore inclination: http://en.wikipedia.org/wiki/Longitude_of_periapsis return(orbit.LAN + orbit.argumentOfPeriapsis); case "lan": return(orbit.LAN); case "mna0": return(meanAnomalyAtUT(orbit, 0.0) * 180.0 / Math.PI); case "mnl0": return(anomalyToLong(meanAnomalyAtUT(orbit, 0.0) * 180.0 / Math.PI, orbit.inclination, orbit.argumentOfPeriapsis, orbit.LAN)); case "porb": return(orbit.period); case "vorb": // Need circumference of an ellipse; closed form does not exist double sum = orbit.semiMajorAxis + orbit.semiMinorAxis; double diff = orbit.semiMajorAxis - orbit.semiMinorAxis; double h = diff * diff / (sum * sum); double correction = 1.0; for (int n = 1; n < 10; n++) { double coeff = Util.DoubleFactorial(2 * n - 1) / (Math.Pow(2, n) * Util.Factorial(n)) / (2 * n - 1); correction += coeff * coeff * Math.Pow(h, n); } return(Math.PI * sum * correction / orbit.period); case "vmin": return(orbit.getOrbitalSpeedAtDistance(orbit.ApR)); case "vmax": return(orbit.getOrbitalSpeedAtDistance(orbit.PeR)); default: throw new ArgumentException( Localizer.Format("#autoLOC_CustomAsteroids_ErrorPlanetBadProperty", property), nameof(property)); } } }