mirror of
https://github.com/Outer-Wilds-New-Horizons/new-horizons.git
synced 2025-12-11 20:15:44 +01:00
Better orbit lines + more binaries code
This commit is contained in:
parent
f41803dea3
commit
749e776c98
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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[] { })
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
4
NewHorizons/External/OrbitModule.cs
vendored
4
NewHorizons/External/OrbitModule.cs
vendored
@ -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; }
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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" />
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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}");
|
||||
|
||||
13
NewHorizons/OrbitalPhysics/ParameterizedAstroObject.cs
Normal file
13
NewHorizons/OrbitalPhysics/ParameterizedAstroObject.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
101
NewHorizons/OrbitalPhysics/TrackingOrbitLine.cs
Normal file
101
NewHorizons/OrbitalPhysics/TrackingOrbitLine.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user