Attempt 1

This commit is contained in:
Nick J. Connors 2021-12-28 15:47:35 -05:00
parent 02510f3820
commit 4e6b6c4768
15 changed files with 194 additions and 510 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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