mirror of
https://github.com/Outer-Wilds-New-Horizons/new-horizons.git
synced 2025-12-11 20:15:44 +01:00
Attempt 1
This commit is contained in:
parent
02510f3820
commit
4e6b6c4768
@ -10,7 +10,7 @@ namespace NewHorizons.Builder.General
|
|||||||
{
|
{
|
||||||
static class BaseBuilder
|
static class BaseBuilder
|
||||||
{
|
{
|
||||||
public static Tuple<AstroObject, OWRigidbody> Make(GameObject body, AstroObject primaryBody, Vector3 positionVector, IPlanetConfig config)
|
public static Tuple<AstroObject, OWRigidbody> Make(GameObject body, AstroObject primaryBody, IPlanetConfig config)
|
||||||
{
|
{
|
||||||
Rigidbody rigidBody = body.AddComponent<Rigidbody>();
|
Rigidbody rigidBody = body.AddComponent<Rigidbody>();
|
||||||
rigidBody.mass = 10000;
|
rigidBody.mass = 10000;
|
||||||
@ -34,7 +34,7 @@ namespace NewHorizons.Builder.General
|
|||||||
|
|
||||||
ParameterizedAstroObject astroObject = body.AddComponent<ParameterizedAstroObject>();
|
ParameterizedAstroObject astroObject = body.AddComponent<ParameterizedAstroObject>();
|
||||||
|
|
||||||
if (config.Orbit != null) astroObject.keplerElements = KeplerElements.FromOrbitModule(config.Orbit);
|
if (config.Orbit != null) astroObject.SetKeplerCoordinatesFromOrbitModule(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;
|
||||||
|
|||||||
@ -122,25 +122,20 @@ namespace NewHorizons.Builder.General
|
|||||||
secondaryCFD.SetValue("_inheritElement0", false);
|
secondaryCFD.SetValue("_inheritElement0", false);
|
||||||
|
|
||||||
// They must have the same eccentricity
|
// They must have the same eccentricity
|
||||||
var parameterizedAstroObject = primary.GetComponent<ParameterizedAstroObject>();
|
var primaryAO = primary.GetComponent<ParameterizedAstroObject>();
|
||||||
var parameterizedAstroObject2 = secondary.GetComponent<ParameterizedAstroObject>();
|
var secondaryAO = secondary.GetComponent<ParameterizedAstroObject>();
|
||||||
|
if (primaryAO == null||secondaryAO == null)
|
||||||
float ecc = 0;
|
|
||||||
float i = 0;
|
|
||||||
float l = 0;
|
|
||||||
float p = 0;
|
|
||||||
if (parameterizedAstroObject != null)
|
|
||||||
{
|
{
|
||||||
ecc = parameterizedAstroObject.keplerElements.Eccentricity;
|
Logger.LogError($"Couldn't find ParameterizedAstroObject for body {primaryRB.name} or {secondaryRB.name}");
|
||||||
i = parameterizedAstroObject.keplerElements.Inclination;
|
return;
|
||||||
l = parameterizedAstroObject.keplerElements.LongitudeOfAscendingNode;
|
|
||||||
p = parameterizedAstroObject.keplerElements.ArgumentOfPeriapsis;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update speeds
|
float ecc = primaryAO.Eccentricity;
|
||||||
var direction = Vector3.Cross(separation, Vector3.up).normalized;
|
float i = primaryAO.Inclination;
|
||||||
if (direction.sqrMagnitude == 0) direction = Vector3.left;
|
float l = primaryAO.LongitudeOfAscendingNode;
|
||||||
|
float p = primaryAO.ArgumentOfPeriapsis;
|
||||||
|
|
||||||
|
// Update speeds
|
||||||
var m1 = Gm1 / GravityVolume.GRAVITATIONAL_CONSTANT;
|
var m1 = Gm1 / GravityVolume.GRAVITATIONAL_CONSTANT;
|
||||||
var m2 = Gm2 / GravityVolume.GRAVITATIONAL_CONSTANT;
|
var m2 = Gm2 / GravityVolume.GRAVITATIONAL_CONSTANT;
|
||||||
var reducedMass = m1 * m2 / (m1 + m2);
|
var reducedMass = m1 * m2 / (m1 + m2);
|
||||||
@ -148,49 +143,37 @@ namespace NewHorizons.Builder.General
|
|||||||
|
|
||||||
var r = separation.magnitude;
|
var r = separation.magnitude;
|
||||||
|
|
||||||
// Start them off at their periapsis
|
Logger.Log($"Primary AO: [{primaryAO}], Secondary AO: [{secondaryAO}]");
|
||||||
var primaryKeplerElements = KeplerElements.FromTrueAnomaly(ecc, r1 / (1f - ecc), i, l, p, 0);
|
|
||||||
var secondaryKeplerElements = KeplerElements.FromTrueAnomaly(ecc, r2 / (1f - ecc), i, l, p, 180);
|
|
||||||
|
|
||||||
// Maybe we'll need these orbital parameters later
|
// Start them off at their periapsis
|
||||||
if(parameterizedAstroObject != null) parameterizedAstroObject.keplerElements = primaryKeplerElements;
|
primaryAO.SetKeplerCoordinatesFromTrueAnomaly(ecc, r1 / (1f - ecc), i, l, p, 0);
|
||||||
if(parameterizedAstroObject2 != null) parameterizedAstroObject2.keplerElements = secondaryKeplerElements;
|
secondaryAO.SetKeplerCoordinatesFromTrueAnomaly(ecc, r2 / (1f - ecc), i, l, p, 180);
|
||||||
|
|
||||||
|
Logger.Log($"Primary AO: [{primaryAO}], Secondary AO: [{secondaryAO}]");
|
||||||
|
|
||||||
// Finally we update the speeds
|
// Finally we update the speeds
|
||||||
float v = Mathf.Sqrt(GravityVolume.GRAVITATIONAL_CONSTANT * totalMass * (1 - ecc * ecc) / Mathf.Pow(r, exponent - 1));
|
var v1 = OrbitalHelper.GetVelocity(new OrbitalHelper.Gravity(exponent, totalMass), primaryAO);
|
||||||
var v2 = v / (1f + (m2 / m1));
|
var v2 = OrbitalHelper.GetVelocity(new OrbitalHelper.Gravity(exponent, totalMass), secondaryAO);
|
||||||
var v1 = v - v2;
|
|
||||||
|
|
||||||
// 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<InitialMotion>();
|
var focalPointMotion = point.gameObject.GetComponent<InitialMotion>();
|
||||||
var focalPointVelocity = focalPointMotion == null ? Vector3.zero : focalPointMotion.GetInitVelocity();
|
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<InitialMotion>();
|
var primaryInitialMotion = primary.gameObject.GetComponent<InitialMotion>();
|
||||||
primaryInitialMotion.SetValue("_initLinearDirection", d1);
|
primaryInitialMotion.SetValue("_initLinearDirection", v1.normalized);
|
||||||
primaryInitialMotion.SetValue("_initLinearSpeed", v1);
|
primaryInitialMotion.SetValue("_initLinearSpeed", v1.magnitude);
|
||||||
|
|
||||||
var secondaryInitialMotion = secondary.gameObject.GetComponent<InitialMotion>();
|
var secondaryInitialMotion = secondary.gameObject.GetComponent<InitialMotion>();
|
||||||
secondaryInitialMotion.SetValue("_initLinearDirection", d2);
|
secondaryInitialMotion.SetValue("_initLinearDirection", v2.normalized);
|
||||||
secondaryInitialMotion.SetValue("_initLinearSpeed", -v2);
|
secondaryInitialMotion.SetValue("_initLinearSpeed", v2.magnitude);
|
||||||
|
|
||||||
Logger.Log($"Velocity: {d1}, {v1}, {d2}, {v2}");
|
|
||||||
|
|
||||||
// InitialMotion already set its speed so we overwrite that
|
// InitialMotion already set its speed so we overwrite that
|
||||||
if (!primaryInitialMotion.GetValue<bool>("_isInitVelocityDirty"))
|
if (!primaryInitialMotion.GetValue<bool>("_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<bool>("_isInitVelocityDirty"))
|
if (!secondaryInitialMotion.GetValue<bool>("_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
|
// If they have tracking orbits set the period
|
||||||
|
|||||||
@ -40,24 +40,24 @@ namespace NewHorizons.Builder.Orbital
|
|||||||
{
|
{
|
||||||
if (!orbit.IsStatic)
|
if (!orbit.IsStatic)
|
||||||
{
|
{
|
||||||
initialMotion.SetPrimaryBody(primaryBody.GetAttachedOWRigidbody());
|
initialMotion._orbitImpulseScalar = 0f;
|
||||||
initialMotion.SetValue("_orbitAngle", orbit.Inclination);
|
|
||||||
initialMotion.SetValue("_isGlobalAxis", false);
|
if(primaryBody != null)
|
||||||
if (orbit.Eccentricity != 0 && primaryBody.GetGravityVolume() != null)
|
|
||||||
{
|
{
|
||||||
// Calculate speed at apoapsis
|
initialMotion.SetPrimaryBody(primaryBody.GetAttachedOWRigidbody());
|
||||||
KeplerElements kepler = KeplerElements.FromOrbitModule(orbit);
|
var gv = primaryBody.GetGravityVolume();
|
||||||
Gravity gravity = new Gravity(primaryBody.GetGravityVolume());
|
if(gv != null)
|
||||||
|
{
|
||||||
var eccSpeed = OrbitalHelper.GetOrbitalVelocity(kepler.Apoapsis, gravity, kepler);
|
var velocity = OrbitalHelper.GetVelocity(new OrbitalHelper.Gravity(primaryBody.GetGravityVolume()), orbit);
|
||||||
var circularSpeed = OWPhysics.CalculateOrbitVelocity(primaryBody.GetAttachedOWRigidbody(), OWRB).magnitude;
|
initialMotion._initLinearDirection = velocity.normalized;
|
||||||
|
initialMotion._initLinearSpeed = velocity.magnitude;
|
||||||
initialMotion.SetValue("_orbitImpulseScalar", eccSpeed / circularSpeed);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rotation
|
// 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;
|
var rotationAxis = Quaternion.AngleAxis(orbit.AxialTilt + orbit.Inclination, Vector3.right) * Vector3.up;
|
||||||
body.transform.rotation = Quaternion.FromToRotation(Vector3.up, rotationAxis);
|
body.transform.rotation = Quaternion.FromToRotation(Vector3.up, rotationAxis);
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,7 @@ namespace NewHorizons.Builder.Orbital
|
|||||||
OrbitLine orbitLine;
|
OrbitLine orbitLine;
|
||||||
if (config.Orbit.Eccentricity == 0)
|
if (config.Orbit.Eccentricity == 0)
|
||||||
{
|
{
|
||||||
orbitLine = orbitGO.AddComponent<OrbitLine>();
|
orbitLine = orbitGO.AddComponent<ParameterizedOrbitLine>();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@ -219,6 +219,8 @@ namespace NewHorizons
|
|||||||
|
|
||||||
Logger.Log($"Begin generation sequence of [{body.Config.Name}]");
|
Logger.Log($"Begin generation sequence of [{body.Config.Name}]");
|
||||||
|
|
||||||
|
body.Config.Orbit.AxialTilt = 0;
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
@ -227,9 +229,7 @@ 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);
|
||||||
|
|
||||||
var positionVector = OrbitalHelper.RotateTo(Vector3.left * body.Config.Orbit.SemiMajorAxis * (1 + body.Config.Orbit.Eccentricity), body.Config.Orbit);
|
var outputTuple = BaseBuilder.Make(go, primaryBody, body.Config);
|
||||||
|
|
||||||
var outputTuple = BaseBuilder.Make(go, primaryBody, positionVector, body.Config);
|
|
||||||
var ao = (AstroObject)outputTuple.Item1;
|
var ao = (AstroObject)outputTuple.Item1;
|
||||||
var owRigidBody = (OWRigidbody)outputTuple.Item2;
|
var owRigidBody = (OWRigidbody)outputTuple.Item2;
|
||||||
|
|
||||||
@ -272,7 +272,7 @@ namespace NewHorizons
|
|||||||
|
|
||||||
// Now that we're done move the planet into place
|
// Now that we're done move the planet into place
|
||||||
go.transform.parent = Locator.GetRootTransform();
|
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)
|
if (go.transform.position.magnitude > FurthestOrbit)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -30,4 +30,9 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="NewHorizons.csproj.user" />
|
<Content Include="NewHorizons.csproj.user" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="PacificEngine.OW_CommonResources">
|
||||||
|
<HintPath>$(OuterWildsModsDirectory)\PacificEngine.OW_CommonResources\PacificEngine.OW_CommonResources.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@ -2,6 +2,7 @@
|
|||||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ProjectView>ProjectFiles</ProjectView>
|
<ProjectView>ProjectFiles</ProjectView>
|
||||||
<OutputPath>C:\Users\Nicholas\AppData\Roaming\OuterWildsModManager\OWML\Mods\xen.NewHorizons</OutputPath>
|
<OutputPath>$(AppData)\OuterWildsModManager\OWML\Mods\xen.NewHorizons</OutputPath>
|
||||||
|
<OuterWildsModsDirectory>$(AppData)\OuterWildsModManager\OWML\Mods</OuterWildsModsDirectory>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -7,7 +7,12 @@ using UnityEngine;
|
|||||||
using NewHorizons.Utility;
|
using NewHorizons.Utility;
|
||||||
using Logger = NewHorizons.Utility.Logger;
|
using Logger = NewHorizons.Utility.Logger;
|
||||||
using NewHorizons.External;
|
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
|
namespace NewHorizons.OrbitalPhysics
|
||||||
{
|
{
|
||||||
public static class OrbitalHelper
|
public static class OrbitalHelper
|
||||||
@ -19,68 +24,97 @@ namespace NewHorizons.OrbitalPhysics
|
|||||||
none
|
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
|
Vector3 pos = Vector3.zero;
|
||||||
var rot = Quaternion.AngleAxis(elements.LongitudeOfAscendingNode + elements.TrueAnomaly + elements.ArgumentOfPeriapsis + 180f, Vector3.up);
|
if(orbit.SemiMajorAxis != 0)
|
||||||
if (elements.Eccentricity != 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;
|
Logger.Log($"Position : {pos}");
|
||||||
var incRot = Quaternion.AngleAxis(elements.Inclination, incAxis);
|
return pos;
|
||||||
|
|
||||||
return rot * incRot * vector;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vector3 VelocityDirection(Vector3 separation, KeplerElements elements)
|
Logger.Log($"Position : {pos}");
|
||||||
{
|
return pos;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float GetOrbitalVelocity(float distance, Gravity gravity, KeplerElements kepler)
|
public static Vector3 GetPositionFromTrueAnomaly(float eccentricity, float semiMajorAxis, float inclination, float argumentOfPeriapsis, float longitudeOfAscendingNode, float trueAnomaly)
|
||||||
{
|
{
|
||||||
if (kepler.Eccentricity == 0) return GetCircularOrbitVelocity(distance, gravity, kepler);
|
Vector3 pos = Vector3.zero;
|
||||||
|
if (semiMajorAxis != 0)
|
||||||
if (gravity.Exponent == 2)
|
|
||||||
{
|
{
|
||||||
return Mathf.Sqrt(GravityVolume.GRAVITATIONAL_CONSTANT * gravity.Mass * (2f / distance - 1f / kepler.SemiMajorAxis));
|
var crGravity = new CRGravity(GravityVolume.GRAVITATIONAL_CONSTANT, 1f, 100f);
|
||||||
}
|
var kepler = KeplerCoordinates.fromTrueAnomaly(eccentricity, semiMajorAxis, inclination + 90, argumentOfPeriapsis, longitudeOfAscendingNode, trueAnomaly);
|
||||||
if(gravity.Exponent == 1)
|
pos = PacificEngine.OW_CommonResources.Geometry.Orbits.OrbitHelper.toCartesian(crGravity, 0f, kepler).Item1;
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float GetCircularOrbitVelocity(float distance, Gravity gravity, KeplerElements kepler)
|
Logger.Log($"Position : {pos}");
|
||||||
{
|
return pos;
|
||||||
if (gravity.Exponent == 2)
|
|
||||||
{
|
|
||||||
return Mathf.Sqrt(GravityVolume.GRAVITATIONAL_CONSTANT * gravity.Mass / distance);
|
|
||||||
}
|
}
|
||||||
if(gravity.Exponent == 1)
|
|
||||||
|
public static Vector3 GetPositionFromEccentricAnomaly(float eccentricity, float semiMajorAxis, float inclination, float argumentOfPeriapsis, float longitudeOfAscendingNode, float eccentricAnomaly)
|
||||||
{
|
{
|
||||||
return Mathf.Sqrt(GravityVolume.GRAVITATIONAL_CONSTANT * gravity.Mass);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.Log($"Position : {pos}");
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector3 GetVelocity(Gravity gravity, OrbitModule orbit)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
Exponent = exponent;
|
||||||
|
Mass = mass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Gravity(GravityVolume gv)
|
||||||
|
{
|
||||||
|
Exponent = gv.GetFalloffExponent();
|
||||||
|
Mass = gv.GetStandardGravitationalParameter() / GravityVolume.GRAVITATIONAL_CONSTANT;
|
||||||
}
|
}
|
||||||
Logger.LogError($"Invalid exponent {gravity.Exponent}");
|
|
||||||
return 0f;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
using System;
|
using NewHorizons.External;
|
||||||
|
using PacificEngine.OW_CommonResources.Geometry.Orbits;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@ -8,6 +10,51 @@ namespace NewHorizons.OrbitalPhysics
|
|||||||
{
|
{
|
||||||
public class ParameterizedAstroObject : AstroObject
|
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}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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<OWRigidbody>();
|
|
||||||
}
|
|
||||||
|
|
||||||
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<AstroObject>();
|
|
||||||
}
|
|
||||||
|
|
||||||
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<InitialMotion>() != null)
|
|
||||||
{
|
|
||||||
var primaryVel = _primary.GetComponent<InitialMotion>().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;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -11,118 +11,25 @@ using Logger = NewHorizons.Utility.Logger;
|
|||||||
|
|
||||||
namespace NewHorizons.OrbitalPhysics
|
namespace NewHorizons.OrbitalPhysics
|
||||||
{
|
{
|
||||||
public class ParameterizedOrbitLine : OrbitLine
|
public class ParameterizedOrbitLine : EllipticOrbitLine
|
||||||
{
|
{
|
||||||
/*
|
public ParameterizedAstroObject astroObject;
|
||||||
protected override void InitializeLineRenderer()
|
|
||||||
{
|
|
||||||
base.GetComponent<LineRenderer>().positionCount = this._numVerts;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnValidate()
|
public override void Start()
|
||||||
{
|
|
||||||
if (_numVerts < 0 || _numVerts > 4096)
|
|
||||||
{
|
|
||||||
_numVerts = Mathf.Clamp(this._numVerts, 0, 4096);
|
|
||||||
}
|
|
||||||
if (base.GetComponent<LineRenderer>().positionCount != _numVerts)
|
|
||||||
{
|
|
||||||
InitializeLineRenderer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Start()
|
|
||||||
{
|
{
|
||||||
base.Start();
|
base.Start();
|
||||||
_verts = new Vector3[_numVerts];
|
|
||||||
base.enabled = false;
|
astroObject = _astroObject as ParameterizedAstroObject;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
_semiMajorAxis = periapsis.normalized * a;
|
||||||
|
_semiMinorAxis = semiMinorDecending.normalized * b;
|
||||||
|
_upAxisDir = Vector3.Cross(_semiMajorAxis, _semiMinorAxis).normalized;
|
||||||
|
_fociDistance = Mathf.Sqrt(a * a - b * b);
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
_initialMotion = (_astroObject != null) ? _astroObject.GetComponent<InitialMotion>() : null;
|
|
||||||
_primary = (_astroObject != null) ? _astroObject.GetPrimaryBody() : null;
|
|
||||||
|
|
||||||
_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 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}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -72,10 +72,10 @@ namespace NewHorizons.OrbitalPhysics
|
|||||||
var v = _vertices[i - 1];
|
var v = _vertices[i - 1];
|
||||||
_vertices[i] = new Vector3(v.x, v.y, v.z);
|
_vertices[i] = new Vector3(v.x, v.y, v.z);
|
||||||
}
|
}
|
||||||
_vertices[0] = transform.parent.position - origin;
|
|
||||||
_lineRenderer.SetPositions(_vertices);
|
|
||||||
_timer = 0;
|
_timer = 0;
|
||||||
}
|
}
|
||||||
|
_vertices[0] = transform.parent.position - origin;
|
||||||
|
_lineRenderer.SetPositions(_vertices);
|
||||||
|
|
||||||
base.transform.position = origin;
|
base.transform.position = origin;
|
||||||
base.transform.rotation = Quaternion.AngleAxis(0f, Vector3.up);
|
base.transform.rotation = Quaternion.AngleAxis(0f, Vector3.up);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user