From 749e776c9869fd21e23885840c82d6c10a6c75dd Mon Sep 17 00:00:00 2001 From: "Nick J. Connors" Date: Sat, 25 Dec 2021 02:26:09 -0500 Subject: [PATCH] Better orbit lines + more binaries code --- NewHorizons/Builder/General/BaseBuilder.cs | 48 ++++---- .../Builder/General/DetectorBuilder.cs | 109 +++++++++++++----- .../Builder/Orbital/OrbitlineBuilder.cs | 44 +++---- NewHorizons/External/OrbitModule.cs | 4 +- NewHorizons/Main.cs | 35 +----- NewHorizons/NewHorizons.csproj | 2 + NewHorizons/OrbitalPhysics/KeplerElements.cs | 50 ++++++-- NewHorizons/OrbitalPhysics/OrbitalHelper.cs | 1 - .../ParameterizedAstroObject.cs | 13 +++ .../OrbitalPhysics/TrackingOrbitLine.cs | 101 ++++++++++++++++ 10 files changed, 284 insertions(+), 123 deletions(-) create mode 100644 NewHorizons/OrbitalPhysics/ParameterizedAstroObject.cs create mode 100644 NewHorizons/OrbitalPhysics/TrackingOrbitLine.cs diff --git a/NewHorizons/Builder/General/BaseBuilder.cs b/NewHorizons/Builder/General/BaseBuilder.cs index 47889823..90fae0b0 100644 --- a/NewHorizons/Builder/General/BaseBuilder.cs +++ b/NewHorizons/Builder/General/BaseBuilder.cs @@ -12,37 +12,39 @@ namespace NewHorizons.Builder.General { public static Tuple Make(GameObject body, AstroObject primaryBody, Vector3 positionVector, IPlanetConfig config) { - Rigidbody RB = body.AddComponent(); - RB.mass = 10000; - RB.drag = 0f; - RB.angularDrag = 0f; - RB.useGravity = false; - RB.isKinematic = true; - RB.interpolation = RigidbodyInterpolation.None; - RB.collisionDetectionMode = CollisionDetectionMode.Discrete; + Rigidbody rigidBody = body.AddComponent(); + rigidBody.mass = 10000; + rigidBody.drag = 0f; + rigidBody.angularDrag = 0f; + rigidBody.useGravity = false; + rigidBody.isKinematic = true; + rigidBody.interpolation = RigidbodyInterpolation.None; + rigidBody.collisionDetectionMode = CollisionDetectionMode.Discrete; - KinematicRigidbody KRB = body.AddComponent(); - KRB.centerOfMass = Vector3.zero; + KinematicRigidbody kinematicRigidBody = body.AddComponent(); + kinematicRigidBody.centerOfMass = Vector3.zero; - OWRigidbody OWRB = body.AddComponent(); - OWRB.SetValue("_kinematicSimulation", true); - OWRB.SetValue("_autoGenerateCenterOfMass", true); - OWRB.SetIsTargetable(true); - OWRB.SetValue("_maintainOriginalCenterOfMass", true); - OWRB.SetValue("_rigidbody", RB); - OWRB.SetValue("_kinematicRigidbody", KRB); + OWRigidbody owRigidBody = body.AddComponent(); + owRigidBody.SetValue("_kinematicSimulation", true); + owRigidBody.SetValue("_autoGenerateCenterOfMass", true); + owRigidBody.SetIsTargetable(true); + owRigidBody.SetValue("_maintainOriginalCenterOfMass", true); + owRigidBody.SetValue("_rigidbody", rigidBody); + owRigidBody.SetValue("_kinematicRigidbody", kinematicRigidBody); - AstroObject AO = body.AddComponent(); + ParameterizedAstroObject astroObject = body.AddComponent(); + + if (config.Orbit != null) astroObject.keplerElements = KeplerElements.FromOrbitModule(config.Orbit); var type = AstroObject.Type.Planet; if (config.Orbit.IsMoon) type = AstroObject.Type.Moon; else if (config.Base.HasCometTail) type = AstroObject.Type.Comet; else if (config.Star != null) type = AstroObject.Type.Star; else if (config.FocalPoint != null) type = AstroObject.Type.None; - AO.SetValue("_type", type); - AO.SetValue("_name", AstroObject.Name.CustomString); - AO.SetValue("_customName", config.Name); - AO.SetValue("_primaryBody", primaryBody); + astroObject.SetValue("_type", type); + astroObject.SetValue("_name", AstroObject.Name.CustomString); + astroObject.SetValue("_customName", config.Name); + astroObject.SetValue("_primaryBody", primaryBody); if (config.Orbit.IsTidallyLocked) { @@ -51,7 +53,7 @@ namespace NewHorizons.Builder.General alignment.SetValue("_usePhysicsToRotate", true); } - return new Tuple(AO, OWRB); + return new Tuple(astroObject, owRigidBody); } } } diff --git a/NewHorizons/Builder/General/DetectorBuilder.cs b/NewHorizons/Builder/General/DetectorBuilder.cs index e1a9ab5e..15d2b178 100644 --- a/NewHorizons/Builder/General/DetectorBuilder.cs +++ b/NewHorizons/Builder/General/DetectorBuilder.cs @@ -79,26 +79,38 @@ namespace NewHorizons.Builder.General var planets = point.Planets; - // Binaries have to use inverse square gravity so overwrite it now + // Binaries have to use the same gravity exponent var primaryGV = primary.GetGravityVolume(); - //primaryGV.SetValue("_falloffType", primaryGV.GetType().GetNestedType("FalloffType", BindingFlags.NonPublic).GetField("inverseSquared").GetValue(primaryGV)); - //primaryGV.SetValue("_falloffExponent", 2); - var secondaryGV = secondary.GetGravityVolume(); - //secondaryGV.SetValue("_falloffType", secondaryGV.GetType().GetNestedType("FalloffType", BindingFlags.NonPublic).GetField("inverseSquared").GetValue(secondaryGV)); - //secondaryGV.SetValue("_falloffExponent", 2); - + + if (primaryGV.GetFalloffType() != secondaryGV.GetFalloffType()) + { + Logger.LogError($"Binaries must have the same gravity falloff! {primaryGV.GetFalloffType()} != {secondaryGV.GetFalloffType()}"); + return; + } + + // Have to use fall off type rn instead of exponent since it the exponent doesnt update until the Awake method I think + var exponent = 0f; + if (primaryGV.GetFalloffType() == OrbitalHelper.FalloffType.linear) exponent = 1f; + if (primaryGV.GetFalloffType() == OrbitalHelper.FalloffType.inverseSquared) exponent = 2f; // Very specific distance between them Vector3 separation = primary.transform.position - secondary.transform.position; var Gm1 = primaryGV.GetStandardGravitationalParameter(); var Gm2 = secondaryGV.GetStandardGravitationalParameter(); + + // One of the two is zero if it just loaded + if (Gm1 == 0) Gm1 = GravityVolume.GRAVITATIONAL_CONSTANT * primaryGV.GetValue("_surfaceAcceleration") * Mathf.Pow(primaryGV.GetValue("_upperSurfaceRadius"), exponent) / 0.001f; + if (Gm2 == 0) Gm2 = GravityVolume.GRAVITATIONAL_CONSTANT * secondaryGV.GetValue("_surfaceAcceleration") * Mathf.Pow(secondaryGV.GetValue("_upperSurfaceRadius"), exponent) / 0.001f; + float r1 = separation.magnitude * Gm2 / (Gm1 + Gm2); float r2 = separation.magnitude * Gm1 / (Gm1 + Gm2); primary.transform.position = point.transform.position + r1 * separation.normalized; secondary.transform.position = point.transform.position - r2 * separation.normalized; + Logger.Log($"{primary.transform.position}, {secondary.transform.position}, {point.transform.position}"); + // Set detectable fields primaryCFD.SetValue("_detectableFields", new ForceVolume[] { secondaryGV }); primaryCFD.SetValue("_inheritDetector", point.GetAttachedOWRigidbody().GetAttachedForceDetector()); @@ -109,39 +121,74 @@ namespace NewHorizons.Builder.General secondaryCFD.SetValue("_inheritDetector", point.GetAttachedOWRigidbody().GetAttachedForceDetector()); secondaryCFD.SetValue("_activeInheritedDetector", point.GetAttachedOWRigidbody().GetAttachedForceDetector()); secondaryCFD.SetValue("_inheritElement0", false); - + // Update speeds var direction = Vector3.Cross(separation, Vector3.up).normalized; - var m1 = primaryRB.GetMass(); - var m2 = secondaryRB.GetMass(); + var m1 = Gm1 / GravityVolume.GRAVITATIONAL_CONSTANT; + var m2 = Gm2 / GravityVolume.GRAVITATIONAL_CONSTANT; var reducedMass = m1 * m2 / (m1 + m2); + var totalMass = m1 + m2; + + // They must have the same eccentricity + var parameterizedAstroObject = primary.GetComponent(); + var parameterizedAstroObject2 = secondary.GetComponent(); + + float ecc = 0; + float i = 0; + float l = 0; + float p = 0; + if (parameterizedAstroObject != null) + { + ecc = parameterizedAstroObject.keplerElements.Eccentricity; + i = parameterizedAstroObject.keplerElements.Inclination; + l = parameterizedAstroObject.keplerElements.LongitudeOfAscendingNode; + p = parameterizedAstroObject.keplerElements.ArgumentOfPeriapsis; + } + var r = separation.magnitude; - float v1 = OrbitalHelper.GetOrbitalVelocity(r, new Gravity(secondaryGV.GetFalloffExponent(), reducedMass), KeplerElements.FromTrueAnomaly(0.5f, r, 0, 0, 0, 0)); - float v2 = OrbitalHelper.GetOrbitalVelocity(r, new Gravity(primaryGV.GetFalloffExponent(), reducedMass), KeplerElements.FromTrueAnomaly(0.5f, r, 0, 0, 0, 180)); - Logger.Log($"Speed: {v1} {v2}"); + // Start them off at their periapsis + var primaryKeplerElements = KeplerElements.FromTrueAnomaly(ecc, r1 / (1f - ecc), i, l, p, 0); + var secondaryKeplerElements = KeplerElements.FromTrueAnomaly(ecc, r2 / (1f - ecc), i, l, p, 180); - primaryRB.UpdateCenterOfMass(); - primaryRB.AddVelocityChange(direction * v1); - secondaryRB.UpdateCenterOfMass(); - secondaryRB.AddVelocityChange(direction * -v2); + // Maybe we'll need these orbital parameters later + if(parameterizedAstroObject != null) parameterizedAstroObject.keplerElements = primaryKeplerElements; + if(parameterizedAstroObject2 != null) parameterizedAstroObject2.keplerElements = secondaryKeplerElements; + // Finally we update the speeds + var b = r * Mathf.Sqrt(1 - ecc * ecc); + float v = Mathf.Sqrt(GravityVolume.GRAVITATIONAL_CONSTANT * totalMass * (1 - ecc * ecc) / Mathf.Pow(r, exponent - 1)); + var v2 = v / (1f + (m2 / m2)); + var v1 = v - v2; + // Rotate around argument of periapsis + var periapsisRotation = Quaternion.AngleAxis(p, Vector3.up); + var ascendingAxis = Quaternion.AngleAxis(p + l, Vector3.up) * Vector3.right; + var longitudeRotation = Quaternion.AngleAxis(i, ascendingAxis); - /* - //Hacky but whatever - var primaryInitialMotion = primary.gameObject.GetComponent(); - if(primaryInitialMotion.GetValue("_isInitVelocityDirty")) - primaryInitialMotion.SetValue("_cachedInitVelocity", OWPhysics.CalculateOrbitVelocity(secondaryRB, primaryRB, 0f)); - else - primaryInitialMotion.SetPrimaryBody(secondaryRB); - - var secondaryInitialMotion = primary.gameObject.GetComponent(); - if (secondaryInitialMotion.GetValue("_isInitVelocityDirty")) - secondaryInitialMotion.SetValue("_cachedInitVelocity", OWPhysics.CalculateOrbitVelocity(primaryRB, secondaryRB, 0f)); - else - secondaryInitialMotion.SetPrimaryBody(primaryRB); - */ + //direction = periapsisRotation * longitudeRotation * direction; + + //Do this next tick for... reasons? + Main.Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => primaryRB.SetVelocity(direction * v1)); + Main.Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => secondaryRB.SetVelocity(direction * -v2)); + + // If they have tracking orbits set the period + var period = 2 * Mathf.PI * Mathf.Sqrt(Mathf.Pow(r, exponent + 1) / (GravityVolume.GRAVITATIONAL_CONSTANT * totalMass)); + + // Only one of these won't be null, the other one gets done next tick + var trackingOrbitPrimary = primary.GetComponentInChildren(); + if (trackingOrbitPrimary != null) + { + trackingOrbitPrimary.TrailTime = period; + Main.Instance.ModHelper.Events.Unity.FireInNUpdates(() => trackingOrbitPrimary.ResetLineVertices(), 15); + } + + var trackingOrbitSecondary = secondary.GetComponentInChildren(); + if (trackingOrbitSecondary != null) + { + trackingOrbitSecondary.TrailTime = period; + Main.Instance.ModHelper.Events.Unity.FireInNUpdates(() => trackingOrbitSecondary.ResetLineVertices(), 15); + } } } } diff --git a/NewHorizons/Builder/Orbital/OrbitlineBuilder.cs b/NewHorizons/Builder/Orbital/OrbitlineBuilder.cs index b163e4c0..2b48f347 100644 --- a/NewHorizons/Builder/Orbital/OrbitlineBuilder.cs +++ b/NewHorizons/Builder/Orbital/OrbitlineBuilder.cs @@ -9,7 +9,7 @@ namespace NewHorizons.Builder.Orbital { static class OrbitlineBuilder { - public static void Make(GameObject body, AstroObject astroobject, bool isMoon, OrbitModule orbit) + public static void Make(GameObject body, AstroObject astroobject, bool isMoon, IPlanetConfig config) { GameObject orbitGO = new GameObject("Orbit"); orbitGO.transform.parent = body.transform; @@ -21,40 +21,32 @@ namespace NewHorizons.Builder.Orbital lineRenderer.useWorldSpace = false; lineRenderer.loop = false; - if(orbit.Eccentricity == 0) + OrbitLine orbitLine; + if (config.Orbit.Eccentricity == 0) { - OrbitLine orbitLine = orbitGO.AddComponent(); - orbitLine.SetValue("_astroObject", astroobject); - orbitLine.SetValue("_fade", isMoon); - orbitLine.SetValue("_lineWidth", 0.3f); - typeof(OrbitLine).GetMethod("InitializeLineRenderer", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(orbitLine, new object[] { }); + orbitLine = orbitGO.AddComponent(); } else { - OrbitLine orbitLine = orbitGO.AddComponent(); - orbitLine.SetValue("_astroObject", astroobject); - orbitLine.SetValue("_fade", isMoon); - orbitLine.SetValue("_lineWidth", 0.3f); - typeof(OrbitLine).GetMethod("InitializeLineRenderer", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(orbitLine, new object[] { }); + orbitLine = orbitGO.AddComponent(); } - /* - ParameterizedOrbitLine orbitLine = orbitGO.AddComponent(); - + var color = Color.white; + if (config.Orbit.Tint != null) color = config.Orbit.Tint.ToColor32(); + else if (config.Star != null) color = config.Star.Tint.ToColor32(); + else if (config.Atmosphere != null && config.Atmosphere.CloudTint != null) color = config.Atmosphere.CloudTint.ToColor32(); + else if (config.Base.BlackHoleSize != 0) color = new Color(1f, 0f, 1f); + else if (config.Base.WaterSize != 0) color = Color.blue; + else if (config.Base.LavaSize != 0) color = Color.red; + orbitLine.SetValue("_color", color); + orbitLine.SetValue("_astroObject", astroobject); orbitLine.SetValue("_fade", isMoon); - orbitLine.SetValue("_lineWidth", 0.5f); + orbitLine.SetValue("_lineWidth", 2f); - orbitLine.SetOrbitalParameters( - orbit.Eccentricity, - orbit.SemiMajorAxis, - orbit.Inclination, - orbit.LongitudeOfAscendingNode, - orbit.ArgumentOfPeriapsis, - orbit.TrueAnomaly); - - typeof(OrbitLine).GetMethod("InitializeLineRenderer", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(orbitLine, new object[] { }); - */ + Main.Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => + typeof(OrbitLine).GetMethod("InitializeLineRenderer", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(orbitLine, new object[] { }) + ); } } } diff --git a/NewHorizons/External/OrbitModule.cs b/NewHorizons/External/OrbitModule.cs index 39508ab8..8f9aca8f 100644 --- a/NewHorizons/External/OrbitModule.cs +++ b/NewHorizons/External/OrbitModule.cs @@ -1,4 +1,5 @@ -using System; +using NewHorizons.Utility; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -21,5 +22,6 @@ namespace NewHorizons.External public bool IsTidallyLocked { get; set; } public bool ShowOrbitLine { get; set; } = true; public bool IsStatic { get; set; } + public MColor32 Tint { get; set; } } } diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index c974e9b0..5830d693 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -56,7 +56,7 @@ namespace NewHorizons } } - public void Destroy() + public void OnDestroy() { Logger.Log($"Destroying NewHorizons"); SceneManager.sceneLoaded -= OnSceneLoaded; @@ -212,7 +212,7 @@ namespace NewHorizons } } - Logger.Log("Begin generation sequence of [" + body.Config.Name + "] ...", Logger.LogType.Log); + Logger.Log($"Begin generation sequence of [{body.Config.Name}]"); var go = new GameObject(body.Config.Name.Replace(" ", "").Replace("'", "") + "_Body"); go.SetActive(false); @@ -222,31 +222,14 @@ namespace NewHorizons var atmoSize = body.Config.Atmosphere != null ? body.Config.Atmosphere.Size : 0f; float sphereOfInfluence = Mathf.Max(atmoSize, body.Config.Base.SurfaceSize * 2f); - // Get initial position but set it at the end - var falloffType = primaryBody.GetGravityVolume().GetFalloffType(); - - /* - var positionVector = OrbitalHelper.CartesianStateVectorsFromTrueAnomaly( - 0f, - body.Config.Orbit.Eccentricity, - body.Config.Orbit.SemiMajorAxis, - body.Config.Orbit.Inclination, - body.Config.Orbit.LongitudeOfAscendingNode, - body.Config.Orbit.ArgumentOfPeriapsis, - body.Config.Orbit.TrueAnomaly, - falloffType).Position; - */ - - var rot = Quaternion.AngleAxis(body.Config.Orbit.LongitudeOfAscendingNode + body.Config.Orbit.TrueAnomaly + body.Config.Orbit.ArgumentOfPeriapsis + 180f, Vector3.up); - // For now, eccentric orbits gotta start at apoapsis and cant be inclined - if(body.Config.Orbit.Eccentricity != 0) + var rot = Quaternion.AngleAxis(body.Config.Orbit.LongitudeOfAscendingNode + body.Config.Orbit.TrueAnomaly + body.Config.Orbit.ArgumentOfPeriapsis + 180f, Vector3.up); + if (body.Config.Orbit.Eccentricity != 0) { rot = Quaternion.AngleAxis(body.Config.Orbit.LongitudeOfAscendingNode + body.Config.Orbit.ArgumentOfPeriapsis + 180f, Vector3.up); body.Config.Orbit.Inclination = 0; } - var incAxis = Quaternion.AngleAxis(body.Config.Orbit.LongitudeOfAscendingNode, Vector3.up) * Vector3.left; var incRot = Quaternion.AngleAxis(body.Config.Orbit.Inclination, incAxis); @@ -305,24 +288,18 @@ namespace NewHorizons // Have to do this after setting position InitialMotionBuilder.Make(go, primaryBody, owRigidBody, body.Config.Orbit); - //if (!body.Config.Orbit.IsStatic) DetectorBuilder.Make(go, owRigidBody, primaryBody, ao); - if (!body.Config.Orbit.IsStatic) Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => DetectorBuilder.Make(go, owRigidBody, primaryBody, ao)); - // Spawning on other planets is a bit hacky so we do it last if (body.Config.Spawn != null) { SpawnPointBuilder.Make(go, body.Config.Spawn, owRigidBody); } - // Some things have to be done the second tick - if (body.Config.Orbit != null && body.Config.Orbit.ShowOrbitLine) - Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => OrbitlineBuilder.Make(body.Object, ao, body.Config.Orbit.IsMoon, body.Config.Orbit)); + if (body.Config.Orbit.ShowOrbitLine) OrbitlineBuilder.Make(body.Object, ao, body.Config.Orbit.IsMoon, body.Config); + if (!body.Config.Orbit.IsStatic) DetectorBuilder.Make(go, owRigidBody, primaryBody, ao); if (ao.GetAstroObjectName() == AstroObject.Name.CustomString) AstroObjectLocator.RegisterCustomAstroObject(ao); - Logger.Log("Generation of [" + body.Config.Name + "] completed.", Logger.LogType.Log); - return go; } diff --git a/NewHorizons/NewHorizons.csproj b/NewHorizons/NewHorizons.csproj index a192eb3d..52e4270c 100644 --- a/NewHorizons/NewHorizons.csproj +++ b/NewHorizons/NewHorizons.csproj @@ -267,8 +267,10 @@ + + diff --git a/NewHorizons/OrbitalPhysics/KeplerElements.cs b/NewHorizons/OrbitalPhysics/KeplerElements.cs index 65c30e7d..2747f8cf 100644 --- a/NewHorizons/OrbitalPhysics/KeplerElements.cs +++ b/NewHorizons/OrbitalPhysics/KeplerElements.cs @@ -15,9 +15,9 @@ namespace NewHorizons.OrbitalPhysics public float SemiMajorAxis { get; } public float Inclination { get; } public float ArgumentOfPeriapsis { get; } - public float TrueAnomaly { get; } - public float EccentricAnomaly { get; } - public float MeanAnomaly { get; } + public float TrueAnomaly { get; private set; } + public float EccentricAnomaly { get; private set; } + public float MeanAnomaly { get; private set; } public float SemiMinorAxis { get; } public float Focus { get; } public float Apoapsis { get; } @@ -48,23 +48,49 @@ namespace NewHorizons.OrbitalPhysics public static KeplerElements FromTrueAnomaly(float e, float a, float i, float longitudeOfAscendingNode, float argumentOfPeriapsis, float trueAnomaly) { - var eccentricAnomaly = EccentricAnomalyFromTrueAnomaly(trueAnomaly, e); - var meanAnomaly = MeanAnomalyFromEccentricAnomaly(eccentricAnomaly, e); - return new KeplerElements(e, a, i, longitudeOfAscendingNode, argumentOfPeriapsis, trueAnomaly, eccentricAnomaly, meanAnomaly); + var newKeplerElements = new KeplerElements(e, a, i, longitudeOfAscendingNode, argumentOfPeriapsis, 0, 0, 0); + newKeplerElements.SetTrueAnomaly(trueAnomaly); + return newKeplerElements; } public static KeplerElements FromMeanAnomaly(float e, float a, float i, float longitudeOfAscendingNode, float argumentOfPeriapsis, float meanAnomaly) { - var trueAnomaly = TrueAnomalyFromMeanAnomaly(meanAnomaly, e); - var eccentricAnomaly = EccentricAnomalyFromTrueAnomaly(trueAnomaly, e); - return new KeplerElements(e, a, i, longitudeOfAscendingNode, argumentOfPeriapsis, trueAnomaly, eccentricAnomaly, meanAnomaly); + var newKeplerElements = new KeplerElements(e, a, i, longitudeOfAscendingNode, argumentOfPeriapsis, 0, 0, 0); + newKeplerElements.SetMeanAnomaly(meanAnomaly); + return newKeplerElements; } public static KeplerElements FromEccentricAnomaly(float e, float a, float i, float longitudeOfAscendingNode, float argumentOfPeriapsis, float eccentricAnomaly) { - var trueAnomaly = TrueAnomalyFromEccentricAnomaly(eccentricAnomaly, e); - var meanAnomaly = MeanAnomalyFromEccentricAnomaly(eccentricAnomaly, e); - return new KeplerElements(e, a, i, longitudeOfAscendingNode, argumentOfPeriapsis, trueAnomaly, eccentricAnomaly, meanAnomaly); + var newKeplerElements = new KeplerElements(e, a, i, longitudeOfAscendingNode, argumentOfPeriapsis, 0, 0, 0); + newKeplerElements.SetEccentricAnomaly(eccentricAnomaly); + return newKeplerElements; + } + + public static KeplerElements Copy(KeplerElements original) + { + return KeplerElements.FromTrueAnomaly(original.Eccentricity, original.SemiMajorAxis, original.Inclination, original.LongitudeOfAscendingNode, original.ArgumentOfPeriapsis, original.TrueAnomaly); + } + + public void SetTrueAnomaly(float trueAnomaly) + { + TrueAnomaly = trueAnomaly; + EccentricAnomaly = EccentricAnomalyFromTrueAnomaly(trueAnomaly, Eccentricity); + MeanAnomaly = MeanAnomalyFromEccentricAnomaly(EccentricAnomaly, Eccentricity); + } + + public void SetMeanAnomaly(float meanAnomaly) + { + MeanAnomaly = meanAnomaly; + TrueAnomaly = TrueAnomalyFromMeanAnomaly(meanAnomaly, Eccentricity); + EccentricAnomaly = EccentricAnomalyFromTrueAnomaly(TrueAnomaly, Eccentricity); + } + + public void SetEccentricAnomaly(float eccentricAnomaly) + { + EccentricAnomaly = eccentricAnomaly; + TrueAnomaly = TrueAnomalyFromEccentricAnomaly(eccentricAnomaly, Eccentricity); + MeanAnomaly = MeanAnomalyFromEccentricAnomaly(eccentricAnomaly, Eccentricity); } private static float MeanAnomalyFromEccentricAnomaly(float eccentricAnomaly, float eccentricity) diff --git a/NewHorizons/OrbitalPhysics/OrbitalHelper.cs b/NewHorizons/OrbitalPhysics/OrbitalHelper.cs index a82e8d7f..a71f7fdc 100644 --- a/NewHorizons/OrbitalPhysics/OrbitalHelper.cs +++ b/NewHorizons/OrbitalPhysics/OrbitalHelper.cs @@ -35,7 +35,6 @@ namespace NewHorizons.OrbitalPhysics if(kepler.Eccentricity < 1) term1 = mu * Mathf.Log(kepler.Periapsis / kepler.Apoapsis) * rp2 / (rp2 - ra2); var term2 = mu * Mathf.Log(kepler.Apoapsis / distance); - Logger.Log($"{term1}, {term2}, {kepler.Periapsis} {kepler.Apoapsis}, {kepler.SemiMajorAxis}, {kepler.SemiMinorAxis}"); return Mathf.Sqrt(2 * (term1 + term2)); } Logger.LogError($"Invalid exponent {gravity.Exponent}"); diff --git a/NewHorizons/OrbitalPhysics/ParameterizedAstroObject.cs b/NewHorizons/OrbitalPhysics/ParameterizedAstroObject.cs new file mode 100644 index 00000000..f762ddb5 --- /dev/null +++ b/NewHorizons/OrbitalPhysics/ParameterizedAstroObject.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NewHorizons.OrbitalPhysics +{ + public class ParameterizedAstroObject : AstroObject + { + public KeplerElements keplerElements; + } +} diff --git a/NewHorizons/OrbitalPhysics/TrackingOrbitLine.cs b/NewHorizons/OrbitalPhysics/TrackingOrbitLine.cs new file mode 100644 index 00000000..dc5e54ae --- /dev/null +++ b/NewHorizons/OrbitalPhysics/TrackingOrbitLine.cs @@ -0,0 +1,101 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace NewHorizons.OrbitalPhysics +{ + public class TrackingOrbitLine : OrbitLine + { + protected override void InitializeLineRenderer() + { + _lineRenderer.positionCount = this._numVerts; + } + + protected override void OnValidate() + { + if (_numVerts < 0 || _numVerts > 4096) + { + _numVerts = Mathf.Clamp(this._numVerts, 0, 4096); + } + if (_lineRenderer.positionCount != _numVerts) + { + InitializeLineRenderer(); + } + } + + protected override void Start() + { + base.Start(); + _vertices = new Vector3[_numVerts]; + + ResetLineVertices(); + + base.enabled = false; + } + + protected override void Update() + { + var primary = _astroObject.GetPrimaryBody(); + Vector3 origin = primary == null ? Locator.GetRootTransform().position : primary.transform.position; + + _timer += Time.deltaTime; + var updateTime = (TrailTime / (float)_numVerts); + + if(_timer > updateTime) + { + for (int i = _numVerts - 1; i > 0; i--) + { + var v = _vertices[i - 1]; + _vertices[i] = new Vector3(v.x, v.y, v.z); + } + _vertices[0] = transform.parent.position - origin; + _lineRenderer.SetPositions(_vertices); + _timer = 0; + } + + base.transform.position = origin; + base.transform.rotation = Quaternion.AngleAxis(0f, Vector3.up); + + float num2 = DistanceToTrackingOrbitLine(Locator.GetActiveCamera().transform.position); + float widthMultiplier = Mathf.Min(num2 * (_lineWidth / 1000f), _maxLineWidth); + float num3 = _fade ? (1f - Mathf.Clamp01((num2 - _fadeStartDist) / (_fadeEndDist - _fadeStartDist))) : 1f; + _lineRenderer.widthMultiplier = widthMultiplier; + _lineRenderer.startColor = new Color(_color.r, _color.g, _color.b, num3 * num3); + } + + private float DistanceToTrackingOrbitLine(Vector3 point) + { + // Check against 3 points on the line + var primary = _astroObject.GetPrimaryBody(); + point -= primary.transform.position; + var dist1 = Vector3.Distance(point, _vertices[0]); + var dist2 = Vector3.Distance(point, _vertices[(int)(_numVerts / 2)]); + var dist3 = Vector3.Distance(point, _vertices[_numVerts - 1]); + + return Mathf.Min(new float[] { dist1, dist2, dist3 }); + } + + public void ResetLineVertices() + { + var primary = _astroObject.GetPrimaryBody(); + Vector3 origin = primary == null ? Locator.GetRootTransform().position : primary.transform.position; + + base.transform.position = origin; + base.transform.rotation = Quaternion.AngleAxis(0f, Vector3.up); + + for (int i = _numVerts - 1; i > 0; i--) + { + _vertices[i] = transform.parent.position - origin; + } + _lineRenderer.SetPositions(_vertices); + } + + private Vector3[] _vertices; + private float _timer; + + public float TrailTime = 60f; + } +}