diff --git a/NewHorizons/Builder/General/BaseBuilder.cs b/NewHorizons/Builder/General/BaseBuilder.cs index 90fae0b0..2968cc12 100644 --- a/NewHorizons/Builder/General/BaseBuilder.cs +++ b/NewHorizons/Builder/General/BaseBuilder.cs @@ -10,7 +10,7 @@ namespace NewHorizons.Builder.General { static class BaseBuilder { - public static Tuple Make(GameObject body, AstroObject primaryBody, Vector3 positionVector, IPlanetConfig config) + public static Tuple Make(GameObject body, AstroObject primaryBody, IPlanetConfig config) { Rigidbody rigidBody = body.AddComponent(); rigidBody.mass = 10000; @@ -34,7 +34,7 @@ namespace NewHorizons.Builder.General ParameterizedAstroObject astroObject = body.AddComponent(); - if (config.Orbit != null) astroObject.keplerElements = KeplerElements.FromOrbitModule(config.Orbit); + if (config.Orbit != null) astroObject.SetKeplerCoordinatesFromOrbitModule(config.Orbit); var type = AstroObject.Type.Planet; if (config.Orbit.IsMoon) type = AstroObject.Type.Moon; diff --git a/NewHorizons/Builder/General/DetectorBuilder.cs b/NewHorizons/Builder/General/DetectorBuilder.cs index 3cab38c2..d561fe98 100644 --- a/NewHorizons/Builder/General/DetectorBuilder.cs +++ b/NewHorizons/Builder/General/DetectorBuilder.cs @@ -79,7 +79,7 @@ namespace NewHorizons.Builder.General var secondary = point.Secondary; var planets = point.Planets; - + // Binaries have to use the same gravity exponent var primaryGV = primary.GetGravityVolume(); var secondaryGV = secondary.GetGravityVolume(); @@ -122,25 +122,20 @@ namespace NewHorizons.Builder.General secondaryCFD.SetValue("_inheritElement0", false); // 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) + var primaryAO = primary.GetComponent(); + var secondaryAO = secondary.GetComponent(); + if (primaryAO == null||secondaryAO == null) { - ecc = parameterizedAstroObject.keplerElements.Eccentricity; - i = parameterizedAstroObject.keplerElements.Inclination; - l = parameterizedAstroObject.keplerElements.LongitudeOfAscendingNode; - p = parameterizedAstroObject.keplerElements.ArgumentOfPeriapsis; + Logger.LogError($"Couldn't find ParameterizedAstroObject for body {primaryRB.name} or {secondaryRB.name}"); + return; } - // Update speeds - var direction = Vector3.Cross(separation, Vector3.up).normalized; - if (direction.sqrMagnitude == 0) direction = Vector3.left; + float ecc = primaryAO.Eccentricity; + float i = primaryAO.Inclination; + float l = primaryAO.LongitudeOfAscendingNode; + float p = primaryAO.ArgumentOfPeriapsis; + // Update speeds var m1 = Gm1 / GravityVolume.GRAVITATIONAL_CONSTANT; var m2 = Gm2 / GravityVolume.GRAVITATIONAL_CONSTANT; var reducedMass = m1 * m2 / (m1 + m2); @@ -148,54 +143,42 @@ namespace NewHorizons.Builder.General var r = separation.magnitude; - // 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); + Logger.Log($"Primary AO: [{primaryAO}], Secondary AO: [{secondaryAO}]"); - // Maybe we'll need these orbital parameters later - if(parameterizedAstroObject != null) parameterizedAstroObject.keplerElements = primaryKeplerElements; - if(parameterizedAstroObject2 != null) parameterizedAstroObject2.keplerElements = secondaryKeplerElements; + // Start them off at their periapsis + primaryAO.SetKeplerCoordinatesFromTrueAnomaly(ecc, r1 / (1f - ecc), i, l, p, 0); + secondaryAO.SetKeplerCoordinatesFromTrueAnomaly(ecc, r2 / (1f - ecc), i, l, p, 180); + + Logger.Log($"Primary AO: [{primaryAO}], Secondary AO: [{secondaryAO}]"); // Finally we update the speeds - float v = Mathf.Sqrt(GravityVolume.GRAVITATIONAL_CONSTANT * totalMass * (1 - ecc * ecc) / Mathf.Pow(r, exponent - 1)); - var v2 = v / (1f + (m2 / m1)); - var v1 = v - v2; + var v1 = OrbitalHelper.GetVelocity(new OrbitalHelper.Gravity(exponent, totalMass), primaryAO); + var v2 = OrbitalHelper.GetVelocity(new OrbitalHelper.Gravity(exponent, totalMass), secondaryAO); - // Rotate - var rot = Quaternion.AngleAxis(l + p + 180f, Vector3.up); - var incAxis = Quaternion.AngleAxis(l, Vector3.up) * Vector3.left; - var incRot = Quaternion.AngleAxis(i, incAxis); - - //Do this next tick for... reasons? var focalPointMotion = point.gameObject.GetComponent(); var focalPointVelocity = focalPointMotion == null ? Vector3.zero : focalPointMotion.GetInitVelocity(); - var d1 = Vector3.Cross(OrbitalHelper.RotateTo(Vector3.up, primaryKeplerElements), separation.normalized); - var d2 = Vector3.Cross(OrbitalHelper.RotateTo(Vector3.up, primaryKeplerElements), separation.normalized); - var primaryInitialMotion = primary.gameObject.GetComponent(); - primaryInitialMotion.SetValue("_initLinearDirection", d1); - primaryInitialMotion.SetValue("_initLinearSpeed", v1); + primaryInitialMotion.SetValue("_initLinearDirection", v1.normalized); + primaryInitialMotion.SetValue("_initLinearSpeed", v1.magnitude); var secondaryInitialMotion = secondary.gameObject.GetComponent(); - secondaryInitialMotion.SetValue("_initLinearDirection", d2); - secondaryInitialMotion.SetValue("_initLinearSpeed", -v2); - - Logger.Log($"Velocity: {d1}, {v1}, {d2}, {v2}"); + secondaryInitialMotion.SetValue("_initLinearDirection", v2.normalized); + secondaryInitialMotion.SetValue("_initLinearSpeed", v2.magnitude); // InitialMotion already set its speed so we overwrite that if (!primaryInitialMotion.GetValue("_isInitVelocityDirty")) { - Main.Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => primaryRB.SetVelocity(d1 * v1 + focalPointVelocity)); + Main.Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => primaryRB.SetVelocity(v1 + focalPointVelocity)); } if (!secondaryInitialMotion.GetValue("_isInitVelocityDirty")) { - Main.Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => primaryRB.SetVelocity(d2 * -v2 + focalPointVelocity)); + Main.Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => primaryRB.SetVelocity(-v2 + focalPointVelocity)); } // If they have tracking orbits set the period var period = 2 * Mathf.PI * Mathf.Sqrt(Mathf.Pow(r, exponent + 1) / (GravityVolume.GRAVITATIONAL_CONSTANT * totalMass)); - + if (exponent == 1) period /= 3f; // Only one of these won't be null, the other one gets done next tick diff --git a/NewHorizons/Builder/Orbital/InitialMotionBuilder.cs b/NewHorizons/Builder/Orbital/InitialMotionBuilder.cs index 09354ec2..ad53c343 100644 --- a/NewHorizons/Builder/Orbital/InitialMotionBuilder.cs +++ b/NewHorizons/Builder/Orbital/InitialMotionBuilder.cs @@ -40,24 +40,24 @@ namespace NewHorizons.Builder.Orbital { if (!orbit.IsStatic) { - initialMotion.SetPrimaryBody(primaryBody.GetAttachedOWRigidbody()); - initialMotion.SetValue("_orbitAngle", orbit.Inclination); - initialMotion.SetValue("_isGlobalAxis", false); - if (orbit.Eccentricity != 0 && primaryBody.GetGravityVolume() != null) + initialMotion._orbitImpulseScalar = 0f; + + if(primaryBody != null) { - // Calculate speed at apoapsis - KeplerElements kepler = KeplerElements.FromOrbitModule(orbit); - Gravity gravity = new Gravity(primaryBody.GetGravityVolume()); - - var eccSpeed = OrbitalHelper.GetOrbitalVelocity(kepler.Apoapsis, gravity, kepler); - var circularSpeed = OWPhysics.CalculateOrbitVelocity(primaryBody.GetAttachedOWRigidbody(), OWRB).magnitude; - - initialMotion.SetValue("_orbitImpulseScalar", eccSpeed / circularSpeed); + initialMotion.SetPrimaryBody(primaryBody.GetAttachedOWRigidbody()); + var gv = primaryBody.GetGravityVolume(); + if(gv != null) + { + var velocity = OrbitalHelper.GetVelocity(new OrbitalHelper.Gravity(primaryBody.GetGravityVolume()), orbit); + initialMotion._initLinearDirection = velocity.normalized; + initialMotion._initLinearSpeed = velocity.magnitude; + } } } // Rotation - initialMotion.SetValue("_initAngularSpeed", orbit.SiderealPeriod == 0 ? 0f : 1.0f / orbit.SiderealPeriod); + //initialMotion.SetValue("_initAngularSpeed", orbit.SiderealPeriod == 0 ? 0f : 1.0f / orbit.SiderealPeriod); + initialMotion.SetValue("_initAngularSpeed", 0); var rotationAxis = Quaternion.AngleAxis(orbit.AxialTilt + orbit.Inclination, Vector3.right) * Vector3.up; body.transform.rotation = Quaternion.FromToRotation(Vector3.up, rotationAxis); diff --git a/NewHorizons/Builder/Orbital/OrbitlineBuilder.cs b/NewHorizons/Builder/Orbital/OrbitlineBuilder.cs index 71468c1b..b54a5c4e 100644 --- a/NewHorizons/Builder/Orbital/OrbitlineBuilder.cs +++ b/NewHorizons/Builder/Orbital/OrbitlineBuilder.cs @@ -24,7 +24,7 @@ namespace NewHorizons.Builder.Orbital OrbitLine orbitLine; if (config.Orbit.Eccentricity == 0) { - orbitLine = orbitGO.AddComponent(); + orbitLine = orbitGO.AddComponent(); } else { diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index 7ea6ee75..6e9a1895 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -219,6 +219,8 @@ namespace NewHorizons Logger.Log($"Begin generation sequence of [{body.Config.Name}]"); + body.Config.Orbit.AxialTilt = 0; + var go = new GameObject(body.Config.Name.Replace(" ", "").Replace("'", "") + "_Body"); go.SetActive(false); @@ -227,9 +229,7 @@ namespace NewHorizons var atmoSize = body.Config.Atmosphere != null ? body.Config.Atmosphere.Size : 0f; float sphereOfInfluence = Mathf.Max(atmoSize, body.Config.Base.SurfaceSize * 2f); - var positionVector = OrbitalHelper.RotateTo(Vector3.left * body.Config.Orbit.SemiMajorAxis * (1 + body.Config.Orbit.Eccentricity), body.Config.Orbit); - - var outputTuple = BaseBuilder.Make(go, primaryBody, positionVector, body.Config); + var outputTuple = BaseBuilder.Make(go, primaryBody, body.Config); var ao = (AstroObject)outputTuple.Item1; var owRigidBody = (OWRigidbody)outputTuple.Item2; @@ -272,7 +272,7 @@ namespace NewHorizons // Now that we're done move the planet into place go.transform.parent = Locator.GetRootTransform(); - go.transform.position = positionVector + primaryBody.transform.position; + go.transform.position = OrbitalHelper.GetPosition(body.Config.Orbit) + primaryBody.transform.position; if (go.transform.position.magnitude > FurthestOrbit) { diff --git a/NewHorizons/NewHorizons.csproj b/NewHorizons/NewHorizons.csproj index 486ddf83..404c67b0 100644 --- a/NewHorizons/NewHorizons.csproj +++ b/NewHorizons/NewHorizons.csproj @@ -30,4 +30,9 @@ + + + $(OuterWildsModsDirectory)\PacificEngine.OW_CommonResources\PacificEngine.OW_CommonResources.dll + + \ No newline at end of file diff --git a/NewHorizons/NewHorizons.csproj.user b/NewHorizons/NewHorizons.csproj.user index e74174ee..0199f732 100644 --- a/NewHorizons/NewHorizons.csproj.user +++ b/NewHorizons/NewHorizons.csproj.user @@ -2,6 +2,7 @@ ProjectFiles - C:\Users\Nicholas\AppData\Roaming\OuterWildsModManager\OWML\Mods\xen.NewHorizons + $(AppData)\OuterWildsModManager\OWML\Mods\xen.NewHorizons + $(AppData)\OuterWildsModManager\OWML\Mods diff --git a/NewHorizons/OrbitalPhysics/CartesianStateVectors.cs b/NewHorizons/OrbitalPhysics/CartesianStateVectors.cs deleted file mode 100644 index 7442bbba..00000000 --- a/NewHorizons/OrbitalPhysics/CartesianStateVectors.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; - -namespace NewHorizons.OrbitalPhysics -{ - public class CartesianStateVectors - { - public Vector3 Position { get; set; } - public Vector3 Velocity { get; set; } - - public CartesianStateVectors() - { - Position = Vector3.zero; - Velocity = Vector3.zero; - } - - public CartesianStateVectors(Vector3 pos, Vector3 vel) - { - Position = pos; - Velocity = vel; - } - } -} diff --git a/NewHorizons/OrbitalPhysics/Gravity.cs b/NewHorizons/OrbitalPhysics/Gravity.cs deleted file mode 100644 index f63667c0..00000000 --- a/NewHorizons/OrbitalPhysics/Gravity.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using NewHorizons.Utility; - -namespace NewHorizons.OrbitalPhysics -{ - public class Gravity - { - public float Exponent { get; } - public float Mass { get; } - - public Gravity(float exponent, float mass) - { - Exponent = exponent; - Mass = mass; - } - - public Gravity(GravityVolume gv) - { - Exponent = gv.GetFalloffExponent(); - Mass = gv.GetStandardGravitationalParameter() / GravityVolume.GRAVITATIONAL_CONSTANT; - } - } -} diff --git a/NewHorizons/OrbitalPhysics/KeplerElements.cs b/NewHorizons/OrbitalPhysics/KeplerElements.cs deleted file mode 100644 index 2747f8cf..00000000 --- a/NewHorizons/OrbitalPhysics/KeplerElements.cs +++ /dev/null @@ -1,127 +0,0 @@ -using NewHorizons.External; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; - -namespace NewHorizons.OrbitalPhysics -{ - public class KeplerElements - { - public float LongitudeOfAscendingNode { get; } - public float Eccentricity { get; } - public float SemiMajorAxis { get; } - public float Inclination { get; } - public float ArgumentOfPeriapsis { 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; } - public float Periapsis { get; } - - private KeplerElements(float e, float a, float i, float longitudeOfAscendingNode, float argumentOfPeriapsis, float trueAnomaly, float eccentricAnomaly, float meanAnomaly) - { - LongitudeOfAscendingNode = longitudeOfAscendingNode; - Eccentricity = e; - SemiMajorAxis = a; - Inclination = i; - ArgumentOfPeriapsis = argumentOfPeriapsis; - TrueAnomaly = trueAnomaly; - - SemiMinorAxis = SemiMajorAxis * Mathf.Sqrt(1 - Eccentricity * Eccentricity); - Focus = Mathf.Sqrt((SemiMajorAxis * SemiMajorAxis) - (SemiMinorAxis * SemiMinorAxis)); - Apoapsis = SemiMajorAxis + Focus; - Periapsis = SemiMajorAxis - Focus; - - EccentricAnomaly = eccentricAnomaly; - MeanAnomaly = meanAnomaly; - } - - public static KeplerElements FromOrbitModule(OrbitModule module) - { - return FromTrueAnomaly(module.Eccentricity, module.SemiMajorAxis, module.Inclination, module.LongitudeOfAscendingNode, module.ArgumentOfPeriapsis, module.TrueAnomaly); - } - - public static KeplerElements FromTrueAnomaly(float e, float a, float i, float longitudeOfAscendingNode, float argumentOfPeriapsis, float trueAnomaly) - { - 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 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 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) - { - return eccentricAnomaly - eccentricity * Mathf.Sin(eccentricAnomaly); - } - - private static float TrueAnomalyFromEccentricAnomaly(float eccentricAnomaly, float eccentricity) - { - var a = Mathf.Cos(eccentricAnomaly) - eccentricity; - var h = 1 - eccentricity * Mathf.Cos(eccentricAnomaly); - var o = h * h - a * a; - return Mathf.Atan2(o, a); - } - - private static float EccentricAnomalyFromTrueAnomaly(float trueAnomaly, float eccentricity) - { - var a = Mathf.Cos(trueAnomaly) + eccentricity; - var h = 1 + eccentricity * Mathf.Cos(trueAnomaly); - var o = h * h - a * a; - return Mathf.Atan2(o, a); - } - - private static float TrueAnomalyFromMeanAnomaly(float meanAnomaly, float eccentricity) - { - // Fourier expansion - var term1 = meanAnomaly; - var term2 = (2 * eccentricity - eccentricity * eccentricity * eccentricity / 4f) * Mathf.Sin(meanAnomaly); - var term3 = (eccentricity * eccentricity * Mathf.Sin(2 * meanAnomaly) * 5f / 4f); - var term4 = (eccentricity * eccentricity * eccentricity * Mathf.Sin(3 * meanAnomaly) * 13f / 12f); - return term1 + term2 + term3 + term4; - } - } -} diff --git a/NewHorizons/OrbitalPhysics/OrbitalHelper.cs b/NewHorizons/OrbitalPhysics/OrbitalHelper.cs index cc7cc7a9..de0c059b 100644 --- a/NewHorizons/OrbitalPhysics/OrbitalHelper.cs +++ b/NewHorizons/OrbitalPhysics/OrbitalHelper.cs @@ -7,7 +7,12 @@ using UnityEngine; using NewHorizons.Utility; using Logger = NewHorizons.Utility.Logger; using NewHorizons.External; +using CRGravity = PacificEngine.OW_CommonResources.Geometry.Orbits.Gravity; +using KeplerCoordinates = PacificEngine.OW_CommonResources.Geometry.Orbits.KeplerCoordinates; +/* + * Wrapper class for OW_CommonResources.Geometry.Orbits functions + */ namespace NewHorizons.OrbitalPhysics { public static class OrbitalHelper @@ -19,68 +24,97 @@ namespace NewHorizons.OrbitalPhysics none } - public static Vector3 RotateTo(Vector3 vector, KeplerElements elements) + public static Vector3 GetPosition(OrbitModule orbit) { - // For now, eccentric orbits gotta start at apoapsis and cant be inclined - var rot = Quaternion.AngleAxis(elements.LongitudeOfAscendingNode + elements.TrueAnomaly + elements.ArgumentOfPeriapsis + 180f, Vector3.up); - if (elements.Eccentricity != 0) + Vector3 pos = Vector3.zero; + if(orbit.SemiMajorAxis != 0) { - rot = Quaternion.AngleAxis(elements.LongitudeOfAscendingNode + elements.ArgumentOfPeriapsis + 180f, Vector3.up); + // The gravity doesnt have an affect on position so we put whatever + var crGravity = new CRGravity(GravityVolume.GRAVITATIONAL_CONSTANT, 1f, 100f); + var kepler = KeplerCoordinates.fromTrueAnomaly(orbit.Eccentricity, orbit.SemiMajorAxis, orbit.Inclination + 90, orbit.ArgumentOfPeriapsis, orbit.LongitudeOfAscendingNode, orbit.TrueAnomaly); + pos = PacificEngine.OW_CommonResources.Geometry.Orbits.OrbitHelper.toCartesian(crGravity, 0f, kepler).Item1; } - var incAxis = Quaternion.AngleAxis(elements.LongitudeOfAscendingNode, Vector3.up) * Vector3.left; - var incRot = Quaternion.AngleAxis(elements.Inclination, incAxis); - - return rot * incRot * vector; + Logger.Log($"Position : {pos}"); + return pos; } - public static Vector3 RotateTo(Vector3 vector, OrbitModule module) + public static Vector3 GetPosition(ParameterizedAstroObject ao) { - return RotateTo(vector, KeplerElements.FromOrbitModule(module)); + Vector3 pos = Vector3.zero; + if(ao.SemiMajorAxis != 0) + { + var crGravity = new CRGravity(GravityVolume.GRAVITATIONAL_CONSTANT, 1f, 100f); + var kepler = KeplerCoordinates.fromTrueAnomaly(ao.Eccentricity, ao.SemiMajorAxis, ao.Inclination + 90, ao.ArgumentOfPeriapsis, ao.LongitudeOfAscendingNode, ao.TrueAnomaly); + pos = PacificEngine.OW_CommonResources.Geometry.Orbits.OrbitHelper.toCartesian(crGravity, 0f, kepler).Item1; + } + + Logger.Log($"Position : {pos}"); + return pos; } - public static Vector3 VelocityDirection(Vector3 separation, KeplerElements elements) + public static Vector3 GetPositionFromTrueAnomaly(float eccentricity, float semiMajorAxis, float inclination, float argumentOfPeriapsis, float longitudeOfAscendingNode, float trueAnomaly) { - var incAxis = Quaternion.AngleAxis(elements.LongitudeOfAscendingNode, Vector3.up) * Vector3.left; - var incRot = Quaternion.AngleAxis(elements.Inclination, incAxis); - return Vector3.Cross(RotateTo(Vector3.up, elements), separation); + Vector3 pos = Vector3.zero; + if (semiMajorAxis != 0) + { + var crGravity = new CRGravity(GravityVolume.GRAVITATIONAL_CONSTANT, 1f, 100f); + var kepler = KeplerCoordinates.fromTrueAnomaly(eccentricity, semiMajorAxis, inclination + 90, argumentOfPeriapsis, longitudeOfAscendingNode, trueAnomaly); + pos = PacificEngine.OW_CommonResources.Geometry.Orbits.OrbitHelper.toCartesian(crGravity, 0f, kepler).Item1; + } + + Logger.Log($"Position : {pos}"); + return pos; } - public static float GetOrbitalVelocity(float distance, Gravity gravity, KeplerElements kepler) + public static Vector3 GetPositionFromEccentricAnomaly(float eccentricity, float semiMajorAxis, float inclination, float argumentOfPeriapsis, float longitudeOfAscendingNode, float eccentricAnomaly) { - if (kepler.Eccentricity == 0) return GetCircularOrbitVelocity(distance, gravity, kepler); + Vector3 pos = Vector3.zero; + if (semiMajorAxis != 0) + { + var crGravity = new CRGravity(GravityVolume.GRAVITATIONAL_CONSTANT, 1f, 100f); + var kepler = KeplerCoordinates.fromEccentricAnomaly(eccentricity, semiMajorAxis, inclination + 90, argumentOfPeriapsis, longitudeOfAscendingNode, eccentricAnomaly); + pos = PacificEngine.OW_CommonResources.Geometry.Orbits.OrbitHelper.toCartesian(crGravity, 0f, kepler).Item1; + } - if (gravity.Exponent == 2) - { - return Mathf.Sqrt(GravityVolume.GRAVITATIONAL_CONSTANT * gravity.Mass * (2f / distance - 1f / kepler.SemiMajorAxis)); - } - if(gravity.Exponent == 1) - { - var mu = GravityVolume.GRAVITATIONAL_CONSTANT * gravity.Mass; - var rp2 = kepler.Periapsis * kepler.Periapsis; - var ra2 = kepler.Apoapsis * kepler.Apoapsis; - float term1 = 0; - if(kepler.Eccentricity < 1) - term1 = mu * Mathf.Log(kepler.Periapsis / kepler.Apoapsis) * rp2 / (rp2 - ra2); - var term2 = mu * Mathf.Log(kepler.Apoapsis / distance); - return Mathf.Sqrt(2 * (term1 + term2)); - } - Logger.LogError($"Invalid exponent {gravity.Exponent}"); - return 0f; + Logger.Log($"Position : {pos}"); + return pos; } - public static float GetCircularOrbitVelocity(float distance, Gravity gravity, KeplerElements kepler) + public static Vector3 GetVelocity(Gravity gravity, OrbitModule orbit) { - if (gravity.Exponent == 2) + var crGravity = new CRGravity(GravityVolume.GRAVITATIONAL_CONSTANT, gravity.Exponent, gravity.Mass); + var kepler = KeplerCoordinates.fromTrueAnomaly(orbit.Eccentricity, orbit.SemiMajorAxis, orbit.Inclination + 90, orbit.ArgumentOfPeriapsis, orbit.LongitudeOfAscendingNode, orbit.TrueAnomaly); + var vel = PacificEngine.OW_CommonResources.Geometry.Orbits.OrbitHelper.toCartesian(crGravity, 0f, kepler).Item2; + Logger.Log($"Velocity : {vel}"); + return vel; + } + + public static Vector3 GetVelocity(Gravity gravity, ParameterizedAstroObject ao) + { + var crGravity = new CRGravity(GravityVolume.GRAVITATIONAL_CONSTANT, gravity.Exponent, gravity.Mass); + var kepler = KeplerCoordinates.fromTrueAnomaly(ao.Eccentricity, ao.SemiMajorAxis, ao.Inclination + 90, ao.ArgumentOfPeriapsis, ao.LongitudeOfAscendingNode, ao.TrueAnomaly); + var vel = PacificEngine.OW_CommonResources.Geometry.Orbits.OrbitHelper.toCartesian(crGravity, 0f, kepler).Item2; + Logger.Log($"Velocity : {vel}"); + return vel; + } + + public class Gravity + { + public float Exponent { get; } + public float Mass { get; } + + public Gravity(float exponent, float mass) { - return Mathf.Sqrt(GravityVolume.GRAVITATIONAL_CONSTANT * gravity.Mass / distance); + Exponent = exponent; + Mass = mass; } - if(gravity.Exponent == 1) + + public Gravity(GravityVolume gv) { - return Mathf.Sqrt(GravityVolume.GRAVITATIONAL_CONSTANT * gravity.Mass); + Exponent = gv.GetFalloffExponent(); + Mass = gv.GetStandardGravitationalParameter() / GravityVolume.GRAVITATIONAL_CONSTANT; } - Logger.LogError($"Invalid exponent {gravity.Exponent}"); - return 0f; } } } diff --git a/NewHorizons/OrbitalPhysics/ParameterizedAstroObject.cs b/NewHorizons/OrbitalPhysics/ParameterizedAstroObject.cs index f762ddb5..7668667d 100644 --- a/NewHorizons/OrbitalPhysics/ParameterizedAstroObject.cs +++ b/NewHorizons/OrbitalPhysics/ParameterizedAstroObject.cs @@ -1,4 +1,6 @@ -using System; +using NewHorizons.External; +using PacificEngine.OW_CommonResources.Geometry.Orbits; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -8,6 +10,51 @@ namespace NewHorizons.OrbitalPhysics { public class ParameterizedAstroObject : AstroObject { - public KeplerElements keplerElements; + private KeplerCoordinates _keplerCoordinates; + + public float Eccentricity + { + get { return _keplerCoordinates.eccentricity; } + } + + public float SemiMajorAxis + { + get { return _keplerCoordinates.semiMajorRadius; } + } + + public float Inclination + { + get { return _keplerCoordinates.inclinationAngle - 90; } + } + + public float ArgumentOfPeriapsis + { + get { return _keplerCoordinates.periapseAngle; } + } + + public float LongitudeOfAscendingNode + { + get { return _keplerCoordinates.ascendingAngle; } + } + + public float TrueAnomaly + { + get { return _keplerCoordinates.trueAnomaly; } + } + + public void SetKeplerCoordinatesFromOrbitModule(OrbitModule orbit) + { + _keplerCoordinates = KeplerCoordinates.fromTrueAnomaly(orbit.Eccentricity, orbit.SemiMajorAxis, orbit.Inclination + 90, orbit.ArgumentOfPeriapsis, orbit.LongitudeOfAscendingNode, orbit.TrueAnomaly); + } + + public void SetKeplerCoordinatesFromTrueAnomaly(float ecc, float a, float i, float p, float l, float trueAnomaly) + { + _keplerCoordinates = KeplerCoordinates.fromTrueAnomaly(ecc, a, i + 90, p, l, trueAnomaly); + } + + public override string ToString() + { + return $"ParameterizedAstroObject: Eccentricity {Eccentricity}, SemiMajorAxis {SemiMajorAxis}, Inclination {Inclination}, ArgumentOfPeriapsis {ArgumentOfPeriapsis}, LongitudeOfAscendingNode {LongitudeOfAscendingNode}, TrueAnomaly {TrueAnomaly}"; + } } } diff --git a/NewHorizons/OrbitalPhysics/ParameterizedInitialMotion.cs b/NewHorizons/OrbitalPhysics/ParameterizedInitialMotion.cs deleted file mode 100644 index 9e91b081..00000000 --- a/NewHorizons/OrbitalPhysics/ParameterizedInitialMotion.cs +++ /dev/null @@ -1,112 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; -using NewHorizons.Utility; -using Logger = NewHorizons.Utility.Logger; - -namespace NewHorizons.OrbitalPhysics -{ - public class ParameterizedInitialMotion : InitialMotion - { - /* - private new void Awake() - { - _rotationAxis = base.transform.TransformDirection(_rotationAxis); - _satelliteBody = this.GetRequiredComponent(); - } - - private new void Start() - { - _satelliteBody.UpdateCenterOfMass(); - _satelliteBody.AddVelocityChange(GetInitVelocity()); - _satelliteBody.AddAngularVelocityChange(GetInitAngularVelocity()); - } - - public new Vector2 GetOrbitEllipseSemiAxes() - { - var x = _semiMajorAxis; - var y = _semiMajorAxis * Mathf.Sqrt(1 - _eccentricity * _eccentricity); - - return new Vector2(x, y); - } - - public new Vector3 GetInitAngularVelocity() - { - return _rotationAxis.normalized * _initAngularSpeed; - } - - public new OWRigidbody GetPrimaryBody() - { - return _primary.GetAttachedOWRigidbody(); - } - - public new void SetPrimaryBody(OWRigidbody primaryBody) - { - _primary = primaryBody.gameObject.GetComponent(); - } - - public new Vector3 GetInitVelocity() - { - if(_initVelocityDirty) - { - var state = OrbitalHelper.CartesianStateVectorsFromTrueAnomaly( - _primary.GetGravityVolume().GetStandardGravitationalParameter(), - _eccentricity, - _semiMajorAxis, - _inclination, - _longitudeOfAscendingNode, - _argumentOfPeriapsis, - _trueAnomaly, - _primary.GetGravityVolume().GetFalloffType() - ); - _initVelocity = state.Velocity; - - if(_primary?.GetComponent() != null) - { - var primaryVel = _primary.GetComponent().GetInitVelocity(); - Logger.Log($"{primaryVel}"); - _initVelocity += primaryVel; - } - - _initVelocityDirty = false; - } - return _initVelocity; - } - - public void SetOrbitalParameters(float eccentricity, float semiMajorAxis, float inclination, float longitudeOfAscendingNode, float argumentOfPeriapsis, float trueAnomaly) - { - _eccentricity = eccentricity; - _semiMajorAxis = semiMajorAxis; - _inclination = inclination; - _longitudeOfAscendingNode = longitudeOfAscendingNode; - _argumentOfPeriapsis = argumentOfPeriapsis; - _trueAnomaly = trueAnomaly; - } - - public void SetPrimary(AstroObject primary) - { - _primary = primary; - } - - private float _eccentricity; - private float _semiMajorAxis; - private float _inclination; - private float _longitudeOfAscendingNode; - private float _argumentOfPeriapsis; - private float _trueAnomaly; - - private AstroObject _primary; - - private bool _initVelocityDirty = true; - private Vector3 _initVelocity; - private Vector3 _rotationAxis = Vector3.up; - - private float _initAngularSpeed; - - private OWRigidbody _satelliteBody; - */ - } -} diff --git a/NewHorizons/OrbitalPhysics/ParameterizedOrbitLine.cs b/NewHorizons/OrbitalPhysics/ParameterizedOrbitLine.cs index 56e39ef3..f63827db 100644 --- a/NewHorizons/OrbitalPhysics/ParameterizedOrbitLine.cs +++ b/NewHorizons/OrbitalPhysics/ParameterizedOrbitLine.cs @@ -11,118 +11,25 @@ using Logger = NewHorizons.Utility.Logger; namespace NewHorizons.OrbitalPhysics { - public class ParameterizedOrbitLine : OrbitLine - { - /* - protected override void InitializeLineRenderer() - { - base.GetComponent().positionCount = this._numVerts; - } + public class ParameterizedOrbitLine : EllipticOrbitLine + { + public ParameterizedAstroObject astroObject; - protected override void OnValidate() - { - if (_numVerts < 0 || _numVerts > 4096) - { - _numVerts = Mathf.Clamp(this._numVerts, 0, 4096); - } - if (base.GetComponent().positionCount != _numVerts) - { - InitializeLineRenderer(); - } - } - - protected override void Start() - { - base.Start(); - _verts = new Vector3[_numVerts]; - base.enabled = false; - } - - public void SetOrbitalParameters(float eccentricity, float semiMajorAxis, float inclination, float longitudeOfAscendingNode, float argumentOfPeriapsis, float trueAnomaly) + public override void Start() { - _eccentricity = eccentricity; - _semiMajorAxis = semiMajorAxis; - _inclination = inclination; - _longitudeOfAscendingNode = longitudeOfAscendingNode; - _argumentOfPeriapsis = argumentOfPeriapsis; - _trueAnomaly = trueAnomaly; + base.Start(); - _initialMotion = (_astroObject != null) ? _astroObject.GetComponent() : null; - _primary = (_astroObject != null) ? _astroObject.GetPrimaryBody() : null; + astroObject = _astroObject as ParameterizedAstroObject; - _falloffType = _primary.GetGravityVolume().GetFalloffType(); - if (_initialMotion && _primary) - { - _vSemiMajorAxis = OrbitalHelper.CartesianStateVectorsFromEccentricAnomaly(0f, _eccentricity, _semiMajorAxis, _inclination, _longitudeOfAscendingNode, _argumentOfPeriapsis, 0, _falloffType).Position; - _vSemiMinorAxis = OrbitalHelper.CartesianStateVectorsFromEccentricAnomaly(0f, _eccentricity, _semiMajorAxis, _inclination, _longitudeOfAscendingNode, _argumentOfPeriapsis, 90, _falloffType).Position; - _upAxisDir = Vector3.Cross(_vSemiMajorAxis, _vSemiMinorAxis); + var periapsis = OrbitalHelper.GetPositionFromEccentricAnomaly(astroObject.Eccentricity, astroObject.SemiMajorAxis, astroObject.Inclination + 90, astroObject.ArgumentOfPeriapsis, astroObject.LongitudeOfAscendingNode, 0f); + var semiMinorDecending = OrbitalHelper.GetPositionFromEccentricAnomaly(astroObject.Eccentricity, astroObject.SemiMajorAxis, astroObject.Inclination + 90, astroObject.ArgumentOfPeriapsis, astroObject.LongitudeOfAscendingNode, 90f); + var a = astroObject.SemiMajorAxis; + var b = a * Mathf.Sqrt(1 - astroObject.Eccentricity * astroObject.Eccentricity); - var semiMinorAxis = semiMajorAxis * Mathf.Sqrt(1 - (eccentricity * eccentricity)); - _fociDistance = Mathf.Sqrt((semiMajorAxis * semiMajorAxis) - (semiMinorAxis * semiMinorAxis)); - - base.enabled = true; - } - else - { - Logger.LogError($"Couldn't set values for KeplerOrbitLine. InitialMotion = {_initialMotion}, AstroObject = {_primary}"); - } + _semiMajorAxis = periapsis.normalized * a; + _semiMinorAxis = semiMinorDecending.normalized * b; + _upAxisDir = Vector3.Cross(_semiMajorAxis, _semiMinorAxis).normalized; + _fociDistance = Mathf.Sqrt(a * a - b * b); } - - protected override void Update() - { - Vector3 vector = _primary.transform.position + _vSemiMajorAxis.normalized * _fociDistance; - float nu = CalcProjectedAngleToCenter(vector, _vSemiMajorAxis, _vSemiMinorAxis, _astroObject.transform.position); - - for (int i = 0; i < _numVerts; i++) - { - var angle = Mathf.Rad2Deg * _trueAnomaly + (Mathf.Rad2Deg * nu) - ((float)i / (float)(_numVerts - 1)) * 360f; - _verts[i] = OrbitalHelper.CartesianStateVectorsFromTrueAnomaly(0f, _eccentricity, _semiMajorAxis, _inclination, _longitudeOfAscendingNode, _argumentOfPeriapsis, angle, _falloffType).Position; - } - _lineRenderer.SetPositions(_verts); - - // From EllipticalOrbitLine - base.transform.position = vector; - base.transform.rotation = Quaternion.AngleAxis(0f, Vector3.up); - //base.transform.rotation = Quaternion.AngleAxis(_trueAnomaly + _longitudeOfAscendingNode + _argumentOfPeriapsis, Vector3.up); - - float num2 = DistanceToEllipticalOrbitLine(vector, _vSemiMajorAxis, _vSemiMinorAxis, _upAxisDir, 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 CalcProjectedAngleToCenter(Vector3 foci, Vector3 semiMajorAxis, Vector3 semiMinorAxis, Vector3 point) - { - Vector3 lhs = point - foci; - Vector3 vector = new Vector3(Vector3.Dot(lhs, semiMajorAxis.normalized), 0f, Vector3.Dot(lhs, semiMinorAxis.normalized)); - vector.x *= semiMinorAxis.magnitude / semiMajorAxis.magnitude; - return Mathf.Atan2(vector.z, vector.x); - } - - private float DistanceToEllipticalOrbitLine(Vector3 foci, Vector3 semiMajorAxis, Vector3 semiMinorAxis, Vector3 upAxis, Vector3 point) - { - float f = this.CalcProjectedAngleToCenter(foci, semiMajorAxis, semiMinorAxis, point); - Vector3 b = foci + this._vSemiMajorAxis * Mathf.Cos(f) + this._vSemiMinorAxis * Mathf.Sin(f); - return Vector3.Distance(point, b); - } - - private Vector3 _vSemiMajorAxis; - private Vector3 _vSemiMinorAxis; - private Vector3 _upAxisDir; - private float _fociDistance; - - private float _eccentricity; - private float _semiMajorAxis; - private float _inclination; - private float _longitudeOfAscendingNode; - private float _argumentOfPeriapsis; - private float _trueAnomaly; - - private Vector3[] _verts; - private InitialMotion _initialMotion; - private AstroObject _primary; - private OrbitalHelper.FalloffType _falloffType; - */ - } + } } diff --git a/NewHorizons/OrbitalPhysics/TrackingOrbitLine.cs b/NewHorizons/OrbitalPhysics/TrackingOrbitLine.cs index 6ea98521..30512861 100644 --- a/NewHorizons/OrbitalPhysics/TrackingOrbitLine.cs +++ b/NewHorizons/OrbitalPhysics/TrackingOrbitLine.cs @@ -72,10 +72,10 @@ namespace NewHorizons.OrbitalPhysics 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; } + _vertices[0] = transform.parent.position - origin; + _lineRenderer.SetPositions(_vertices); base.transform.position = origin; base.transform.rotation = Quaternion.AngleAxis(0f, Vector3.up);