Better orbit lines + more binaries code

This commit is contained in:
Nick J. Connors 2021-12-25 02:26:09 -05:00
parent f41803dea3
commit 749e776c98
10 changed files with 284 additions and 123 deletions

View File

@ -12,37 +12,39 @@ namespace NewHorizons.Builder.General
{ {
public static Tuple<AstroObject, OWRigidbody> Make(GameObject body, AstroObject primaryBody, Vector3 positionVector, IPlanetConfig config) public static Tuple<AstroObject, OWRigidbody> Make(GameObject body, AstroObject primaryBody, Vector3 positionVector, IPlanetConfig config)
{ {
Rigidbody RB = body.AddComponent<Rigidbody>(); Rigidbody rigidBody = body.AddComponent<Rigidbody>();
RB.mass = 10000; rigidBody.mass = 10000;
RB.drag = 0f; rigidBody.drag = 0f;
RB.angularDrag = 0f; rigidBody.angularDrag = 0f;
RB.useGravity = false; rigidBody.useGravity = false;
RB.isKinematic = true; rigidBody.isKinematic = true;
RB.interpolation = RigidbodyInterpolation.None; rigidBody.interpolation = RigidbodyInterpolation.None;
RB.collisionDetectionMode = CollisionDetectionMode.Discrete; rigidBody.collisionDetectionMode = CollisionDetectionMode.Discrete;
KinematicRigidbody KRB = body.AddComponent<KinematicRigidbody>(); KinematicRigidbody kinematicRigidBody = body.AddComponent<KinematicRigidbody>();
KRB.centerOfMass = Vector3.zero; kinematicRigidBody.centerOfMass = Vector3.zero;
OWRigidbody OWRB = body.AddComponent<OWRigidbody>(); OWRigidbody owRigidBody = body.AddComponent<OWRigidbody>();
OWRB.SetValue("_kinematicSimulation", true); owRigidBody.SetValue("_kinematicSimulation", true);
OWRB.SetValue("_autoGenerateCenterOfMass", true); owRigidBody.SetValue("_autoGenerateCenterOfMass", true);
OWRB.SetIsTargetable(true); owRigidBody.SetIsTargetable(true);
OWRB.SetValue("_maintainOriginalCenterOfMass", true); owRigidBody.SetValue("_maintainOriginalCenterOfMass", true);
OWRB.SetValue("_rigidbody", RB); owRigidBody.SetValue("_rigidbody", rigidBody);
OWRB.SetValue("_kinematicRigidbody", KRB); owRigidBody.SetValue("_kinematicRigidbody", kinematicRigidBody);
AstroObject AO = body.AddComponent<AstroObject>(); ParameterizedAstroObject astroObject = body.AddComponent<ParameterizedAstroObject>();
if (config.Orbit != null) astroObject.keplerElements = KeplerElements.FromOrbitModule(config.Orbit);
var type = AstroObject.Type.Planet; var type = AstroObject.Type.Planet;
if (config.Orbit.IsMoon) type = AstroObject.Type.Moon; if (config.Orbit.IsMoon) type = AstroObject.Type.Moon;
else if (config.Base.HasCometTail) type = AstroObject.Type.Comet; else if (config.Base.HasCometTail) type = AstroObject.Type.Comet;
else if (config.Star != null) type = AstroObject.Type.Star; else if (config.Star != null) type = AstroObject.Type.Star;
else if (config.FocalPoint != null) type = AstroObject.Type.None; else if (config.FocalPoint != null) type = AstroObject.Type.None;
AO.SetValue("_type", type); astroObject.SetValue("_type", type);
AO.SetValue("_name", AstroObject.Name.CustomString); astroObject.SetValue("_name", AstroObject.Name.CustomString);
AO.SetValue("_customName", config.Name); astroObject.SetValue("_customName", config.Name);
AO.SetValue("_primaryBody", primaryBody); astroObject.SetValue("_primaryBody", primaryBody);
if (config.Orbit.IsTidallyLocked) if (config.Orbit.IsTidallyLocked)
{ {
@ -51,7 +53,7 @@ namespace NewHorizons.Builder.General
alignment.SetValue("_usePhysicsToRotate", true); alignment.SetValue("_usePhysicsToRotate", true);
} }
return new Tuple<AstroObject, OWRigidbody>(AO, OWRB); return new Tuple<AstroObject, OWRigidbody>(astroObject, owRigidBody);
} }
} }
} }

View File

@ -79,26 +79,38 @@ namespace NewHorizons.Builder.General
var planets = point.Planets; 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(); 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(); 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 // Very specific distance between them
Vector3 separation = primary.transform.position - secondary.transform.position; Vector3 separation = primary.transform.position - secondary.transform.position;
var Gm1 = primaryGV.GetStandardGravitationalParameter(); var Gm1 = primaryGV.GetStandardGravitationalParameter();
var Gm2 = secondaryGV.GetStandardGravitationalParameter(); var Gm2 = secondaryGV.GetStandardGravitationalParameter();
// One of the two is zero if it just loaded
if (Gm1 == 0) Gm1 = GravityVolume.GRAVITATIONAL_CONSTANT * primaryGV.GetValue<float>("_surfaceAcceleration") * Mathf.Pow(primaryGV.GetValue<float>("_upperSurfaceRadius"), exponent) / 0.001f;
if (Gm2 == 0) Gm2 = GravityVolume.GRAVITATIONAL_CONSTANT * secondaryGV.GetValue<float>("_surfaceAcceleration") * Mathf.Pow(secondaryGV.GetValue<float>("_upperSurfaceRadius"), exponent) / 0.001f;
float r1 = separation.magnitude * Gm2 / (Gm1 + Gm2); float r1 = separation.magnitude * Gm2 / (Gm1 + Gm2);
float r2 = separation.magnitude * Gm1 / (Gm1 + Gm2); float r2 = separation.magnitude * Gm1 / (Gm1 + Gm2);
primary.transform.position = point.transform.position + r1 * separation.normalized; primary.transform.position = point.transform.position + r1 * separation.normalized;
secondary.transform.position = point.transform.position - r2 * 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 // Set detectable fields
primaryCFD.SetValue("_detectableFields", new ForceVolume[] { secondaryGV }); primaryCFD.SetValue("_detectableFields", new ForceVolume[] { secondaryGV });
primaryCFD.SetValue("_inheritDetector", point.GetAttachedOWRigidbody().GetAttachedForceDetector()); primaryCFD.SetValue("_inheritDetector", point.GetAttachedOWRigidbody().GetAttachedForceDetector());
@ -112,36 +124,71 @@ namespace NewHorizons.Builder.General
// Update speeds // Update speeds
var direction = Vector3.Cross(separation, Vector3.up).normalized; var direction = Vector3.Cross(separation, Vector3.up).normalized;
var m1 = primaryRB.GetMass(); var m1 = Gm1 / GravityVolume.GRAVITATIONAL_CONSTANT;
var m2 = secondaryRB.GetMass(); var m2 = Gm2 / GravityVolume.GRAVITATIONAL_CONSTANT;
var reducedMass = m1 * m2 / (m1 + m2); var reducedMass = m1 * m2 / (m1 + m2);
var totalMass = m1 + m2;
// They must have the same eccentricity
var parameterizedAstroObject = primary.GetComponent<ParameterizedAstroObject>();
var parameterizedAstroObject2 = secondary.GetComponent<ParameterizedAstroObject>();
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; 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(); // Maybe we'll need these orbital parameters later
primaryRB.AddVelocityChange(direction * v1); if(parameterizedAstroObject != null) parameterizedAstroObject.keplerElements = primaryKeplerElements;
secondaryRB.UpdateCenterOfMass(); if(parameterizedAstroObject2 != null) parameterizedAstroObject2.keplerElements = secondaryKeplerElements;
secondaryRB.AddVelocityChange(direction * -v2);
// 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);
/* //direction = periapsisRotation * longitudeRotation * direction;
//Hacky but whatever
var primaryInitialMotion = primary.gameObject.GetComponent<InitialMotion>();
if(primaryInitialMotion.GetValue<bool>("_isInitVelocityDirty"))
primaryInitialMotion.SetValue("_cachedInitVelocity", OWPhysics.CalculateOrbitVelocity(secondaryRB, primaryRB, 0f));
else
primaryInitialMotion.SetPrimaryBody(secondaryRB);
var secondaryInitialMotion = primary.gameObject.GetComponent<InitialMotion>(); //Do this next tick for... reasons?
if (secondaryInitialMotion.GetValue<bool>("_isInitVelocityDirty")) Main.Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => primaryRB.SetVelocity(direction * v1));
secondaryInitialMotion.SetValue("_cachedInitVelocity", OWPhysics.CalculateOrbitVelocity(primaryRB, secondaryRB, 0f)); Main.Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => secondaryRB.SetVelocity(direction * -v2));
else
secondaryInitialMotion.SetPrimaryBody(primaryRB); // 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<TrackingOrbitLine>();
if (trackingOrbitPrimary != null)
{
trackingOrbitPrimary.TrailTime = period;
Main.Instance.ModHelper.Events.Unity.FireInNUpdates(() => trackingOrbitPrimary.ResetLineVertices(), 15);
}
var trackingOrbitSecondary = secondary.GetComponentInChildren<TrackingOrbitLine>();
if (trackingOrbitSecondary != null)
{
trackingOrbitSecondary.TrailTime = period;
Main.Instance.ModHelper.Events.Unity.FireInNUpdates(() => trackingOrbitSecondary.ResetLineVertices(), 15);
}
} }
} }
} }

View File

@ -9,7 +9,7 @@ namespace NewHorizons.Builder.Orbital
{ {
static class OrbitlineBuilder 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"); GameObject orbitGO = new GameObject("Orbit");
orbitGO.transform.parent = body.transform; orbitGO.transform.parent = body.transform;
@ -21,40 +21,32 @@ namespace NewHorizons.Builder.Orbital
lineRenderer.useWorldSpace = false; lineRenderer.useWorldSpace = false;
lineRenderer.loop = false; lineRenderer.loop = false;
if(orbit.Eccentricity == 0) OrbitLine orbitLine;
if (config.Orbit.Eccentricity == 0)
{ {
OrbitLine orbitLine = orbitGO.AddComponent<OrbitLine>(); orbitLine = orbitGO.AddComponent<OrbitLine>();
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[] { });
} }
else else
{ {
OrbitLine orbitLine = orbitGO.AddComponent<EllipticOrbitLine>(); orbitLine = orbitGO.AddComponent<TrackingOrbitLine>();
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[] { });
} }
/* var color = Color.white;
ParameterizedOrbitLine orbitLine = orbitGO.AddComponent<ParameterizedOrbitLine>(); 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("_astroObject", astroobject);
orbitLine.SetValue("_fade", isMoon); orbitLine.SetValue("_fade", isMoon);
orbitLine.SetValue("_lineWidth", 0.5f); orbitLine.SetValue("_lineWidth", 2f);
orbitLine.SetOrbitalParameters( Main.Instance.ModHelper.Events.Unity.FireOnNextUpdate(() =>
orbit.Eccentricity, typeof(OrbitLine).GetMethod("InitializeLineRenderer", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(orbitLine, new object[] { })
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[] { });
*/
} }
} }
} }

View File

@ -1,4 +1,5 @@
using System; using NewHorizons.Utility;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
@ -21,5 +22,6 @@ namespace NewHorizons.External
public bool IsTidallyLocked { get; set; } public bool IsTidallyLocked { get; set; }
public bool ShowOrbitLine { get; set; } = true; public bool ShowOrbitLine { get; set; } = true;
public bool IsStatic { get; set; } public bool IsStatic { get; set; }
public MColor32 Tint { get; set; }
} }
} }

View File

@ -56,7 +56,7 @@ namespace NewHorizons
} }
} }
public void Destroy() public void OnDestroy()
{ {
Logger.Log($"Destroying NewHorizons"); Logger.Log($"Destroying NewHorizons");
SceneManager.sceneLoaded -= OnSceneLoaded; 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"); var go = new GameObject(body.Config.Name.Replace(" ", "").Replace("'", "") + "_Body");
go.SetActive(false); go.SetActive(false);
@ -222,31 +222,14 @@ namespace NewHorizons
var atmoSize = body.Config.Atmosphere != null ? body.Config.Atmosphere.Size : 0f; var atmoSize = body.Config.Atmosphere != null ? body.Config.Atmosphere.Size : 0f;
float sphereOfInfluence = Mathf.Max(atmoSize, body.Config.Base.SurfaceSize * 2f); 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 // 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); rot = Quaternion.AngleAxis(body.Config.Orbit.LongitudeOfAscendingNode + body.Config.Orbit.ArgumentOfPeriapsis + 180f, Vector3.up);
body.Config.Orbit.Inclination = 0; body.Config.Orbit.Inclination = 0;
} }
var incAxis = Quaternion.AngleAxis(body.Config.Orbit.LongitudeOfAscendingNode, Vector3.up) * Vector3.left; var incAxis = Quaternion.AngleAxis(body.Config.Orbit.LongitudeOfAscendingNode, Vector3.up) * Vector3.left;
var incRot = Quaternion.AngleAxis(body.Config.Orbit.Inclination, incAxis); var incRot = Quaternion.AngleAxis(body.Config.Orbit.Inclination, incAxis);
@ -305,24 +288,18 @@ namespace NewHorizons
// Have to do this after setting position // Have to do this after setting position
InitialMotionBuilder.Make(go, primaryBody, owRigidBody, body.Config.Orbit); 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 // Spawning on other planets is a bit hacky so we do it last
if (body.Config.Spawn != null) if (body.Config.Spawn != null)
{ {
SpawnPointBuilder.Make(go, body.Config.Spawn, owRigidBody); SpawnPointBuilder.Make(go, body.Config.Spawn, owRigidBody);
} }
// Some things have to be done the second tick if (body.Config.Orbit.ShowOrbitLine) OrbitlineBuilder.Make(body.Object, ao, body.Config.Orbit.IsMoon, body.Config);
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.IsStatic) DetectorBuilder.Make(go, owRigidBody, primaryBody, ao);
if (ao.GetAstroObjectName() == AstroObject.Name.CustomString) AstroObjectLocator.RegisterCustomAstroObject(ao); if (ao.GetAstroObjectName() == AstroObject.Name.CustomString) AstroObjectLocator.RegisterCustomAstroObject(ao);
Logger.Log("Generation of [" + body.Config.Name + "] completed.", Logger.LogType.Log);
return go; return go;
} }

View File

@ -267,8 +267,10 @@
<Compile Include="OrbitalPhysics\CartesianStateVectors.cs" /> <Compile Include="OrbitalPhysics\CartesianStateVectors.cs" />
<Compile Include="OrbitalPhysics\Gravity.cs" /> <Compile Include="OrbitalPhysics\Gravity.cs" />
<Compile Include="OrbitalPhysics\KeplerElements.cs" /> <Compile Include="OrbitalPhysics\KeplerElements.cs" />
<Compile Include="OrbitalPhysics\ParameterizedAstroObject.cs" />
<Compile Include="OrbitalPhysics\ParameterizedInitialMotion.cs" /> <Compile Include="OrbitalPhysics\ParameterizedInitialMotion.cs" />
<Compile Include="OrbitalPhysics\OrbitalHelper.cs" /> <Compile Include="OrbitalPhysics\OrbitalHelper.cs" />
<Compile Include="OrbitalPhysics\TrackingOrbitLine.cs" />
<Compile Include="Utility\AddDebugShape.cs" /> <Compile Include="Utility\AddDebugShape.cs" />
<Compile Include="Builder\General\AmbientLightBuilder.cs" /> <Compile Include="Builder\General\AmbientLightBuilder.cs" />
<Compile Include="External\IPlanetConfig.cs" /> <Compile Include="External\IPlanetConfig.cs" />

View File

@ -15,9 +15,9 @@ namespace NewHorizons.OrbitalPhysics
public float SemiMajorAxis { get; } public float SemiMajorAxis { get; }
public float Inclination { get; } public float Inclination { get; }
public float ArgumentOfPeriapsis { get; } public float ArgumentOfPeriapsis { get; }
public float TrueAnomaly { get; } public float TrueAnomaly { get; private set; }
public float EccentricAnomaly { get; } public float EccentricAnomaly { get; private set; }
public float MeanAnomaly { get; } public float MeanAnomaly { get; private set; }
public float SemiMinorAxis { get; } public float SemiMinorAxis { get; }
public float Focus { get; } public float Focus { get; }
public float Apoapsis { 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) public static KeplerElements FromTrueAnomaly(float e, float a, float i, float longitudeOfAscendingNode, float argumentOfPeriapsis, float trueAnomaly)
{ {
var eccentricAnomaly = EccentricAnomalyFromTrueAnomaly(trueAnomaly, e); var newKeplerElements = new KeplerElements(e, a, i, longitudeOfAscendingNode, argumentOfPeriapsis, 0, 0, 0);
var meanAnomaly = MeanAnomalyFromEccentricAnomaly(eccentricAnomaly, e); newKeplerElements.SetTrueAnomaly(trueAnomaly);
return new KeplerElements(e, a, i, longitudeOfAscendingNode, argumentOfPeriapsis, trueAnomaly, eccentricAnomaly, meanAnomaly); return newKeplerElements;
} }
public static KeplerElements FromMeanAnomaly(float e, float a, float i, float longitudeOfAscendingNode, float argumentOfPeriapsis, float meanAnomaly) public static KeplerElements FromMeanAnomaly(float e, float a, float i, float longitudeOfAscendingNode, float argumentOfPeriapsis, float meanAnomaly)
{ {
var trueAnomaly = TrueAnomalyFromMeanAnomaly(meanAnomaly, e); var newKeplerElements = new KeplerElements(e, a, i, longitudeOfAscendingNode, argumentOfPeriapsis, 0, 0, 0);
var eccentricAnomaly = EccentricAnomalyFromTrueAnomaly(trueAnomaly, e); newKeplerElements.SetMeanAnomaly(meanAnomaly);
return new KeplerElements(e, a, i, longitudeOfAscendingNode, argumentOfPeriapsis, trueAnomaly, eccentricAnomaly, meanAnomaly); return newKeplerElements;
} }
public static KeplerElements FromEccentricAnomaly(float e, float a, float i, float longitudeOfAscendingNode, float argumentOfPeriapsis, float eccentricAnomaly) public static KeplerElements FromEccentricAnomaly(float e, float a, float i, float longitudeOfAscendingNode, float argumentOfPeriapsis, float eccentricAnomaly)
{ {
var trueAnomaly = TrueAnomalyFromEccentricAnomaly(eccentricAnomaly, e); var newKeplerElements = new KeplerElements(e, a, i, longitudeOfAscendingNode, argumentOfPeriapsis, 0, 0, 0);
var meanAnomaly = MeanAnomalyFromEccentricAnomaly(eccentricAnomaly, e); newKeplerElements.SetEccentricAnomaly(eccentricAnomaly);
return new KeplerElements(e, a, i, longitudeOfAscendingNode, argumentOfPeriapsis, trueAnomaly, eccentricAnomaly, meanAnomaly); 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) private static float MeanAnomalyFromEccentricAnomaly(float eccentricAnomaly, float eccentricity)

View File

@ -35,7 +35,6 @@ namespace NewHorizons.OrbitalPhysics
if(kepler.Eccentricity < 1) if(kepler.Eccentricity < 1)
term1 = mu * Mathf.Log(kepler.Periapsis / kepler.Apoapsis) * rp2 / (rp2 - ra2); term1 = mu * Mathf.Log(kepler.Periapsis / kepler.Apoapsis) * rp2 / (rp2 - ra2);
var term2 = mu * Mathf.Log(kepler.Apoapsis / distance); 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)); return Mathf.Sqrt(2 * (term1 + term2));
} }
Logger.LogError($"Invalid exponent {gravity.Exponent}"); Logger.LogError($"Invalid exponent {gravity.Exponent}");

View File

@ -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;
}
}

View File

@ -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;
}
}