diff --git a/NewHorizons/Atmosphere/AirBuilder.cs b/NewHorizons/Builder/Atmosphere/AirBuilder.cs similarity index 100% rename from NewHorizons/Atmosphere/AirBuilder.cs rename to NewHorizons/Builder/Atmosphere/AirBuilder.cs diff --git a/NewHorizons/Atmosphere/AtmosphereBuilder.cs b/NewHorizons/Builder/Atmosphere/AtmosphereBuilder.cs similarity index 100% rename from NewHorizons/Atmosphere/AtmosphereBuilder.cs rename to NewHorizons/Builder/Atmosphere/AtmosphereBuilder.cs diff --git a/NewHorizons/Atmosphere/CloudsBuilder.cs b/NewHorizons/Builder/Atmosphere/CloudsBuilder.cs similarity index 100% rename from NewHorizons/Atmosphere/CloudsBuilder.cs rename to NewHorizons/Builder/Atmosphere/CloudsBuilder.cs diff --git a/NewHorizons/Atmosphere/EffectsBuilder.cs b/NewHorizons/Builder/Atmosphere/EffectsBuilder.cs similarity index 100% rename from NewHorizons/Atmosphere/EffectsBuilder.cs rename to NewHorizons/Builder/Atmosphere/EffectsBuilder.cs diff --git a/NewHorizons/Atmosphere/FogBuilder.cs b/NewHorizons/Builder/Atmosphere/FogBuilder.cs similarity index 100% rename from NewHorizons/Atmosphere/FogBuilder.cs rename to NewHorizons/Builder/Atmosphere/FogBuilder.cs diff --git a/NewHorizons/Atmosphere/SunOverrideBuilder.cs b/NewHorizons/Builder/Atmosphere/SunOverrideBuilder.cs similarity index 100% rename from NewHorizons/Atmosphere/SunOverrideBuilder.cs rename to NewHorizons/Builder/Atmosphere/SunOverrideBuilder.cs diff --git a/NewHorizons/Atmosphere/VolumesBuilder.cs b/NewHorizons/Builder/Atmosphere/VolumesBuilder.cs similarity index 100% rename from NewHorizons/Atmosphere/VolumesBuilder.cs rename to NewHorizons/Builder/Atmosphere/VolumesBuilder.cs diff --git a/NewHorizons/Body/AsteroidBeltBuilder.cs b/NewHorizons/Builder/Body/AsteroidBeltBuilder.cs similarity index 98% rename from NewHorizons/Body/AsteroidBeltBuilder.cs rename to NewHorizons/Builder/Body/AsteroidBeltBuilder.cs index 29eb7668..dec67cfe 100644 --- a/NewHorizons/Body/AsteroidBeltBuilder.cs +++ b/NewHorizons/Builder/Body/AsteroidBeltBuilder.cs @@ -10,7 +10,7 @@ using UnityEngine; using Logger = NewHorizons.Utility.Logger; using Random = UnityEngine.Random; -namespace NewHorizons.Body +namespace NewHorizons.Builder.Body { static class AsteroidBeltBuilder { diff --git a/NewHorizons/Body/BlackHoleBuilder.cs b/NewHorizons/Builder/Body/BlackHoleBuilder.cs similarity index 97% rename from NewHorizons/Body/BlackHoleBuilder.cs rename to NewHorizons/Builder/Body/BlackHoleBuilder.cs index 65b86a43..850651b4 100644 --- a/NewHorizons/Body/BlackHoleBuilder.cs +++ b/NewHorizons/Builder/Body/BlackHoleBuilder.cs @@ -6,7 +6,7 @@ using System.Text; using System.Threading.Tasks; using UnityEngine; -namespace NewHorizons.General +namespace NewHorizons.Builder.Body { static class BlackHoleBuilder { diff --git a/NewHorizons/Body/CometTailBuilder.cs b/NewHorizons/Builder/Body/CometTailBuilder.cs similarity index 96% rename from NewHorizons/Body/CometTailBuilder.cs rename to NewHorizons/Builder/Body/CometTailBuilder.cs index f7b61510..fd349451 100644 --- a/NewHorizons/Body/CometTailBuilder.cs +++ b/NewHorizons/Builder/Body/CometTailBuilder.cs @@ -7,7 +7,7 @@ using System.Text; using System.Threading.Tasks; using UnityEngine; -namespace NewHorizons.Body +namespace NewHorizons.Builder.Body { public static class CometTailBuilder { diff --git a/NewHorizons/Body/Geometry/CubeSphere.cs b/NewHorizons/Builder/Body/Geometry/CubeSphere.cs similarity index 100% rename from NewHorizons/Body/Geometry/CubeSphere.cs rename to NewHorizons/Builder/Body/Geometry/CubeSphere.cs diff --git a/NewHorizons/Body/Geometry/Icosphere.cs b/NewHorizons/Builder/Body/Geometry/Icosphere.cs similarity index 100% rename from NewHorizons/Body/Geometry/Icosphere.cs rename to NewHorizons/Builder/Body/Geometry/Icosphere.cs diff --git a/NewHorizons/Body/Geometry/Perlin.cs b/NewHorizons/Builder/Body/Geometry/Perlin.cs similarity index 100% rename from NewHorizons/Body/Geometry/Perlin.cs rename to NewHorizons/Builder/Body/Geometry/Perlin.cs diff --git a/NewHorizons/Body/GeometryBuilder.cs b/NewHorizons/Builder/Body/GeometryBuilder.cs similarity index 95% rename from NewHorizons/Body/GeometryBuilder.cs rename to NewHorizons/Builder/Body/GeometryBuilder.cs index 3e25a7dd..1f0d4c82 100644 --- a/NewHorizons/Body/GeometryBuilder.cs +++ b/NewHorizons/Builder/Body/GeometryBuilder.cs @@ -1,7 +1,7 @@ using UnityEngine; using Logger = NewHorizons.Utility.Logger; -namespace NewHorizons.Body +namespace NewHorizons.Builder.Body { static class GeometryBuilder { diff --git a/NewHorizons/Body/HeightMapBuilder.cs b/NewHorizons/Builder/Body/HeightMapBuilder.cs similarity index 95% rename from NewHorizons/Body/HeightMapBuilder.cs rename to NewHorizons/Builder/Body/HeightMapBuilder.cs index c4f6c66e..58ef8d21 100644 --- a/NewHorizons/Body/HeightMapBuilder.cs +++ b/NewHorizons/Builder/Body/HeightMapBuilder.cs @@ -1,4 +1,5 @@ -using NewHorizons.Body.Geometry; +using NewHorizons.Body; +using NewHorizons.Body.Geometry; using NewHorizons.External; using OWML.Common; using System; @@ -9,7 +10,7 @@ using System.Threading.Tasks; using UnityEngine; using Logger = NewHorizons.Utility.Logger; -namespace NewHorizons.Body +namespace NewHorizons.Builder.Body { static class HeightMapBuilder { diff --git a/NewHorizons/Body/LavaBuilder.cs b/NewHorizons/Builder/Body/LavaBuilder.cs similarity index 98% rename from NewHorizons/Body/LavaBuilder.cs rename to NewHorizons/Builder/Body/LavaBuilder.cs index e38b9e68..44e1230b 100644 --- a/NewHorizons/Body/LavaBuilder.cs +++ b/NewHorizons/Builder/Body/LavaBuilder.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; using UnityEngine; using Logger = NewHorizons.Utility.Logger; -namespace NewHorizons.General +namespace NewHorizons.Builder.Body { static class LavaBuilder { diff --git a/NewHorizons/Body/ProcGenBuilder.cs b/NewHorizons/Builder/Body/ProcGenBuilder.cs similarity index 97% rename from NewHorizons/Body/ProcGenBuilder.cs rename to NewHorizons/Builder/Body/ProcGenBuilder.cs index 258c1407..4561e19a 100644 --- a/NewHorizons/Body/ProcGenBuilder.cs +++ b/NewHorizons/Builder/Body/ProcGenBuilder.cs @@ -7,7 +7,7 @@ using System.Text; using System.Threading.Tasks; using UnityEngine; -namespace NewHorizons.Body +namespace NewHorizons.Builder.Body { static class ProcGenBuilder { diff --git a/NewHorizons/Body/RingBuilder.cs b/NewHorizons/Builder/Body/RingBuilder.cs similarity index 98% rename from NewHorizons/Body/RingBuilder.cs rename to NewHorizons/Builder/Body/RingBuilder.cs index e5234a28..03df9906 100644 --- a/NewHorizons/Body/RingBuilder.cs +++ b/NewHorizons/Builder/Body/RingBuilder.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; using UnityEngine; using Logger = NewHorizons.Utility.Logger; -namespace NewHorizons.General +namespace NewHorizons.Builder.Body { static class RingBuilder { diff --git a/NewHorizons/Body/StarBuilder.cs b/NewHorizons/Builder/Body/StarBuilder.cs similarity index 96% rename from NewHorizons/Body/StarBuilder.cs rename to NewHorizons/Builder/Body/StarBuilder.cs index d2051d1a..3f3e49ba 100644 --- a/NewHorizons/Body/StarBuilder.cs +++ b/NewHorizons/Builder/Body/StarBuilder.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; using UnityEngine; using Logger = NewHorizons.Utility.Logger; -namespace NewHorizons.Body +namespace NewHorizons.Builder.Body { static class StarBuilder { @@ -74,10 +74,10 @@ namespace NewHorizons.Body var giantMaterial = sun.GetComponent().GetValue("_endSurfaceMaterial"); surface.sharedMaterial = new Material(starModule.Size >= 3000 ? giantMaterial : mainSequenceMaterial); - surface.sharedMaterial.color = new Color(colour.r * 4f / 255f, colour.g * 4f / 255f, colour.b * 4f / 255f); + surface.sharedMaterial.color = new Color(colour.r * 8f / 255f, colour.g * 8f / 255f, colour.b * 8f / 255f); surface.sharedMaterial.SetTexture("_ColorRamp", Utility.ImageUtilities.TintImage(_colorOverTime, colour)); - sunAtmosphere.transform.Find("AtmoSphere").transform.localScale = Vector3.one * 2f; + sunAtmosphere.transform.Find("AtmoSphere").transform.localScale = Vector3.one * (starModule.Size + 1000)/starModule.Size; foreach (var lod in sunAtmosphere.transform.Find("AtmoSphere").GetComponentsInChildren()) { lod.material.SetColor("_SkyColor", colour); diff --git a/NewHorizons/Body/WaterBuilder.cs b/NewHorizons/Builder/Body/WaterBuilder.cs similarity index 99% rename from NewHorizons/Body/WaterBuilder.cs rename to NewHorizons/Builder/Body/WaterBuilder.cs index 704d7a7b..7fcd5c6f 100644 --- a/NewHorizons/Body/WaterBuilder.cs +++ b/NewHorizons/Builder/Body/WaterBuilder.cs @@ -3,7 +3,7 @@ using OWML.Utils; using UnityEngine; using Logger = NewHorizons.Utility.Logger; -namespace NewHorizons.Body +namespace NewHorizons.Builder.Body { static class WaterBuilder { diff --git a/NewHorizons/General/AmbientLightBuilder.cs b/NewHorizons/Builder/General/AmbientLightBuilder.cs similarity index 95% rename from NewHorizons/General/AmbientLightBuilder.cs rename to NewHorizons/Builder/General/AmbientLightBuilder.cs index 572c9c9e..d79c380e 100644 --- a/NewHorizons/General/AmbientLightBuilder.cs +++ b/NewHorizons/Builder/General/AmbientLightBuilder.cs @@ -4,7 +4,7 @@ using OWML.Utils; using UnityEngine; using Logger = NewHorizons.Utility.Logger; -namespace NewHorizons.General +namespace NewHorizons.Builder.General { static class AmbientLightBuilder { diff --git a/NewHorizons/General/BaseBuilder.cs b/NewHorizons/Builder/General/BaseBuilder.cs similarity index 71% rename from NewHorizons/General/BaseBuilder.cs rename to NewHorizons/Builder/General/BaseBuilder.cs index 275cb77d..47889823 100644 --- a/NewHorizons/General/BaseBuilder.cs +++ b/NewHorizons/Builder/General/BaseBuilder.cs @@ -2,14 +2,15 @@ using NewHorizons.OrbitalPhysics; using NewHorizons.Utility; using OWML.Utils; +using System; using UnityEngine; using Logger = NewHorizons.Utility.Logger; -namespace NewHorizons.General +namespace NewHorizons.Builder.General { static class BaseBuilder { - public static MTuple Make(GameObject body, AstroObject primaryBody, Vector3 positionVector, IPlanetConfig config) + public static Tuple Make(GameObject body, AstroObject primaryBody, Vector3 positionVector, IPlanetConfig config) { Rigidbody RB = body.AddComponent(); RB.mass = 10000; @@ -31,10 +32,14 @@ namespace NewHorizons.General OWRB.SetValue("_rigidbody", RB); OWRB.SetValue("_kinematicRigidbody", KRB); - DetectorBuilder.Make(body, primaryBody); - AstroObject AO = body.AddComponent(); - AO.SetValue("_type", config.Orbit.IsMoon ? AstroObject.Type.Moon : AstroObject.Type.Planet); + + 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); @@ -46,7 +51,7 @@ namespace NewHorizons.General alignment.SetValue("_usePhysicsToRotate", true); } - return new MTuple(AO, OWRB); + return new Tuple(AO, OWRB); } } } diff --git a/NewHorizons/Builder/General/DetectorBuilder.cs b/NewHorizons/Builder/General/DetectorBuilder.cs new file mode 100644 index 00000000..e1a9ab5e --- /dev/null +++ b/NewHorizons/Builder/General/DetectorBuilder.cs @@ -0,0 +1,147 @@ +using NewHorizons.Builder.Orbital; +using NewHorizons.External; +using NewHorizons.OrbitalPhysics; +using OWML.Utils; +using System; +using System.Collections.Generic; +using System.Reflection; +using UnityEngine; +using NewHorizons.Utility; +using Logger = NewHorizons.Utility.Logger; + +namespace NewHorizons.Builder.General +{ + static class DetectorBuilder + { + public static void Make(GameObject body, OWRigidbody OWRB, AstroObject primaryBody, AstroObject astroObject) + { + GameObject detectorGO = new GameObject("FieldDetector"); + detectorGO.SetActive(false); + detectorGO.transform.parent = body.transform; + detectorGO.transform.localPosition = Vector3.zero; + detectorGO.layer = 20; + + ConstantForceDetector forceDetector = detectorGO.AddComponent(); + forceDetector.SetValue("_inheritElement0", true); + OWRB.RegisterAttachedForceDetector(forceDetector); + + GravityVolume parentGravityVolume = primaryBody.GetAttachedOWRigidbody().GetAttachedGravityVolume(); + if (parentGravityVolume != null) + { + forceDetector.SetValue("_detectableFields", new ForceVolume[] { parentGravityVolume }); + } + else + { + // It's probably a focal point (or its just broken) + var binaryFocalPoint = primaryBody.gameObject.GetComponent(); + if(binaryFocalPoint != null) + { + if(astroObject.GetCustomName().Equals(binaryFocalPoint.PrimaryName)) { + binaryFocalPoint.Primary = astroObject; + if (binaryFocalPoint.Secondary != null) + { + var secondaryRB = binaryFocalPoint.Secondary.GetAttachedOWRigidbody(); + SetBinaryForceDetectableFields(binaryFocalPoint, forceDetector, secondaryRB.GetAttachedForceDetector(), OWRB, secondaryRB); + } + } + else if (astroObject.GetCustomName().Equals(binaryFocalPoint.SecondaryName)) + { + binaryFocalPoint.Secondary = astroObject; + if (binaryFocalPoint.Primary != null) + { + var primaryRB = binaryFocalPoint.Primary.GetAttachedOWRigidbody(); + SetBinaryForceDetectableFields(binaryFocalPoint, primaryRB.GetAttachedForceDetector(), forceDetector, primaryRB, OWRB); + } + } + else + { + // It's a planet + binaryFocalPoint.Planets.Add(astroObject); + if(binaryFocalPoint.Primary != null && binaryFocalPoint.Secondary != null) + { + var primaryGravityVolume = binaryFocalPoint.Primary.GetGravityVolume(); + var secondaryGravityVolume = binaryFocalPoint.Secondary.GetGravityVolume(); + forceDetector.SetValue("_detectableFields", new ForceVolume[] { primaryGravityVolume, secondaryGravityVolume }); + } + } + } + } + + detectorGO.SetActive(true); + } + + private static void SetBinaryForceDetectableFields(BinaryFocalPoint point, ForceDetector primaryCFD, ForceDetector secondaryCFD, OWRigidbody primaryRB, OWRigidbody secondaryRB) + { + Logger.Log($"Setting up binary focal point for {point.name}"); + + var primary = point.Primary; + var secondary = point.Secondary; + var planets = point.Planets; + + + // Binaries have to use inverse square gravity so overwrite it now + 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); + + + // Very specific distance between them + Vector3 separation = primary.transform.position - secondary.transform.position; + var Gm1 = primaryGV.GetStandardGravitationalParameter(); + var Gm2 = secondaryGV.GetStandardGravitationalParameter(); + 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; + + // Set detectable fields + primaryCFD.SetValue("_detectableFields", new ForceVolume[] { secondaryGV }); + primaryCFD.SetValue("_inheritDetector", point.GetAttachedOWRigidbody().GetAttachedForceDetector()); + primaryCFD.SetValue("_activeInheritedDetector", point.GetAttachedOWRigidbody().GetAttachedForceDetector()); + primaryCFD.SetValue("_inheritElement0", false); + + secondaryCFD.SetValue("_detectableFields", new ForceVolume[] { primaryGV }); + secondaryCFD.SetValue("_inheritDetector", point.GetAttachedOWRigidbody().GetAttachedForceDetector()); + secondaryCFD.SetValue("_activeInheritedDetector", point.GetAttachedOWRigidbody().GetAttachedForceDetector()); + secondaryCFD.SetValue("_inheritElement0", false); + + // Update speeds + var direction = Vector3.Cross(separation, Vector3.up).normalized; + var m1 = primaryRB.GetMass(); + var m2 = secondaryRB.GetMass(); + var reducedMass = m1 * m2 / (m1 + m2); + 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}"); + + primaryRB.UpdateCenterOfMass(); + primaryRB.AddVelocityChange(direction * v1); + secondaryRB.UpdateCenterOfMass(); + secondaryRB.AddVelocityChange(direction * -v2); + + + + /* + //Hacky but whatever + var primaryInitialMotion = primary.gameObject.GetComponent(); + if(primaryInitialMotion.GetValue("_isInitVelocityDirty")) + primaryInitialMotion.SetValue("_cachedInitVelocity", OWPhysics.CalculateOrbitVelocity(secondaryRB, primaryRB, 0f)); + else + primaryInitialMotion.SetPrimaryBody(secondaryRB); + + var secondaryInitialMotion = primary.gameObject.GetComponent(); + if (secondaryInitialMotion.GetValue("_isInitVelocityDirty")) + secondaryInitialMotion.SetValue("_cachedInitVelocity", OWPhysics.CalculateOrbitVelocity(primaryRB, secondaryRB, 0f)); + else + secondaryInitialMotion.SetPrimaryBody(primaryRB); + */ + } + } +} diff --git a/NewHorizons/General/GravityBuilder.cs b/NewHorizons/Builder/General/GravityBuilder.cs similarity index 97% rename from NewHorizons/General/GravityBuilder.cs rename to NewHorizons/Builder/General/GravityBuilder.cs index 2489c1c8..d859a217 100644 --- a/NewHorizons/General/GravityBuilder.cs +++ b/NewHorizons/Builder/General/GravityBuilder.cs @@ -4,7 +4,7 @@ using System.Reflection; using UnityEngine; using Logger = NewHorizons.Utility.Logger; -namespace NewHorizons.General +namespace NewHorizons.Builder.General { static class GravityBuilder { diff --git a/NewHorizons/General/MarkerBuilder.cs b/NewHorizons/Builder/General/MarkerBuilder.cs similarity index 96% rename from NewHorizons/General/MarkerBuilder.cs rename to NewHorizons/Builder/General/MarkerBuilder.cs index 7c03fe8a..2ef4af4d 100644 --- a/NewHorizons/General/MarkerBuilder.cs +++ b/NewHorizons/Builder/General/MarkerBuilder.cs @@ -4,7 +4,7 @@ using System.Reflection; using UnityEngine; using Logger = NewHorizons.Utility.Logger; -namespace NewHorizons.General +namespace NewHorizons.Builder.General { static class MarkerBuilder { diff --git a/NewHorizons/General/PlanetDestroyer.cs b/NewHorizons/Builder/General/PlanetDestroyer.cs similarity index 99% rename from NewHorizons/General/PlanetDestroyer.cs rename to NewHorizons/Builder/General/PlanetDestroyer.cs index 7a520b9f..d6e46a08 100644 --- a/NewHorizons/General/PlanetDestroyer.cs +++ b/NewHorizons/Builder/General/PlanetDestroyer.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; using UnityEngine; using Logger = NewHorizons.Utility.Logger; -namespace NewHorizons.General +namespace NewHorizons.Builder.General { static class PlanetDestroyer { diff --git a/NewHorizons/General/RFVolumeBuilder.cs b/NewHorizons/Builder/General/RFVolumeBuilder.cs similarity index 97% rename from NewHorizons/General/RFVolumeBuilder.cs rename to NewHorizons/Builder/General/RFVolumeBuilder.cs index a1bf672b..c93811f9 100644 --- a/NewHorizons/General/RFVolumeBuilder.cs +++ b/NewHorizons/Builder/General/RFVolumeBuilder.cs @@ -3,7 +3,7 @@ using OWML.Utils; using UnityEngine; using Logger = NewHorizons.Utility.Logger; -namespace NewHorizons.General +namespace NewHorizons.Builder.General { static class RFVolumeBuilder { diff --git a/NewHorizons/General/SectorBuilder.cs b/NewHorizons/Builder/General/SectorBuilder.cs similarity index 96% rename from NewHorizons/General/SectorBuilder.cs rename to NewHorizons/Builder/General/SectorBuilder.cs index 496e67f4..1545c924 100644 --- a/NewHorizons/General/SectorBuilder.cs +++ b/NewHorizons/Builder/General/SectorBuilder.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; using UnityEngine; using Logger = NewHorizons.Utility.Logger; -namespace NewHorizons.Body +namespace NewHorizons.Builder.General { static class MakeSector { diff --git a/NewHorizons/General/SpawnpointBuilder.cs b/NewHorizons/Builder/General/SpawnPointBuilder.cs similarity index 99% rename from NewHorizons/General/SpawnpointBuilder.cs rename to NewHorizons/Builder/General/SpawnPointBuilder.cs index e462586a..d5cd6c9b 100644 --- a/NewHorizons/General/SpawnpointBuilder.cs +++ b/NewHorizons/Builder/General/SpawnPointBuilder.cs @@ -4,7 +4,7 @@ using System; using UnityEngine; using Logger = NewHorizons.Utility.Logger; -namespace NewHorizons.General +namespace NewHorizons.Builder.General { static class SpawnPointBuilder { diff --git a/NewHorizons/Builder/Orbital/FocalPointBuilder.cs b/NewHorizons/Builder/Orbital/FocalPointBuilder.cs new file mode 100644 index 00000000..a9914828 --- /dev/null +++ b/NewHorizons/Builder/Orbital/FocalPointBuilder.cs @@ -0,0 +1,21 @@ +using NewHorizons.External; +using NewHorizons.OrbitalPhysics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace NewHorizons.Builder.Orbital +{ + static class FocalPointBuilder + { + public static void Make(GameObject go, FocalPointModule module) + { + var binary = go.AddComponent(); + binary.PrimaryName = module.Primary; + binary.SecondaryName = module.Secondary; + } + } +} diff --git a/NewHorizons/General/InitialMotionBuilder.cs b/NewHorizons/Builder/Orbital/InitialMotionBuilder.cs similarity index 54% rename from NewHorizons/General/InitialMotionBuilder.cs rename to NewHorizons/Builder/Orbital/InitialMotionBuilder.cs index c7b94d93..09354ec2 100644 --- a/NewHorizons/General/InitialMotionBuilder.cs +++ b/NewHorizons/Builder/Orbital/InitialMotionBuilder.cs @@ -11,7 +11,7 @@ using Logger = NewHorizons.Utility.Logger; using System.Reflection; using NewHorizons.Utility; -namespace NewHorizons.General +namespace NewHorizons.Builder.Orbital { static class InitialMotionBuilder { @@ -33,23 +33,31 @@ namespace NewHorizons.General */ InitialMotion initialMotion = body.AddComponent(); - initialMotion.SetPrimaryBody(primaryBody.GetAttachedOWRigidbody()); - initialMotion.SetValue("_orbitAngle", orbit.Inclination); - initialMotion.SetValue("_isGlobalAxis", false); - initialMotion.SetValue("_initAngularSpeed", orbit.SiderealPeriod == 0 ? 0.02f : 1.0f / orbit.SiderealPeriod); - if(orbit.Eccentricity != 0) + return Update(initialMotion, body, primaryBody, OWRB, orbit); + } + + public static InitialMotion Update(InitialMotion initialMotion, GameObject body, AstroObject primaryBody, OWRigidbody OWRB, OrbitModule orbit) + { + if (!orbit.IsStatic) { - // Calculate speed at apoapsis - var eccSpeed = OrbitalHelper.Visviva(primaryBody.GetGravityVolume().GetFalloffType(), - primaryBody.GetGravityVolume().GetStandardGravitationalParameter(), - orbit.SemiMajorAxis * (1 + orbit.Eccentricity), - orbit.SemiMajorAxis, - orbit.Eccentricity - ); - var circularSpeed = OWPhysics.CalculateOrbitVelocity(primaryBody.GetAttachedOWRigidbody(), OWRB).magnitude; - initialMotion.SetValue("_orbitImpulseScalar", eccSpeed / circularSpeed); + initialMotion.SetPrimaryBody(primaryBody.GetAttachedOWRigidbody()); + initialMotion.SetValue("_orbitAngle", orbit.Inclination); + initialMotion.SetValue("_isGlobalAxis", false); + if (orbit.Eccentricity != 0 && primaryBody.GetGravityVolume() != null) + { + // Calculate speed at apoapsis + KeplerElements kepler = KeplerElements.FromOrbitModule(orbit); + Gravity gravity = new Gravity(primaryBody.GetGravityVolume()); + + var eccSpeed = OrbitalHelper.GetOrbitalVelocity(kepler.Apoapsis, gravity, kepler); + var circularSpeed = OWPhysics.CalculateOrbitVelocity(primaryBody.GetAttachedOWRigidbody(), OWRB).magnitude; + + initialMotion.SetValue("_orbitImpulseScalar", eccSpeed / circularSpeed); + } } + // Rotation + initialMotion.SetValue("_initAngularSpeed", orbit.SiderealPeriod == 0 ? 0f : 1.0f / orbit.SiderealPeriod); var rotationAxis = Quaternion.AngleAxis(orbit.AxialTilt + orbit.Inclination, Vector3.right) * Vector3.up; body.transform.rotation = Quaternion.FromToRotation(Vector3.up, rotationAxis); diff --git a/NewHorizons/General/OrbitlineBuilder.cs b/NewHorizons/Builder/Orbital/OrbitlineBuilder.cs similarity index 64% rename from NewHorizons/General/OrbitlineBuilder.cs rename to NewHorizons/Builder/Orbital/OrbitlineBuilder.cs index 56b9885f..b163e4c0 100644 --- a/NewHorizons/General/OrbitlineBuilder.cs +++ b/NewHorizons/Builder/Orbital/OrbitlineBuilder.cs @@ -5,7 +5,7 @@ using OWML.Utils; using UnityEngine; using Logger = NewHorizons.Utility.Logger; -namespace NewHorizons.General +namespace NewHorizons.Builder.Orbital { static class OrbitlineBuilder { @@ -15,29 +15,27 @@ namespace NewHorizons.General orbitGO.transform.parent = body.transform; orbitGO.transform.localPosition = Vector3.zero; - var LR = orbitGO.AddComponent(); + var lineRenderer = orbitGO.AddComponent(); - var thLR = GameObject.Find("OrbitLine_CO").GetComponent(); - - LR.material = thLR.material; - LR.useWorldSpace = false; - LR.loop = false; + lineRenderer.material = GameObject.Find("OrbitLine_CO").GetComponent().material; + lineRenderer.useWorldSpace = false; + lineRenderer.loop = false; if(orbit.Eccentricity == 0) { - OrbitLine ol = orbitGO.AddComponent(); - ol.SetValue("_astroObject", astroobject); - ol.SetValue("_fade", isMoon); - ol.SetValue("_lineWidth", 0.5f); - typeof(OrbitLine).GetMethod("InitializeLineRenderer", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(ol, new object[] { }); + OrbitLine orbitLine = orbitGO.AddComponent(); + orbitLine.SetValue("_astroObject", astroobject); + orbitLine.SetValue("_fade", isMoon); + orbitLine.SetValue("_lineWidth", 0.3f); + typeof(OrbitLine).GetMethod("InitializeLineRenderer", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(orbitLine, new object[] { }); } else { - OrbitLine ol = orbitGO.AddComponent(); - ol.SetValue("_astroObject", astroobject); - ol.SetValue("_fade", isMoon); - ol.SetValue("_lineWidth", 0.5f); - typeof(OrbitLine).GetMethod("InitializeLineRenderer", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(ol, new object[] { }); + OrbitLine orbitLine = orbitGO.AddComponent(); + 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[] { }); } /* diff --git a/NewHorizons/External/FocalPointModule.cs b/NewHorizons/External/FocalPointModule.cs new file mode 100644 index 00000000..41a5de50 --- /dev/null +++ b/NewHorizons/External/FocalPointModule.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NewHorizons.External +{ + public class FocalPointModule + { + public string Primary { get; set; } + public string Secondary { get; set; } + } +} diff --git a/NewHorizons/External/IPlanetConfig.cs b/NewHorizons/External/IPlanetConfig.cs index df204a5a..63e26dfe 100644 --- a/NewHorizons/External/IPlanetConfig.cs +++ b/NewHorizons/External/IPlanetConfig.cs @@ -15,6 +15,7 @@ namespace NewHorizons.External ProcGenModule ProcGen { get; } AsteroidBeltModule AsteroidBelt { get; } StarModule Star { get; } + FocalPointModule FocalPoint { get; } SpawnModule Spawn { get; } } } diff --git a/NewHorizons/External/OrbitModule.cs b/NewHorizons/External/OrbitModule.cs index 869bf0cd..39508ab8 100644 --- a/NewHorizons/External/OrbitModule.cs +++ b/NewHorizons/External/OrbitModule.cs @@ -20,5 +20,6 @@ namespace NewHorizons.External public float SiderealPeriod { get; set; } public bool IsTidallyLocked { get; set; } public bool ShowOrbitLine { get; set; } = true; + public bool IsStatic { get; set; } } } diff --git a/NewHorizons/External/PlanetConfig.cs b/NewHorizons/External/PlanetConfig.cs index 76dddcdc..87bf8b0f 100644 --- a/NewHorizons/External/PlanetConfig.cs +++ b/NewHorizons/External/PlanetConfig.cs @@ -1,6 +1,7 @@ using NewHorizons.Utility; using System; using System.Collections.Generic; +using System.Globalization; namespace NewHorizons.External { @@ -18,6 +19,7 @@ namespace NewHorizons.External public ProcGenModule ProcGen { get; set; } public AsteroidBeltModule AsteroidBelt { get; set; } public StarModule Star { get; set; } + public FocalPointModule FocalPoint { get; set; } public SpawnModule Spawn { get; set; } public PlanetConfig(Dictionary dict) @@ -30,6 +32,31 @@ namespace NewHorizons.External foreach (var item in dict) { + var property = typeof(PlanetConfig).GetProperty(item.Key, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance); + if(property == null) + property = typeof(PlanetConfig).GetProperty(item.Key.ToCamelCase(), System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance); + if (property == null) + property = typeof(PlanetConfig).GetProperty(item.Key.ToTitleCase(), System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance); + + if (property != null) + { + if (property.PropertyType.BaseType == typeof(Module)) + { + if (property.GetValue(this) == null) + { + var module = Activator.CreateInstance(property.PropertyType); + property.SetValue(this, module); + } + ((Module)property.GetValue(this)).Build(item.Value as Dictionary); + } + else + { + property.SetValue(this, Convert.ChangeType(item.Value, property.PropertyType)); + } + } + else Logger.LogError($"{item.Key} {item.Value} is not valid. Is your config formatted correctly?"); + + /* switch(item.Key) { case "Base": @@ -68,6 +95,7 @@ namespace NewHorizons.External else Logger.LogError($"{item.Key} {item.Value} is not valid. Is your config formatted correctly?"); break; } + */ } } } diff --git a/NewHorizons/General/DetectorBuilder.cs b/NewHorizons/General/DetectorBuilder.cs deleted file mode 100644 index 1857cd1a..00000000 --- a/NewHorizons/General/DetectorBuilder.cs +++ /dev/null @@ -1,28 +0,0 @@ -using OWML.Utils; -using System; -using UnityEngine; -using Logger = NewHorizons.Utility.Logger; - -namespace NewHorizons.General -{ - static class DetectorBuilder - { - public static void Make(GameObject body, AstroObject primaryBody) - { - GameObject detectorGO = new GameObject("FieldDetector"); - detectorGO.SetActive(false); - detectorGO.transform.parent = body.transform; - detectorGO.transform.localPosition = Vector3.zero; - detectorGO.layer = 20; - - ConstantForceDetector CFD = detectorGO.AddComponent(); - - GravityVolume parentGravityVolume = primaryBody.GetAttachedOWRigidbody().GetAttachedGravityVolume(); - - CFD.SetValue("_detectableFields", new ForceVolume[] { parentGravityVolume }); - CFD.SetValue("_inheritElement0", true); - - detectorGO.SetActive(true); - } - } -} diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index 0f86dbe6..c974e9b0 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -1,7 +1,9 @@ using NewHorizons.Atmosphere; using NewHorizons.Body; +using NewHorizons.Builder.Body; +using NewHorizons.Builder.General; +using NewHorizons.Builder.Orbital; using NewHorizons.External; -using NewHorizons.General; using NewHorizons.OrbitalPhysics; using NewHorizons.Utility; using OWML.Common; @@ -34,7 +36,7 @@ namespace NewHorizons return new NewHorizonsApi(); } - void Start() + public void Start() { SceneManager.sceneLoaded += OnSceneLoaded; Instance = this; @@ -54,8 +56,9 @@ namespace NewHorizons } } - void Destroy() + public void Destroy() { + Logger.Log($"Destroying NewHorizons"); SceneManager.sceneLoaded -= OnSceneLoaded; } @@ -73,9 +76,11 @@ namespace NewHorizons // Stars then planets then moons BodyList = BodyList.OrderBy(b => - (b.Config.BuildPriority != -1 ? b.Config.BuildPriority : (b.Config.Star != null) ? 0 : + (b.Config.BuildPriority != -1 ? b.Config.BuildPriority : + (b.Config.FocalPoint != null ? 0 : + (b.Config.Star != null) ? 0 : (b.Config.Orbit.IsMoon ? 2 : 1) - )).ToList(); + ))).ToList(); var flagNoneLoadedThisPass = true; while(BodyList.Count != 0) @@ -248,14 +253,14 @@ namespace NewHorizons var positionVector = rot * incRot * Vector3.left * body.Config.Orbit.SemiMajorAxis * (1 + body.Config.Orbit.Eccentricity); var outputTuple = BaseBuilder.Make(go, primaryBody, positionVector, body.Config); - var ao = (AstroObject)outputTuple.Items[0]; - var rb = (OWRigidbody)outputTuple.Items[1]; + var ao = (AstroObject)outputTuple.Item1; + var owRigidBody = (OWRigidbody)outputTuple.Item2; if (body.Config.Base.SurfaceGravity != 0) GravityBuilder.Make(go, ao, body.Config.Base.SurfaceGravity, sphereOfInfluence, body.Config.Base.SurfaceSize, body.Config.Base.GravityFallOff); if(body.Config.Base.HasReferenceFrame) - RFVolumeBuilder.Make(go, rb, sphereOfInfluence); + RFVolumeBuilder.Make(go, owRigidBody, sphereOfInfluence); if (body.Config.Base.HasMapMarker) MarkerBuilder.Make(go, body.Config.Name, body.Config.Orbit.IsMoon, body.Config.Star != null); @@ -263,7 +268,8 @@ namespace NewHorizons if (body.Config.Base.HasAmbientLight) AmbientLightBuilder.Make(go, sphereOfInfluence); - var sector = MakeSector.Make(go, rb, sphereOfInfluence); + var sector = MakeSector.Make(go, owRigidBody, sphereOfInfluence); + ao.SetValue("_rootSector", sector); VolumesBuilder.Make(go, body.Config.Base.SurfaceSize, sphereOfInfluence); @@ -279,15 +285,14 @@ namespace NewHorizons if (body.Config.Star != null) StarBuilder.Make(go, sector, body.Config.Star); + if (body.Config.FocalPoint != null) + FocalPointBuilder.Make(go, body.Config.FocalPoint); + // Do stuff that's shared between generating new planets and updating old ones - go = SharedGenerateBody(body, go, sector, rb); + go = SharedGenerateBody(body, go, sector, owRigidBody); body.Object = go; - // 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)); - // Now that we're done move the planet into place go.transform.parent = Locator.GetRootTransform(); go.transform.position = positionVector + primaryBody.transform.position; @@ -298,14 +303,22 @@ namespace NewHorizons } // Have to do this after setting position - InitialMotionBuilder.Make(go, primaryBody, rb, body.Config.Orbit); + InitialMotionBuilder.Make(go, primaryBody, owRigidBody, body.Config.Orbit); + + //if (!body.Config.Orbit.IsStatic) DetectorBuilder.Make(go, owRigidBody, primaryBody, ao); + if (!body.Config.Orbit.IsStatic) Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => DetectorBuilder.Make(go, owRigidBody, primaryBody, ao)); // Spawning on other planets is a bit hacky so we do it last if (body.Config.Spawn != null) { - SpawnPointBuilder.Make(go, body.Config.Spawn, rb); + 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 (ao.GetAstroObjectName() == AstroObject.Name.CustomString) AstroObjectLocator.RegisterCustomAstroObject(ao); Logger.Log("Generation of [" + body.Config.Name + "] completed.", Logger.LogType.Log); diff --git a/NewHorizons/NewHorizons.csproj b/NewHorizons/NewHorizons.csproj index 95b34c81..a192eb3d 100644 --- a/NewHorizons/NewHorizons.csproj +++ b/NewHorizons/NewHorizons.csproj @@ -229,18 +229,20 @@ - - - - - - - - - + + + + + + + + + + + @@ -248,34 +250,37 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - + - - - - - - - - + + + + + + + + @@ -288,7 +293,6 @@ - diff --git a/NewHorizons/OrbitalPhysics/BinaryFocalPoint.cs b/NewHorizons/OrbitalPhysics/BinaryFocalPoint.cs new file mode 100644 index 00000000..c8e6a716 --- /dev/null +++ b/NewHorizons/OrbitalPhysics/BinaryFocalPoint.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace NewHorizons.OrbitalPhysics +{ + public class BinaryFocalPoint : MonoBehaviour + { + public string PrimaryName = null; + public string SecondaryName = null; + + public AstroObject Primary = null; + public AstroObject Secondary = null; + + public List Planets { get; private set; } = new List(); + } +} diff --git a/NewHorizons/OrbitalPhysics/Gravity.cs b/NewHorizons/OrbitalPhysics/Gravity.cs new file mode 100644 index 00000000..f63667c0 --- /dev/null +++ b/NewHorizons/OrbitalPhysics/Gravity.cs @@ -0,0 +1,27 @@ +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; + } + } +} diff --git a/NewHorizons/OrbitalPhysics/KeplerElements.cs b/NewHorizons/OrbitalPhysics/KeplerElements.cs new file mode 100644 index 00000000..65c30e7d --- /dev/null +++ b/NewHorizons/OrbitalPhysics/KeplerElements.cs @@ -0,0 +1,101 @@ +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; } + public float EccentricAnomaly { get; } + public float MeanAnomaly { get; } + 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 eccentricAnomaly = EccentricAnomalyFromTrueAnomaly(trueAnomaly, e); + var meanAnomaly = MeanAnomalyFromEccentricAnomaly(eccentricAnomaly, e); + return new KeplerElements(e, a, i, longitudeOfAscendingNode, argumentOfPeriapsis, trueAnomaly, eccentricAnomaly, meanAnomaly); + } + + 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); + } + + 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); + } + + 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; + } + } +} diff --git a/NewHorizons/OrbitalPhysics/OrbitalHelper.cs b/NewHorizons/OrbitalPhysics/OrbitalHelper.cs index a0b1e0a9..a82e8d7f 100644 --- a/NewHorizons/OrbitalPhysics/OrbitalHelper.cs +++ b/NewHorizons/OrbitalPhysics/OrbitalHelper.cs @@ -14,83 +14,46 @@ namespace NewHorizons.OrbitalPhysics public enum FalloffType { inverseSquared, - linear + linear, + none } - public static CartesianStateVectors CartesianStateVectorsFromTrueAnomaly(float standardGraviationalParameter, float eccentricity, float semiMajorAxis, float inclination, - float longitudeOfAscendingNode, float argumentOfPeriapsis, float trueAnomaly, FalloffType falloffType) + public static float GetOrbitalVelocity(float distance, Gravity gravity, KeplerElements kepler) { - var nu = Mathf.Deg2Rad * trueAnomaly; - var E = Mathf.Atan2(Mathf.Sqrt(1 - eccentricity * eccentricity) * Mathf.Sin(nu), (eccentricity + Mathf.Cos(nu))); + if (kepler.Eccentricity == 0) return GetCircularOrbitVelocity(distance, gravity, kepler); - return CartesianStateVectorsFromOrbitalElements(standardGraviationalParameter, eccentricity, semiMajorAxis, inclination, longitudeOfAscendingNode, argumentOfPeriapsis, E, nu, falloffType); - } - - public static CartesianStateVectors CartesianStateVectorsFromEccentricAnomaly(float standardGraviationalParameter, float eccentricity, float semiMajorAxis, float inclination, - float longitudeOfAscendingNode, float argumentOfPeriapsis, float eccentricAnomaly, FalloffType falloffType) - { - var E = Mathf.Deg2Rad * eccentricAnomaly; - var nu = 2f * Mathf.Atan2(Mathf.Sqrt(1 + eccentricity) * Mathf.Sin(E)/2f, Mathf.Sqrt(1 - eccentricity) * Mathf.Cos(E) / 2f); - - return CartesianStateVectorsFromOrbitalElements(standardGraviationalParameter, eccentricity, semiMajorAxis, inclination, longitudeOfAscendingNode, argumentOfPeriapsis, E, nu, falloffType); - } - - private static CartesianStateVectors CartesianStateVectorsFromOrbitalElements(float standardGraviationalParameter, float eccentricity, float semiMajorAxis, float inclination, - float longitudeOfAscendingNode, float argumentOfPeriapsis, float E, float nu, FalloffType falloffType) - { - //Keplerian Orbit Elements −→ Cartesian State Vectors (Memorandum #1) Rene Schwarz - - if (semiMajorAxis == 0) return new CartesianStateVectors(); - - // POS - var r = semiMajorAxis * (1 - eccentricity * Mathf.Cos(E)); - - Vector3 position = r * new Vector3(Mathf.Cos(nu), 0, Mathf.Sin(nu)); - - // VEL - var speed = Visviva(falloffType, standardGraviationalParameter, position.magnitude, semiMajorAxis, eccentricity); - Vector3 velocity = speed * (new Vector3(-Mathf.Sin(E), 0, Mathf.Sqrt(1 - (eccentricity * eccentricity)) * Mathf.Cos(E))).normalized; - - Quaternion periapsisRot = Quaternion.AngleAxis(Mathf.Deg2Rad * argumentOfPeriapsis, Vector3.up); - var inclinationAxis = Quaternion.AngleAxis(Mathf.Repeat(Mathf.Deg2Rad * longitudeOfAscendingNode, 2f * Mathf.PI), Vector3.up) * Vector3.left; - Quaternion inclinationRot = Quaternion.AngleAxis(inclination, inclinationAxis); - - position = periapsisRot * inclinationRot * position; - velocity = periapsisRot * inclinationRot * velocity; - - return new CartesianStateVectors(position, velocity); - } - - public static float Visviva(FalloffType falloffType, float standardGravitationalParameter, float dist, float semiMajorAxis, float eccentricity) - { - switch(falloffType) + if (gravity.Exponent == 2) { - case FalloffType.inverseSquared: - return Mathf.Sqrt(standardGravitationalParameter * (2f / dist - 1f / semiMajorAxis)); - case FalloffType.linear: - if (eccentricity == 0f) return Mathf.Sqrt(standardGravitationalParameter); - - var ra = semiMajorAxis * (1 + eccentricity); - var rp = semiMajorAxis * (1 - eccentricity); - - var kineticEneregyAtApoapsis = standardGravitationalParameter * Mathf.Log(ra / rp) * (rp * rp) / ((rp * rp) - (ra * ra)); - var gravitationalEnergy = standardGravitationalParameter * Mathf.Log(dist / ra); - var v = Mathf.Sqrt(2 * (kineticEneregyAtApoapsis + gravitationalEnergy)); - - return v; + return Mathf.Sqrt(GravityVolume.GRAVITATIONAL_CONSTANT * gravity.Mass * (2f / distance - 1f / kepler.SemiMajorAxis)); } - Logger.LogError($"Invalid falloffType {falloffType}"); + if(gravity.Exponent == 1) + { + 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); + Logger.Log($"{term1}, {term2}, {kepler.Periapsis} {kepler.Apoapsis}, {kepler.SemiMajorAxis}, {kepler.SemiMinorAxis}"); + return Mathf.Sqrt(2 * (term1 + term2)); + } + Logger.LogError($"Invalid exponent {gravity.Exponent}"); return 0f; } - private static Vector3 RotateToOrbitalPlane(Vector3 vector, float longitudeOfAscendingNode, float argumentOfPeriapsis, float inclination) + public static float GetCircularOrbitVelocity(float distance, Gravity gravity, KeplerElements kepler) { - vector = Quaternion.AngleAxis(Mathf.Deg2Rad * argumentOfPeriapsis, Vector3.up) * vector; - - var inclinationAxis = Quaternion.AngleAxis(Mathf.Repeat(Mathf.Deg2Rad * longitudeOfAscendingNode, 2f * Mathf.PI), Vector3.up) * new Vector3(1, 0, 0); - vector = Quaternion.AngleAxis(Mathf.Repeat(Mathf.Deg2Rad * inclination, 2f * Mathf.PI), inclinationAxis) * vector; - - return vector; + if (gravity.Exponent == 2) + { + return Mathf.Sqrt(GravityVolume.GRAVITATIONAL_CONSTANT * gravity.Mass / distance); + } + if(gravity.Exponent == 1) + { + return Mathf.Sqrt(GravityVolume.GRAVITATIONAL_CONSTANT * gravity.Mass); + } + Logger.LogError($"Invalid exponent {gravity.Exponent}"); + return 0f; } } } diff --git a/NewHorizons/OrbitalPhysics/ParameterizedInitialMotion.cs b/NewHorizons/OrbitalPhysics/ParameterizedInitialMotion.cs index 197300ea..9e91b081 100644 --- a/NewHorizons/OrbitalPhysics/ParameterizedInitialMotion.cs +++ b/NewHorizons/OrbitalPhysics/ParameterizedInitialMotion.cs @@ -11,6 +11,7 @@ namespace NewHorizons.OrbitalPhysics { public class ParameterizedInitialMotion : InitialMotion { + /* private new void Awake() { _rotationAxis = base.transform.TransformDirection(_rotationAxis); @@ -106,5 +107,6 @@ namespace NewHorizons.OrbitalPhysics private float _initAngularSpeed; private OWRigidbody _satelliteBody; + */ } } diff --git a/NewHorizons/OrbitalPhysics/ParameterizedOrbitLine.cs b/NewHorizons/OrbitalPhysics/ParameterizedOrbitLine.cs index bfd00a14..56e39ef3 100644 --- a/NewHorizons/OrbitalPhysics/ParameterizedOrbitLine.cs +++ b/NewHorizons/OrbitalPhysics/ParameterizedOrbitLine.cs @@ -12,7 +12,8 @@ using Logger = NewHorizons.Utility.Logger; namespace NewHorizons.OrbitalPhysics { public class ParameterizedOrbitLine : OrbitLine - { + { + /* protected override void InitializeLineRenderer() { base.GetComponent().positionCount = this._numVerts; @@ -122,5 +123,6 @@ namespace NewHorizons.OrbitalPhysics private InitialMotion _initialMotion; private AstroObject _primary; private OrbitalHelper.FalloffType _falloffType; + */ } } diff --git a/NewHorizons/Utility/MTuple.cs b/NewHorizons/Utility/MTuple.cs deleted file mode 100644 index 27617224..00000000 --- a/NewHorizons/Utility/MTuple.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Collections.Generic; -using System.Linq; - -namespace NewHorizons.Utility -{ - public class MTuple - { - public MTuple(params object[] _items) - { - Items = _items.ToList(); - } - - public List Items { get; } - } -} diff --git a/NewHorizons/Utility/NewHorizonExtensions.cs b/NewHorizons/Utility/NewHorizonExtensions.cs index e8a59d35..35eb5677 100644 --- a/NewHorizons/Utility/NewHorizonExtensions.cs +++ b/NewHorizons/Utility/NewHorizonExtensions.cs @@ -1,6 +1,7 @@ using NewHorizons.OrbitalPhysics; using System.Collections.Generic; using System.Reflection; +using System.Text; using UnityEngine; namespace NewHorizons.Utility @@ -19,9 +20,30 @@ namespace NewHorizons.Utility public static OrbitalHelper.FalloffType GetFalloffType(this GravityVolume gv) { + if (gv == null) return OrbitalHelper.FalloffType.none; var falloffTypeString = typeof(GravityVolume).GetField("_falloffType", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(gv).ToString(); var falloffType = falloffTypeString.Equals("linear") ? OrbitalHelper.FalloffType.linear : OrbitalHelper.FalloffType.inverseSquared; return falloffType; } + + public static float GetFalloffExponent(this GravityVolume gv) + { + if (gv == null) return 0; + return (float)typeof(GravityVolume).GetField("_falloffExponent", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(gv); + } + + public static string ToCamelCase(this string str) + { + StringBuilder strBuilder = new StringBuilder(str); + strBuilder[0] = strBuilder[0].ToString().ToLower().ToCharArray()[0]; + return strBuilder.ToString(); + } + + public static string ToTitleCase(this string str) + { + StringBuilder strBuilder = new StringBuilder(str); + strBuilder[0] = strBuilder[0].ToString().ToUpper().ToCharArray()[0]; + return strBuilder.ToString(); + } } }