Bunch of stuff

This commit is contained in:
Nick J. Connors 2021-12-20 22:32:10 -05:00
parent 769d5a8049
commit cebcbd4e14
31 changed files with 689 additions and 234 deletions

View File

@ -1,5 +1,6 @@
using NewHorizons.External;
using NewHorizons.Utility;
using OWML.Common;
using OWML.Utils;
using System;
using UnityEngine;
@ -9,15 +10,20 @@ namespace NewHorizons.Atmosphere
{
static class CloudsBuilder
{
public static void Make(GameObject body, Sector sector, AtmosphereModule atmo)
public static void Make(GameObject body, Sector sector, AtmosphereModule atmo, IModAssets assets)
{
Texture2D image, cap, ramp;
try
{
image = Main.Instance.CurrentAssets.GetTexture(atmo.Cloud);
cap = Main.Instance.CurrentAssets.GetTexture(atmo.CloudCap);
ramp = Main.Instance.CurrentAssets.GetTexture(atmo.CloudRamp);
image = assets.GetTexture(atmo.Cloud);
if (atmo.CloudCap == null) cap = ImageUtilities.ClearTexture(128, 128);
else cap = assets.GetTexture(atmo.CloudCap);
//if(atmo.CloudRamp == null) ramp = ImageUtilities.Scaled(image, 1, 128);
if(atmo.CloudRamp == null) ramp = ImageUtilities.CanvasScaled(image, 1, image.height);
else ramp = assets.GetTexture(atmo.CloudRamp);
}
catch(Exception e)
{
@ -112,7 +118,11 @@ namespace NewHorizons.Atmosphere
// Fix the rotations once the rest is done
cloudsMainGO.transform.localRotation = Quaternion.Euler(0, 0, 0);
cloudsMainGO.transform.localPosition = Vector3.zero;
cloudsBottomGO.transform.localPosition = Vector3.zero;
cloudsFluidGO.transform.localPosition = Vector3.zero;
cloudsTopGO.transform.localPosition = Vector3.zero;
cloudsTopGO.SetActive(true);
cloudsBottomGO.SetActive(true);

View File

@ -35,19 +35,22 @@ namespace NewHorizons.Atmosphere
if(hasSnow)
{
var snowGO = GameObject.Instantiate(GameObject.Find("/BrittleHollow_Body/Sector_BH/Effects_BH/Effects_BH_Snowflakes"), effectsGO.transform);
var snowGO = new GameObject("SnowEffects");
snowGO.transform.parent = effectsGO.transform;
snowGO.transform.localPosition = Vector3.zero;
for(int i = 0; i < 5; i++)
{
var snowEmitter = GameObject.Instantiate(GameObject.Find("/BrittleHollow_Body/Sector_BH/Effects_BH/Effects_BH_Snowflakes"), snowGO.transform);
snowEmitter.name = "SnowEmitter";
snowEmitter.transform.localPosition = Vector3.zero;
var pvc = snowGO.GetComponent<PlanetaryVectionController>();
pvc.SetValue("_densityByHeight", new AnimationCurve(new Keyframe[] { new Keyframe(surfaceSize, 10f), new Keyframe(atmoSize, 0f) }));
var pvc = snowEmitter.GetComponent<PlanetaryVectionController>();
pvc.SetValue("_densityByHeight", new AnimationCurve(new Keyframe[] { new Keyframe(surfaceSize, 10f), new Keyframe(atmoSize, 0f) }));
var particleSystem = snowGO.GetComponent<ParticleSystem>();
var e = particleSystem.emission;
e.rateOverTime = 50;
snowGO.GetComponent<PlanetaryVectionController>().SetValue("_activeInSector", sector);
snowGO.GetComponent<PlanetaryVectionController>().SetValue("_exclusionSectors", new Sector[] { });
snowGO.SetActive(true);
snowEmitter.GetComponent<PlanetaryVectionController>().SetValue("_activeInSector", sector);
snowEmitter.GetComponent<PlanetaryVectionController>().SetValue("_exclusionSectors", new Sector[] { });
snowEmitter.SetActive(true);
}
}
effectsGO.transform.localPosition = Vector3.zero;

View File

@ -66,6 +66,7 @@ namespace NewHorizons.Atmosphere
fogGO.transform.localPosition = Vector3.zero;
lodFogGO.transform.localPosition = Vector3.zero;
fogGO.SetActive(true);
lodFogGO.SetActive(true);
}

View File

@ -1,5 +1,6 @@
using NewHorizons.External;
using NewHorizons.Utility;
using OWML.Common;
using System;
using System.Collections.Generic;
using System.Linq;
@ -13,7 +14,7 @@ namespace NewHorizons.Body
{
static class AsteroidBeltBuilder
{
public static void Make(string bodyName, AsteroidBeltModule belt)
public static void Make(string bodyName, AsteroidBeltModule belt, IModAssets assets)
{
var minSize = 20;
var maxSize = 50;
@ -33,7 +34,8 @@ namespace NewHorizons.Body
{"HasMapMarker", false },
{"SurfaceGravity", 1 },
{"SurfaceSize", size },
{"HasReferenceFrame", false }
{"HasReferenceFrame", false },
{"GravityFallOff", "inverseSquared" }
}
},
{"Orbit", new Dictionary<string, object>()
@ -57,7 +59,7 @@ namespace NewHorizons.Body
Logger.Log($"{config}");
var asteroid = new NewHorizonsBody(new PlanetConfig(config));
var asteroid = new NewHorizonsBody(new PlanetConfig(config), assets);
Main.AdditionalBodies.Add(asteroid);
}
}

View File

@ -1,4 +1,5 @@
using System;
using NewHorizons.External;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -9,12 +10,27 @@ namespace NewHorizons.General
{
static class BlackHoleBuilder
{
public static void Make(GameObject body)
public static void Make(GameObject body, BaseModule module, Sector sector)
{
var blackHole = GameObject.Instantiate(GameObject.Find("BrittleHollow_Body/BlackHole_BH"), body.transform);
blackHole.name = "BlackHole";
blackHole.GetComponentInChildren<MeshRenderer>().material.renderQueue = 3001;
blackHole.transform.localPosition = Vector3.zero;
//blackHole.transform.localScale = Vector3.one; //* module.BlackHoleSize;
var blackHoleRenderer = blackHole.transform.Find("BlackHoleRenderer");
//blackHoleRenderer.transform.localScale = Vector3.one;
var singularityLOD = blackHoleRenderer.GetComponent<SingularityLOD>();
singularityLOD.SetSector(sector);
/*
var meshRenderer = blackHoleRenderer.GetComponent<MeshRenderer>();
meshRenderer.material.SetFloat("_Radius", module.BlackHoleSize * 0.4f);
var owRenderer = blackHoleRenderer.gameObject.AddComponent<OWRenderer>();
var propID_Radius = Shader.PropertyToID("_Radius");
owRenderer.SetMaterialProperty(propID_Radius, module.BlackHoleSize * 0.4f);
*/
}
}
}

View File

@ -0,0 +1,28 @@
using NewHorizons.External;
using OWML.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace NewHorizons.Body
{
public static class CometTailBuilder
{
public static void Make(GameObject go, BaseModule module, AstroObject primary)
{
var cometTail = GameObject.Instantiate(GameObject.Find("Comet_Body/Sector_CO/Effects_CO/Effects_CO_TailMeshes"), go.transform);
cometTail.transform.localPosition = Vector3.zero;
cometTail.name = "CometTail";
cometTail.transform.localScale = Vector3.one * 110 / module.SurfaceSize;
cometTail.transform.localRotation = Quaternion.Euler(0, 180, 90);
/*
var alignment = cometTail.AddComponent<AlignWithTargetBody>();
alignment.SetTargetBody(primary.GetAttachedOWRigidbody());
alignment.SetValue("_usePhysicsToRotate", true);
*/
}
}
}

View File

@ -1,5 +1,6 @@
using NewHorizons.Body.Geometry;
using NewHorizons.External;
using OWML.Common;
using System;
using System.Collections.Generic;
using System.Linq;
@ -14,13 +15,15 @@ namespace NewHorizons.Body
{
public static Shader PlanetShader;
public static void Make(GameObject go, HeightMapModule module)
public static void Make(GameObject go, HeightMapModule module, IModAssets assets)
{
Texture2D heightMap, textureMap;
try
{
heightMap = Main.Instance.CurrentAssets.GetTexture(module.HeightMap);
textureMap = Main.Instance.CurrentAssets.GetTexture(module.TextureMap);
if (module.HeightMap == null) heightMap = Texture2D.whiteTexture;
else heightMap = assets.GetTexture(module.HeightMap);
if (module.TextureMap == null) textureMap = Texture2D.whiteTexture;
else textureMap = assets.GetTexture(module.TextureMap);
}
catch(Exception e)
{

View File

@ -1,4 +1,5 @@
using NewHorizons.External;
using OWML.Common;
using System;
using System.Collections.Generic;
using System.Linq;
@ -13,12 +14,12 @@ namespace NewHorizons.General
{
public static Shader RingShader;
public static void Make(GameObject body, RingModule ring)
public static void Make(GameObject body, RingModule ring, IModAssets assets)
{
Texture2D ringTexture;
try
{
ringTexture = Main.Instance.CurrentAssets.GetTexture(ring.Texture);
ringTexture = assets.GetTexture(ring.Texture);
}
catch (Exception e)
{

View File

@ -0,0 +1,56 @@
using NewHorizons.External;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace NewHorizons.Body
{
static class StarBuilder
{
public static void Make(GameObject body, Sector sector, StarModule starModule)
{
var sunGO = new GameObject("Star");
sunGO.transform.parent = body.transform;
var sunSurface = GameObject.Instantiate(GameObject.Find("Sun_Body/Sector_SUN/Geometry_SUN/Surface"), sunGO.transform);
sunSurface.transform.localPosition = Vector3.zero;
sunSurface.transform.localScale = Vector3.one;
sunSurface.name = "Surface";
var sunLight = GameObject.Instantiate(GameObject.Find("Sun_Body/Sector_SUN/Effects_SUN/SunLight"), sunGO.transform);
sunSurface.transform.localPosition = Vector3.zero;
sunSurface.transform.localScale = Vector3.one;
sunLight.name = "StarLight";
var solarFlareEmitter = GameObject.Instantiate(GameObject.Find("Sun_Body/Sector_SUN/Effects_SUN/SolarFlareEmitter"), sunGO.transform);
sunSurface.transform.localPosition = Vector3.zero;
sunSurface.transform.localScale = Vector3.one;
solarFlareEmitter.name = "SolarFlareEmitter";
var sunAudio = GameObject.Instantiate(GameObject.Find("Sun_Body/Sector_SUN/Audio_SUN"), sunGO.transform);
sunSurface.transform.localPosition = Vector3.zero;
sunSurface.transform.localScale = Vector3.one;
sunAudio.transform.Find("SurfaceAudio_Sun").GetComponent<AudioSource>().maxDistance = starModule.Size * 2f;
sunAudio.name = "Audio_Star";
var sunAtmosphere = GameObject.Instantiate(GameObject.Find("Sun_Body/Atmosphere_SUN"), sunGO.transform);
sunSurface.transform.localPosition = Vector3.zero;
sunSurface.transform.localScale = Vector3.one * 1.5f;
sunAtmosphere.name = "Atmosphere_Star";
var ambientLightGO = GameObject.Instantiate(GameObject.Find("Sun_Body/AmbientLight_SUN"), sunGO.transform);
ambientLightGO.transform.localPosition = Vector3.zero;
ambientLightGO.name = "AmbientLight_Star";
PlanetaryFogController fog = sunAtmosphere.transform.Find("FogSphere").GetComponent<PlanetaryFogController>();
TessellatedSphereRenderer surface = sunSurface.GetComponent<TessellatedSphereRenderer>();
Light ambientLight = ambientLightGO.GetComponent<Light>();
sunGO.transform.localPosition = Vector3.zero;
sunGO.transform.localScale = starModule.Size * Vector3.one;
}
}
}

View File

@ -1,16 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace NewHorizons.Body
{
static class SunBuilder
{
public static void Make(GameObject body, Sector sector)
{
}
}
}

View File

@ -12,11 +12,13 @@ namespace NewHorizons.External
public bool HasMapMarker { get; set; }
public bool HasAmbientLight { get; set; }
public float SurfaceGravity { get; set; }
public string GravityFallOff { get; set; } = "linear";
public float SurfaceSize { get; set; }
public float WaterSize { get; set; }
public float GroundSize { get; set; }
public float BlackHoleSize { get; set; }
public float LavaSize { get; set; }
public bool HasCometTail { get; set; }
public bool HasReferenceFrame { get; set; } = true;
}
}

View File

@ -6,6 +6,7 @@ namespace NewHorizons.External
{
string Name { get; }
bool Destroy { get; }
int BuildPriority { get; }
BaseModule Base {get;}
AtmosphereModule Atmosphere { get; }
OrbitModule Orbit { get; }
@ -13,6 +14,7 @@ namespace NewHorizons.External
HeightMapModule HeightMap { get; }
ProcGenModule ProcGen { get; }
AsteroidBeltModule AsteroidBelt { get; }
StarModule Star { get; }
SpawnModule Spawn { get; }
}
}

View File

@ -8,7 +8,7 @@ namespace NewHorizons.External
{
public class OrbitModule : Module
{
public int SemiMajorAxis { get; set; }
public int SemiMajorAxis { get; set; } = 5000;
public int Inclination { get; set; }
public string PrimaryBody { get; set; }
public bool IsMoon { get; set; }

View File

@ -8,6 +8,7 @@ namespace NewHorizons.External
{
public string Name { get; set; }
public bool Destroy { get; set; }
public int BuildPriority { get; set; } = -1;
public MVector3 SpawnPoint { get; set; }
public BaseModule Base { get; set; }
public AtmosphereModule Atmosphere { get; set; }
@ -16,6 +17,7 @@ namespace NewHorizons.External
public HeightMapModule HeightMap { get; set; }
public ProcGenModule ProcGen { get; set; }
public AsteroidBeltModule AsteroidBelt { get; set; }
public StarModule Star { get; set; }
public SpawnModule Spawn { get; set; }
public PlanetConfig(Dictionary<string, object> dict)

15
NewHorizons/External/StarModule.cs vendored Normal file
View File

@ -0,0 +1,15 @@
using NewHorizons.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NewHorizons.External
{
public class StarModule : Module
{
public float Size { get; set; }
public MColor32 Tint { get; set; }
}
}

View File

@ -1,4 +1,5 @@
using NewHorizons.External;
using NewHorizons.OrbitalPhysics;
using NewHorizons.Utility;
using OWML.Utils;
using UnityEngine;
@ -19,12 +20,16 @@ namespace NewHorizons.General
RB.interpolation = RigidbodyInterpolation.None;
RB.collisionDetectionMode = CollisionDetectionMode.Discrete;
KinematicRigidbody KRB = body.AddComponent<KinematicRigidbody>();
KRB.centerOfMass = Vector3.zero;
OWRigidbody OWRB = body.AddComponent<OWRigidbody>();
OWRB.SetValue("_kinematicSimulation", true);
OWRB.SetValue("_autoGenerateCenterOfMass", true);
OWRB.SetIsTargetable(true);
OWRB.SetValue("_maintainOriginalCenterOfMass", true);
OWRB.SetValue("_rigidbody", RB);
OWRB.SetValue("_kinematicRigidbody", KRB);
DetectorBuilder.Make(body, primaryBody);
@ -36,11 +41,9 @@ namespace NewHorizons.General
if (config.Orbit.IsTidallyLocked)
{
// Just manually match it fr
/*
RotateToAstroObject RTAO = body.AddComponent<RotateToAstroObject>();
RTAO.SetValue("_astroObjectLock", primaryBody);
*/
var alignment = body.AddComponent<AlignWithTargetBody>();
alignment.SetTargetBody(primaryBody.GetAttachedOWRigidbody());
alignment.SetValue("_usePhysicsToRotate", true);
}
return new MTuple(AO, OWRB);

View File

@ -1,4 +1,5 @@
using OWML.Utils;
using NewHorizons.External;
using OWML.Utils;
using System.Reflection;
using UnityEngine;
using Logger = NewHorizons.Utility.Logger;
@ -7,7 +8,7 @@ namespace NewHorizons.General
{
static class GravityBuilder
{
public static void Make(GameObject body, AstroObject ao, float surfaceAccel, float upperSurface, float lowerSurface)
public static void Make(GameObject body, AstroObject ao, float surfaceAccel, float upperSurface, float lowerSurface, string falloffType)
{
GameObject gravityGO = new GameObject("GravityWell");
gravityGO.transform.parent = body.transform;
@ -26,7 +27,7 @@ namespace NewHorizons.General
GravityVolume GV = gravityGO.AddComponent<GravityVolume>();
GV.SetValue("_cutoffAcceleration", 0.1f);
GV.SetValue("_falloffType", GV.GetType().GetNestedType("FalloffType", BindingFlags.NonPublic).GetField("linear").GetValue(GV));
GV.SetValue("_falloffType", GV.GetType().GetNestedType("FalloffType", BindingFlags.NonPublic).GetField(falloffType).GetValue(GV));
GV.SetValue("_alignmentRadius", 0.75f * upperSurface);
GV.SetValue("_upperSurfaceRadius", lowerSurface);
GV.SetValue("_lowerSurfaceRadius", 0);

View File

@ -6,49 +6,54 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using NewHorizons.OrbitalPhysics;
using Logger = NewHorizons.Utility.Logger;
using System.Reflection;
using NewHorizons.Utility;
namespace NewHorizons.General
{
static class InitialMotionBuilder
{
public static InitialMotion Make(GameObject body, AstroObject primaryBody, OWRigidbody OWRB, Vector3 positionVector, OrbitModule orbit)
public static InitialMotion Make(GameObject body, AstroObject primaryBody, OWRigidbody OWRB, OrbitModule orbit)
{
InitialMotion IM = body.AddComponent<InitialMotion>();
IM.SetPrimaryBody(primaryBody.GetAttachedOWRigidbody());
IM.SetValue("_orbitAngle", orbit.Inclination);
IM.SetValue("_isGlobalAxis", false);
IM.SetValue("_initAngularSpeed", orbit.SiderealPeriod == 0 ? 0.02f : 1.0f / orbit.SiderealPeriod);
// Initial velocity
var distance = positionVector - primaryBody.transform.position;
var speed = Kepler.OrbitalHelper.VisViva(primaryBody.GetGravityVolume().GetStandardGravitationalParameter(), distance, orbit.SemiMajorAxis);
var direction = Kepler.OrbitalHelper.EllipseTangent(orbit.Eccentricity, orbit.SemiMajorAxis, orbit.Inclination, orbit.LongitudeOfAscendingNode, orbit.ArgumentOfPeriapsis, orbit.TrueAnomaly);
var velocity = speed * direction;
// Cancel out what the game does
/*
ParameterizedInitialMotion initialMotion = body.AddComponent<ParameterizedInitialMotion>();
initialMotion.SetPrimary(primaryBody);
initialMotion.SetOrbitalParameters(
orbit.Eccentricity,
orbit.SemiMajorAxis,
orbit.Inclination,
orbit.LongitudeOfAscendingNode,
orbit.ArgumentOfPeriapsis,
orbit.TrueAnomaly);
initialMotion.SetValue("_initAngularSpeed", orbit.SiderealPeriod == 0 ? 0.02f : 1.0f / orbit.SiderealPeriod);
*/
InitialMotion initialMotion = body.AddComponent<InitialMotion>();
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)
{
var oldVelocity = Kepler.OrbitalHelper.CalculateOrbitVelocity(primaryBody.GetAttachedOWRigidbody(), distance, orbit.Inclination);
if (!float.IsNaN(oldVelocity.magnitude)) velocity -= oldVelocity;
else Logger.LogError($"The original orbital velocity for {body.name} was calculated to be NaN?");
var trueSpeed = velocity.magnitude;
var trueDirection = velocity.normalized;
Logger.Log($"Setting initial motion {velocity.magnitude} in direction {velocity.normalized}");
if (!float.IsNaN(trueSpeed) && trueDirection != Vector3.zero)
{
IM.SetValue("_initLinearDirection", velocity.normalized);
IM.SetValue("_initLinearSpeed", velocity.magnitude);
}
else Logger.LogError($"Could not set velocity ({speed}, {direction}) -> ({trueSpeed}, {trueDirection}) for {body.name}");
// 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);
}
var rotationAxis = Quaternion.AngleAxis(orbit.AxialTilt + orbit.Inclination, Vector3.right) * Vector3.up;
body.transform.rotation = Quaternion.FromToRotation(Vector3.up, rotationAxis);
return IM;
return initialMotion;
}
}
}

View File

@ -1,4 +1,5 @@
using NewHorizons.External;
using NewHorizons.OrbitalPhysics;
using NewHorizons.Utility;
using OWML.Utils;
using UnityEngine;
@ -22,12 +23,40 @@ namespace NewHorizons.General
LR.useWorldSpace = false;
LR.loop = false;
OrbitLine ol = orbit.Eccentricity != 0 ? orbitGO.AddComponent<EllipticOrbitLine>() : orbitGO.AddComponent<OrbitLine>();
ol.SetValue("_astroObject", astroobject);
ol.SetValue("_fade", isMoon);
ol.SetValue("_lineWidth", 0.5f);
//ol.SetOrbitalParameters(orbit.Eccentricity, orbit.SemiMajorAxis, orbit.Inclination, orbit.LongitudeOfAscendingNode, orbit.ArgumentOfPeriapsis, orbit.TrueAnomaly);
typeof(OrbitLine).GetMethod("InitializeLineRenderer", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(ol, new object[] { });
if(orbit.Eccentricity == 0)
{
OrbitLine ol = orbitGO.AddComponent<OrbitLine>();
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[] { });
}
else
{
OrbitLine ol = orbitGO.AddComponent<EllipticOrbitLine>();
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[] { });
}
/*
ParameterizedOrbitLine orbitLine = orbitGO.AddComponent<ParameterizedOrbitLine>();
orbitLine.SetValue("_astroObject", astroobject);
orbitLine.SetValue("_fade", isMoon);
orbitLine.SetValue("_lineWidth", 0.5f);
orbitLine.SetOrbitalParameters(
orbit.Eccentricity,
orbit.SemiMajorAxis,
orbit.Inclination,
orbit.LongitudeOfAscendingNode,
orbit.ArgumentOfPeriapsis,
orbit.TrueAnomaly);
typeof(OrbitLine).GetMethod("InitializeLineRenderer", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(orbitLine, new object[] { });
*/
}
}
}

View File

@ -2,6 +2,7 @@
using NewHorizons.Body;
using NewHorizons.External;
using NewHorizons.General;
using NewHorizons.OrbitalPhysics;
using NewHorizons.Utility;
using OWML.Common;
using OWML.ModHelper;
@ -10,6 +11,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using UnityEngine;
using UnityEngine.SceneManagement;
using Logger = NewHorizons.Utility.Logger;
@ -25,8 +27,6 @@ namespace NewHorizons
public static List<NewHorizonsBody> BodyList = new List<NewHorizonsBody>();
public static List<NewHorizonsBody> AdditionalBodies = new List<NewHorizonsBody>();
public IModAssets CurrentAssets { get; private set; }
public override object GetApi()
{
return new NewHorizonsApi();
@ -50,7 +50,11 @@ namespace NewHorizons
{
Logger.LogWarning("Couldn't find planets folder");
}
}
void Destroy()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
}
void OnSceneLoaded(Scene scene, LoadSceneMode mode)
@ -65,8 +69,11 @@ namespace NewHorizons
AstroObjectLocator.AddAstroObject(ao);
}
// Should make moons come after planets
BodyList = BodyList.OrderBy(b => (b.Config?.Orbit?.IsMoon)).ToList();
// Stars then planets then moons
BodyList = BodyList.OrderBy(b =>
(b.Config.BuildPriority != -1 ? b.Config.BuildPriority : (b.Config.Star != null) ? 0 :
(b.Config.Orbit.IsMoon ? 2 : 1)
)).ToList();
while(BodyList.Count != 0)
{
@ -132,7 +139,6 @@ namespace NewHorizons
public void LoadConfigs(IModBehaviour mod)
{
CurrentAssets = mod.ModHelper.Assets;
var folder = mod.ModHelper.Manifest.ModFolderPath;
foreach (var file in Directory.GetFiles(folder + @"planets\"))
{
@ -140,11 +146,11 @@ namespace NewHorizons
{
var config = mod.ModHelper.Storage.Load<PlanetConfig>(file.Replace(folder, ""));
Logger.Log($"Loaded {config.Name}");
BodyList.Add(new NewHorizonsBody(config));
BodyList.Add(new NewHorizonsBody(config, mod.ModHelper.Assets));
}
catch (Exception e)
{
Logger.LogError($"Couldn't load {file}: {e.Message}, {e.StackTrace}");
Logger.LogError($"Couldn't load {file}: {e.Message}, is your Json formatted correctly?");
}
}
}
@ -182,19 +188,41 @@ namespace NewHorizons
float sphereOfInfluence = Mathf.Max(atmoSize, body.Config.Base.SurfaceSize * 2f);
// Get initial position but set it at the end
//var a = body.Config.Orbit.SemiMajorAxis;
//var omega = Mathf.Deg2Rad * body.Config.Orbit.LongitudeOfAscendingNode;
//var positionVector = primaryBody.gameObject.transform.position + new Vector3(a * Mathf.Sin(omega), 0, a * Mathf.Cos(omega));
var positionVector = Kepler.OrbitalHelper.CartesianFromOrbitalElements(body.Config.Orbit.Eccentricity, body.Config.Orbit.SemiMajorAxis, body.Config.Orbit.Inclination,
body.Config.Orbit.LongitudeOfAscendingNode, body.Config.Orbit.ArgumentOfPeriapsis, body.Config.Orbit.TrueAnomaly);
var falloffType = primaryBody.GetGravityVolume().GetFalloffType();
/*
var positionVector = OrbitalHelper.CartesianStateVectorsFromTrueAnomaly(
0f,
body.Config.Orbit.Eccentricity,
body.Config.Orbit.SemiMajorAxis,
body.Config.Orbit.Inclination,
body.Config.Orbit.LongitudeOfAscendingNode,
body.Config.Orbit.ArgumentOfPeriapsis,
body.Config.Orbit.TrueAnomaly,
falloffType).Position;
*/
var rot = Quaternion.AngleAxis(body.Config.Orbit.LongitudeOfAscendingNode + body.Config.Orbit.TrueAnomaly + body.Config.Orbit.ArgumentOfPeriapsis + 180f, Vector3.up);
// For now, eccentric orbits gotta start at apoapsis and cant be inclined
if(body.Config.Orbit.Eccentricity != 0)
{
rot = Quaternion.AngleAxis(body.Config.Orbit.LongitudeOfAscendingNode + body.Config.Orbit.ArgumentOfPeriapsis + 180f, Vector3.up);
body.Config.Orbit.Inclination = 0;
}
var incAxis = Quaternion.AngleAxis(body.Config.Orbit.LongitudeOfAscendingNode, Vector3.up) * Vector3.left;
var incRot = Quaternion.AngleAxis(body.Config.Orbit.Inclination, incAxis);
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];
if (body.Config.Base.SurfaceGravity != 0)
GravityBuilder.Make(go, ao, body.Config.Base.SurfaceGravity, sphereOfInfluence, body.Config.Base.SurfaceSize);
else Logger.Log("No gravity?");
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);
@ -202,17 +230,26 @@ namespace NewHorizons
if (body.Config.Base.HasMapMarker)
MarkerBuilder.Make(go, body.Config.Name, body.Config.Orbit.IsMoon);
if (body.Config.Base.HasAmbientLight)
AmbientLightBuilder.Make(go, sphereOfInfluence);
var sector = MakeSector.Make(go, rb, sphereOfInfluence);
VolumesBuilder.Make(go, body.Config.Base.SurfaceSize, sphereOfInfluence);
if (body.Config.HeightMap != null)
HeightMapBuilder.Make(go, body.Config.HeightMap);
HeightMapBuilder.Make(go, body.Config.HeightMap, body.Assets);
if (body.Config.ProcGen != null)
ProcGenBuilder.Make(go, body.Config.ProcGen);
InitialMotionBuilder.Make(go, primaryBody, rb, positionVector, body.Config.Orbit);
if (body.Config.Base.BlackHoleSize != 0)
BlackHoleBuilder.Make(go, body.Config.Base, sector);
/*
if (body.Config.Star != null)
StarBuilder.Make(go, sector, body.Config.Star);
*/
// Do stuff that's shared between generating new planets and updating old ones
go = SharedGenerateBody(body, go, sector, rb);
@ -227,6 +264,9 @@ namespace NewHorizons
go.transform.parent = Locator.GetRootTransform();
go.transform.position = positionVector + primaryBody.transform.position;
// Have to do this after setting position
InitialMotionBuilder.Make(go, primaryBody, rb, body.Config.Orbit);
// Spawning on other planets is a bit hacky so we do it last
if (body.Config.Spawn != null)
{
@ -243,10 +283,13 @@ namespace NewHorizons
private static GameObject SharedGenerateBody(NewHorizonsBody body, GameObject go, Sector sector, OWRigidbody rb)
{
if (body.Config.Ring != null)
RingBuilder.Make(go, body.Config.Ring);
RingBuilder.Make(go, body.Config.Ring, body.Assets);
if (body.Config.AsteroidBelt != null)
AsteroidBeltBuilder.Make(body.Config.Name, body.Config.AsteroidBelt);
AsteroidBeltBuilder.Make(body.Config.Name, body.Config.AsteroidBelt, body.Assets);
if (body.Config.Base.HasCometTail)
CometTailBuilder.Make(go, body.Config.Base, go.GetComponent<AstroObject>().GetPrimaryBody());
if(body.Config.Base != null)
{
@ -262,7 +305,7 @@ namespace NewHorizons
if (body.Config.Atmosphere.Cloud != null)
{
CloudsBuilder.Make(go, sector, body.Config.Atmosphere);
CloudsBuilder.Make(go, sector, body.Config.Atmosphere, body.Assets);
SunOverrideBuilder.Make(go, sector, body.Config.Base.SurfaceSize, body.Config.Atmosphere);
}
@ -281,12 +324,18 @@ namespace NewHorizons
public class NewHorizonsApi
{
[Obsolete("Create(Dictionary<string, object> config) is deprecated, please use Create(Dictionary<string, object> config, IModBehaviour mod) instead")]
public void Create(Dictionary<string, object> config)
{
Logger.Log("Recieved API request to create planet " + (string)config["Name"] + " at position " + (Vector3)config["Position"], Logger.LogType.Log);
Create(config, null);
}
public void Create(Dictionary<string, object> config, IModBehaviour mod)
{
Logger.Log("Recieved API request to create planet " + (string)config["Name"], Logger.LogType.Log);
var planetConfig = new PlanetConfig(config);
var body = new NewHorizonsBody(planetConfig);
var body = new NewHorizonsBody(planetConfig, mod != null ? mod.ModHelper.Assets : Main.Instance.ModHelper.Assets);
Main.BodyList.Add(body);
}

View File

@ -231,12 +231,13 @@
<ItemGroup>
<Compile Include="Atmosphere\FogBuilder.cs" />
<Compile Include="Body\AsteroidBeltBuilder.cs" />
<Compile Include="Body\CometTailBuilder.cs" />
<Compile Include="Body\Geometry\CubeSphere.cs" />
<Compile Include="Body\Geometry\Icosphere.cs" />
<Compile Include="Body\Geometry\Perlin.cs" />
<Compile Include="Body\HeightMapBuilder.cs" />
<Compile Include="Body\ProcGenBuilder.cs" />
<Compile Include="Body\SunBuilder.cs" />
<Compile Include="Body\StarBuilder.cs" />
<Compile Include="External\AsteroidBeltModule.cs" />
<Compile Include="External\AtmosphereModule.cs" />
<Compile Include="External\BaseModule.cs" />
@ -246,6 +247,7 @@
<Compile Include="External\ProcGenModule.cs" />
<Compile Include="External\RingModule.cs" />
<Compile Include="External\SpawnModule.cs" />
<Compile Include="External\StarModule.cs" />
<Compile Include="General\BaseBuilder.cs" />
<Compile Include="Body\BlackHoleBuilder.cs" />
<Compile Include="General\DetectorBuilder.cs" />
@ -259,7 +261,9 @@
<Compile Include="Body\RingBuilder.cs" />
<Compile Include="General\SectorBuilder.cs" />
<Compile Include="General\SpawnPointBuilder.cs" />
<Compile Include="Physics\OrbitalHelper.cs" />
<Compile Include="OrbitalPhysics\CartesianStateVectors.cs" />
<Compile Include="OrbitalPhysics\ParameterizedInitialMotion.cs" />
<Compile Include="OrbitalPhysics\OrbitalHelper.cs" />
<Compile Include="Utility\AddDebugShape.cs" />
<Compile Include="General\AmbientLightBuilder.cs" />
<Compile Include="External\IPlanetConfig.cs" />
@ -278,7 +282,7 @@
<Compile Include="Utility\AstroObjectLocator.cs" />
<Compile Include="Utility\DebugRaycaster.cs" />
<Compile Include="Utility\ImageUtilities.cs" />
<Compile Include="Physics\ParameterizedOrbitLine.cs" />
<Compile Include="OrbitalPhysics\ParameterizedOrbitLine.cs" />
<Compile Include="Utility\Logger.cs" />
<Compile Include="Utility\MakeMeshDoubleFaced.cs" />
<Compile Include="Utility\NewHorizonBody.cs" />

View File

@ -0,0 +1,27 @@
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

@ -0,0 +1,96 @@
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 static class OrbitalHelper
{
public enum FalloffType
{
inverseSquared,
linear
}
public static CartesianStateVectors CartesianStateVectorsFromTrueAnomaly(float standardGraviationalParameter, float eccentricity, float semiMajorAxis, float inclination,
float longitudeOfAscendingNode, float argumentOfPeriapsis, float trueAnomaly, FalloffType falloffType)
{
var nu = Mathf.Deg2Rad * trueAnomaly;
var E = Mathf.Atan2(Mathf.Sqrt(1 - eccentricity * eccentricity) * Mathf.Sin(nu), (eccentricity + Mathf.Cos(nu)));
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)
{
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;
}
Logger.LogError($"Invalid falloffType {falloffType}");
return 0f;
}
private static Vector3 RotateToOrbitalPlane(Vector3 vector, float longitudeOfAscendingNode, float argumentOfPeriapsis, float inclination)
{
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;
}
}
}

View File

@ -0,0 +1,110 @@
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

@ -1,12 +1,15 @@
using NewHorizons.Kepler;
using OWML.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using NewHorizons.Utility;
using Logger = NewHorizons.Utility.Logger;
namespace NewHorizons.Utility
namespace NewHorizons.OrbitalPhysics
{
public class ParameterizedOrbitLine : OrbitLine
{
@ -17,20 +20,20 @@ namespace NewHorizons.Utility
protected override void OnValidate()
{
if (this._numVerts < 0 || this._numVerts > 4096)
if (_numVerts < 0 || _numVerts > 4096)
{
this._numVerts = Mathf.Clamp(this._numVerts, 0, 4096);
_numVerts = Mathf.Clamp(this._numVerts, 0, 4096);
}
if (base.GetComponent<LineRenderer>().positionCount != this._numVerts)
if (base.GetComponent<LineRenderer>().positionCount != _numVerts)
{
this.InitializeLineRenderer();
InitializeLineRenderer();
}
}
protected override void Start()
{
base.Start();
this._verts = new Vector3[this._numVerts];
_verts = new Vector3[_numVerts];
base.enabled = false;
}
@ -43,23 +46,17 @@ namespace NewHorizons.Utility
_argumentOfPeriapsis = argumentOfPeriapsis;
_trueAnomaly = trueAnomaly;
_initialMotion = (this._astroObject != null) ? this._astroObject.GetComponent<InitialMotion>() : null;
_primary = (this._astroObject != null) ? this._astroObject.GetPrimaryBody() : null;
_initialMotion = (_astroObject != null) ? _astroObject.GetComponent<InitialMotion>() : null;
_primary = (_astroObject != null) ? _astroObject.GetPrimaryBody() : null;
_falloffType = _primary.GetGravityVolume().GetFalloffType();
if (_initialMotion && _primary)
{
var periapsisAngle = longitudeOfAscendingNode + argumentOfPeriapsis;
var apoapsisAngle = periapsisAngle + 90f;
_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);
_vSemiMinorAxis = OrbitalHelper.CartesianFromOrbitalElements(_eccentricity, _semiMajorAxis, _inclination, _longitudeOfAscendingNode, _argumentOfPeriapsis, periapsisAngle);
_vSemiMajorAxis = OrbitalHelper.CartesianFromOrbitalElements(_eccentricity, _semiMajorAxis, _inclination, _longitudeOfAscendingNode, _argumentOfPeriapsis, apoapsisAngle);
Vector3 rhs = this._astroObject.transform.position - _primary.transform.position;
Vector3 initVelocity = _initialMotion.GetInitVelocity();
Vector3 vector = Vector3.Cross(initVelocity, rhs);
this._upAxisDir = vector.normalized;
var semiMinorAxis = semiMajorAxis * Mathf.Sqrt(1 - (eccentricity * eccentricity));
_fociDistance = Mathf.Sqrt((semiMajorAxis * semiMajorAxis) - (semiMinorAxis * semiMinorAxis));
base.enabled = true;
@ -72,18 +69,21 @@ namespace NewHorizons.Utility
protected override void Update()
{
Vector3 vector = _primary.transform.position + _vSemiMajorAxis * _fociDistance;
float num = CalcProjectedAngleToCenter(vector, _vSemiMajorAxis, _vSemiMinorAxis, _astroObject.transform.position);
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 = ((float)i / (float)(_numVerts - 1)) * 360f - Mathf.Rad2Deg * num;
_verts[i] = OrbitalHelper.CartesianFromOrbitalElements(_eccentricity, _semiMajorAxis, _inclination, _longitudeOfAscendingNode, _argumentOfPeriapsis, angle);
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.LookRotation(Quaternion.AngleAxis(-48f, Vector3.up) * _vSemiMajorAxis, -_upAxisDir);
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;
@ -121,5 +121,6 @@ namespace NewHorizons.Utility
private Vector3[] _verts;
private InitialMotion _initialMotion;
private AstroObject _primary;
private OrbitalHelper.FalloffType _falloffType;
}
}

View File

@ -1,99 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace NewHorizons.Kepler
{
public static class OrbitalHelper
{
public static Vector3 CartesianFromOrbitalElements(float e, float a, float inclination, float ascending, float periapsis, float angle)
{
float b = a * Mathf.Sqrt(1f - (e * e));
// Get point on ellipse
// Angle starts at apoapsis, shift by 90 degrees to get to periapsis and add true anomaly
float ellipseAngle = Mathf.Repeat(Mathf.PI / 4f + Mathf.Deg2Rad * angle, 2 * Mathf.PI);
float tAngle = Mathf.Tan(ellipseAngle);
float x = (a * b) / Mathf.Sqrt(b * b + a * a * tAngle * tAngle);
if (ellipseAngle > Mathf.PI / 2f && ellipseAngle < 3f * Mathf.PI / 2f) x *= -1;
float y = x * tAngle;
// Fix limits
if (float.IsNaN(x)) {
x = 0;
if (angle < 180) y = b;
else y = -b;
}
var position = new Vector3(x, 0, y);
return RotateToOrbitalPlane(position, ascending, periapsis, inclination);
}
public static float VisViva(float standardGravitationalParameter, Vector3 relativePosition, float semiMajorAxis)
{
return Mathf.Sqrt(standardGravitationalParameter * (2f / relativePosition.magnitude - 1f / semiMajorAxis));
}
public static Vector3 EllipseTangent(float e, float a, float inclination, float ascending, float periapsis, float angle)
{
float b = a * Mathf.Sqrt(1f - (e * e));
float ellipseAngle = Mathf.Repeat(Mathf.PI / 4f + Mathf.Deg2Rad * angle, 2 * Mathf.PI);
var tan = Mathf.Tan(ellipseAngle);
float x = (a * b) / Mathf.Sqrt(b * b + a * a * tan * tan);
var sec2 = 1f / (tan * tan);
float dxdt = -a * a * a * b * sec2 * tan / Mathf.Pow(a * a * tan * tan + b * b, 3f / 2f);
if (ellipseAngle > Mathf.PI / 2f && ellipseAngle < 3f * Mathf.PI / 2f)
{
dxdt *= -1;
x *= -1;
}
// Product rule
var dydt = sec2 * x + dxdt * tan;
// Fix limits
if(float.IsNaN(dxdt))
{
dydt = 0;
if (angle == Mathf.PI / 2f) dxdt = -1;
else dxdt = 1;
}
var vector = new Vector3(dxdt, 0, dydt).normalized;
return RotateToOrbitalPlane(vector, ascending, periapsis, inclination);
}
private static Vector3 RotateToOrbitalPlane(Vector3 vector, float ascending, float periapsis, float inclination)
{
// Periapsis is at 90 degrees
vector = Quaternion.AngleAxis(Mathf.Deg2Rad * (ascending + periapsis) + Mathf.PI / 2f, Vector3.up) * vector;
var inclinationAxis = Quaternion.AngleAxis(Mathf.Repeat(Mathf.Deg2Rad * ascending, 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;
}
public static Vector3 CalculateOrbitVelocity(OWRigidbody primaryBody, Vector3 relativePosition, float inclination = 0f)
{
GravityVolume attachedGravityVolume = primaryBody.GetAttachedGravityVolume();
if (attachedGravityVolume == null)
{
return Vector3.zero;
}
Vector3 vector2 = Vector3.Cross(relativePosition, Vector3.up).normalized;
vector2 = Quaternion.AngleAxis(inclination, relativePosition) * vector2;
float d = Mathf.Sqrt(attachedGravityVolume.CalculateForceAccelerationAtPoint(relativePosition + primaryBody.transform.position).magnitude * relativePosition.magnitude);
return vector2 * d;
}
}
}

View File

@ -26,5 +26,80 @@ namespace NewHorizons.Utility
tex.LoadRawTextureData(File.ReadAllBytes(filepath));
return tex;
}
public static Texture2D ClearTexture(int width, int height)
{
var tex = (new Texture2D(1, 1, TextureFormat.ARGB32, false));
Color fillColor = Color.clear;
Color[] fillPixels = new Color[tex.width * tex.height];
for(int i = 0; i < fillPixels.Length; i++)
{
fillPixels[i] = fillColor;
}
tex.SetPixels(fillPixels);
tex.Apply();
return tex;
}
public static Texture2D CanvasScaled(Texture2D src, int width, int height)
{
var tex = (new Texture2D(width, height, TextureFormat.ARGB32, false));
Color[] fillPixels = new Color[tex.width * tex.height];
for (int i = 0; i < tex.width; i++)
{
for(int j = 0; j < tex.height; j++)
{
fillPixels[i + j * tex.width] = src.GetPixel(i, j);
}
}
tex.SetPixels(fillPixels);
tex.Apply();
return tex;
}
// Thank you PETERSVP
public static Texture2D Scaled(Texture2D src, int width, int height, FilterMode mode = FilterMode.Trilinear)
{
Rect texR = new Rect(0, 0, width, height);
_gpu_scale(src, width, height, mode);
//Get rendered data back to a new texture
Texture2D result = new Texture2D(width, height, TextureFormat.ARGB32, true);
result.Resize(width, height);
result.ReadPixels(texR, 0, 0, true);
return result;
}
public static void Scale(Texture2D tex, int width, int height, FilterMode mode = FilterMode.Trilinear)
{
Rect texR = new Rect(0, 0, width, height);
_gpu_scale(tex, width, height, mode);
// Update new texture
tex.Resize(width, height);
tex.ReadPixels(texR, 0, 0, true);
tex.Apply(true); //Remove this if you hate us applying textures for you :)
}
// Internal unility that renders the source texture into the RTT - the scaling method itself.
static void _gpu_scale(Texture2D src, int width, int height, FilterMode fmode)
{
//We need the source texture in VRAM because we render with it
src.filterMode = fmode;
src.Apply(true);
//Using RTT for best quality and performance. Thanks, Unity 5
RenderTexture rtt = new RenderTexture(width, height, 32);
//Set the RTT in order to render to it
Graphics.SetRenderTarget(rtt);
//Setup 2D matrix in range 0..1, so nobody needs to care about sized
GL.LoadPixelMatrix(0, 1, 1, 0);
//Then clear & draw the texture to fill the entire RTT.
GL.Clear(true, true, new Color(0, 0, 0, 0));
Graphics.DrawTexture(new Rect(0, 0, 1, 1), src);
}
}
}

View File

@ -1,16 +1,19 @@
using NewHorizons.External;
using OWML.Common;
using UnityEngine;
namespace NewHorizons.Utility
{
public class NewHorizonsBody
{
public NewHorizonsBody(IPlanetConfig config)
public NewHorizonsBody(IPlanetConfig config, IModAssets assets)
{
Config = config;
Assets = assets;
}
public IPlanetConfig Config;
public IModAssets Assets;
public GameObject Object;
}

View File

@ -1,4 +1,6 @@
using System.Collections.Generic;
using NewHorizons.OrbitalPhysics;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
namespace NewHorizons.Utility
@ -14,5 +16,12 @@ namespace NewHorizons.Utility
{
return (T)dict[settingName];
}
public static OrbitalHelper.FalloffType GetFalloffType(this GravityVolume gv)
{
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;
}
}
}

View File

@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace NewHorizons.Utility
{
@ -12,17 +13,33 @@ namespace NewHorizons.Utility
public static void Apply()
{
Main.Instance.ModHelper.HarmonyHelper.AddPrefix<ReferenceFrame>("GetHUDDisplayName", typeof(Patches), nameof(Patches.GetHUDDisplayName));
Main.Instance.ModHelper.HarmonyHelper.AddPrefix<PlayerState>("CheckShipOutsideSolarSystem", typeof(Patches), nameof(Patches.CheckShipOutersideSolarSystem));
Main.Instance.ModHelper.HarmonyHelper.AddPostfix<EllipticOrbitLine>("Start", typeof(Patches), nameof(Patches.OnEllipticOrbitLineStart));
}
public static bool GetHUDDisplayName(ReferenceFrame __instance, ref string __result)
{
var ao = __instance.GetAstroObject();
if (ao.GetAstroObjectName() == AstroObject.Name.CustomString)
if (ao != null && ao.GetAstroObjectName() == AstroObject.Name.CustomString)
{
__result = ao.GetCustomName();
return false;
}
return true;
}
public static bool CheckShipOutersideSolarSystem(PlayerState __instance, bool __result)
{
__result = false;
return false;
}
public static void OnEllipticOrbitLineStart(EllipticOrbitLine __instance, ref Vector3 ____upAxisDir, AstroObject ____astroObject)
{
if (____astroObject.GetAstroObjectName() == AstroObject.Name.Comet) return;
// For some reason other planets do this idk
____upAxisDir *= -1f;
}
}
}

View File

@ -3,6 +3,6 @@
"author": "xen",
"name": "New Horizons",
"uniqueName": "xen.NewHorizons",
"version": "0.1.0",
"version": "0.1.2",
"owmlVersion": "2.1.0"
}