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)
{
Rigidbody RB = body.AddComponent<Rigidbody>();
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>();
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<KinematicRigidbody>();
KRB.centerOfMass = Vector3.zero;
KinematicRigidbody kinematicRigidBody = body.AddComponent<KinematicRigidbody>();
kinematicRigidBody.centerOfMass = Vector3.zero;
OWRigidbody OWRB = body.AddComponent<OWRigidbody>();
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>();
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<AstroObject>();
ParameterizedAstroObject astroObject = body.AddComponent<ParameterizedAstroObject>();
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<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;
// 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<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 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());
@ -112,36 +124,71 @@ namespace NewHorizons.Builder.General
// 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<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;
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<InitialMotion>();
if(primaryInitialMotion.GetValue<bool>("_isInitVelocityDirty"))
primaryInitialMotion.SetValue("_cachedInitVelocity", OWPhysics.CalculateOrbitVelocity(secondaryRB, primaryRB, 0f));
else
primaryInitialMotion.SetPrimaryBody(secondaryRB);
//direction = periapsisRotation * longitudeRotation * direction;
var secondaryInitialMotion = primary.gameObject.GetComponent<InitialMotion>();
if (secondaryInitialMotion.GetValue<bool>("_isInitVelocityDirty"))
secondaryInitialMotion.SetValue("_cachedInitVelocity", OWPhysics.CalculateOrbitVelocity(primaryRB, secondaryRB, 0f));
else
secondaryInitialMotion.SetPrimaryBody(primaryRB);
*/
//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<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
{
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>();
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<OrbitLine>();
}
else
{
OrbitLine orbitLine = orbitGO.AddComponent<EllipticOrbitLine>();
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<TrackingOrbitLine>();
}
/*
ParameterizedOrbitLine orbitLine = orbitGO.AddComponent<ParameterizedOrbitLine>();
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[] { })
);
}
}
}

View File

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

View File

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

View File

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

View File

@ -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)

View File

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

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