Moved binary handling to HeavenlyBodyBuilder instead of DetectorBuilder (still broken)

This commit is contained in:
Nick J. Connors 2021-12-30 23:16:46 -05:00
parent 5999e62927
commit 12eda9cf96
4 changed files with 141 additions and 141 deletions

View File

@ -21,8 +21,6 @@ namespace NewHorizons.Builder.Body
int count = (int)(2f * Mathf.PI * belt.InnerRadius / (10f * maxSize));
if (count > 200) count = 200;
Logger.Log($"Making {count} asteroids around {bodyName}");
Random.InitState(belt.RandomSeed);
for (int i = 0; i < count; i++)
@ -30,7 +28,7 @@ namespace NewHorizons.Builder.Body
var size = Random.Range(minSize, maxSize);
var config = new Dictionary<string, object>()
{
{"Name", $"{bodyName} Asteroid {i}"},
{"Name", $"{bodyName} Asteroid {i+1}"},
{"Base", new Dictionary<string, object>()
{
{"HasMapMarker", false },
@ -59,8 +57,6 @@ namespace NewHorizons.Builder.Body
}
};
Logger.Log($"{config}");
var asteroid = new NewHorizonsBody(new PlanetConfig(config), assets);
Main.NextPassBodies.Add(asteroid);
}

View File

@ -89,114 +89,26 @@ namespace NewHorizons.Builder.General
return;
}
// Have to use fall off type rn instead of exponent since it the exponent doesnt update until the Awake method I think
var exponent = 0f;
if (primaryGV.GetFalloffType() == OrbitalHelper.FalloffType.linear) exponent = 1f;
if (primaryGV.GetFalloffType() == OrbitalHelper.FalloffType.inverseSquared) exponent = 2f;
// Very specific distance between them
Vector3 separation = primary.transform.position - secondary.transform.position;
var Gm1 = primaryGV.GetStandardGravitationalParameter();
var Gm2 = secondaryGV.GetStandardGravitationalParameter();
// One of the two is zero if it just loaded
if (Gm1 == 0) Gm1 = GravityVolume.GRAVITATIONAL_CONSTANT * primaryGV.GetValue<float>("_surfaceAcceleration") * Mathf.Pow(primaryGV.GetValue<float>("_upperSurfaceRadius"), exponent) / 0.001f;
if (Gm2 == 0) Gm2 = GravityVolume.GRAVITATIONAL_CONSTANT * secondaryGV.GetValue<float>("_surfaceAcceleration") * Mathf.Pow(secondaryGV.GetValue<float>("_upperSurfaceRadius"), exponent) / 0.001f;
float r1 = separation.magnitude * Gm2 / (Gm1 + Gm2);
float r2 = separation.magnitude * Gm1 / (Gm1 + Gm2);
primary.transform.position = point.transform.position + r1 * separation.normalized;
secondary.transform.position = point.transform.position - r2 * separation.normalized;
var pointForceDetector = point.GetAttachedOWRigidbody().GetAttachedForceDetector();
// Set detectable fields
primaryCFD.SetValue("_detectableFields", new ForceVolume[] { secondaryGV });
primaryCFD.SetValue("_inheritDetector", point.GetAttachedOWRigidbody().GetAttachedForceDetector());
primaryCFD.SetValue("_activeInheritedDetector", point.GetAttachedOWRigidbody().GetAttachedForceDetector());
primaryCFD.SetValue("_inheritDetector", pointForceDetector);
primaryCFD.SetValue("_activeInheritedDetector", pointForceDetector);
primaryCFD.SetValue("_inheritElement0", false);
secondaryCFD.SetValue("_detectableFields", new ForceVolume[] { primaryGV });
secondaryCFD.SetValue("_inheritDetector", point.GetAttachedOWRigidbody().GetAttachedForceDetector());
secondaryCFD.SetValue("_activeInheritedDetector", point.GetAttachedOWRigidbody().GetAttachedForceDetector());
secondaryCFD.SetValue("_inheritDetector", pointForceDetector);
secondaryCFD.SetValue("_activeInheritedDetector", pointForceDetector);
secondaryCFD.SetValue("_inheritElement0", false);
// They must have the same eccentricity
var primaryAO = primary.GetComponent<ParameterizedAstroObject>();
var secondaryAO = secondary.GetComponent<ParameterizedAstroObject>();
if (primaryAO == null||secondaryAO == null)
foreach(var planet in planets)
{
Logger.LogError($"Couldn't find ParameterizedAstroObject for body {primaryRB.name} or {secondaryRB.name}");
return;
}
float ecc = primaryAO.Eccentricity;
float i = primaryAO.Inclination;
float l = primaryAO.LongitudeOfAscendingNode;
float p = primaryAO.ArgumentOfPeriapsis;
// Update speeds
var m1 = Gm1 / GravityVolume.GRAVITATIONAL_CONSTANT;
var m2 = Gm2 / GravityVolume.GRAVITATIONAL_CONSTANT;
var reducedMass = m1 * m2 / (m1 + m2);
var totalMass = m1 + m2;
var r = separation.magnitude;
Logger.Log($"Primary AO: [{primaryAO}], Secondary AO: [{secondaryAO}]");
// Start them off at their periapsis
primaryAO.SetKeplerCoordinatesFromTrueAnomaly(ecc, r1 / (1f - ecc), i, l, p, 0);
secondaryAO.SetKeplerCoordinatesFromTrueAnomaly(ecc, r2 / (1f - ecc), i, l, p, 180);
// Make sure positions are right
var gravity = new OrbitalHelper.Gravity(exponent, totalMass);
var primaryCat = OrbitalHelper.GetCartesian(gravity, primaryAO);
var secondaryCat = OrbitalHelper.GetCartesian(gravity, secondaryAO);
primary.transform.position = point.transform.position + primaryCat.Item1;
secondary.transform.position = point.transform.position + secondaryCat.Item1;
Logger.Log($"Primary AO: [{primaryAO}], Secondary AO: [{secondaryAO}]");
// Finally we update the speeds
var v1 = primaryCat.Item2;
var v2 = primaryCat.Item2;
var focalPointMotion = point.gameObject.GetComponent<InitialMotion>();
var focalPointVelocity = focalPointMotion == null ? Vector3.zero : focalPointMotion.GetInitVelocity();
var primaryInitialMotion = primary.gameObject.GetComponent<InitialMotion>();
primaryInitialMotion.SetValue("_initLinearDirection", primary.gameObject.transform.InverseTransformDirection(v1.normalized));
primaryInitialMotion.SetValue("_initLinearSpeed", v1.magnitude);
var secondaryInitialMotion = secondary.gameObject.GetComponent<InitialMotion>();
secondaryInitialMotion.SetValue("_initLinearDirection", secondary.gameObject.transform.InverseTransformDirection(v2.normalized));
secondaryInitialMotion.SetValue("_initLinearSpeed", v2.magnitude);
// InitialMotion already set its speed so we overwrite that
if (!primaryInitialMotion.GetValue<bool>("_isInitVelocityDirty"))
{
Main.Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => primaryRB.SetVelocity(v1 + focalPointVelocity));
}
if (!secondaryInitialMotion.GetValue<bool>("_isInitVelocityDirty"))
{
Main.Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => secondaryRB.SetVelocity(v2 + focalPointVelocity));
}
// If they have tracking orbits set the period
var period = 2 * Mathf.PI * Mathf.Sqrt(Mathf.Pow(r, exponent + 1) / (GravityVolume.GRAVITATIONAL_CONSTANT * totalMass));
var trackingOrbitPrimary = primary.GetComponentInChildren<TrackingOrbitLine>();
if (trackingOrbitPrimary != null)
{
trackingOrbitPrimary.TrailTime = period;
}
var trackingOrbitSecondary = secondary.GetComponentInChildren<TrackingOrbitLine>();
if (trackingOrbitSecondary != null)
{
trackingOrbitSecondary.TrailTime = period;
var planetCFD = planet.GetAttachedOWRigidbody().GetAttachedForceDetector() as ConstantForceDetector;
planetCFD._detectableFields = new ForceVolume[] { primaryGV, secondaryGV };
planetCFD._inheritDetector = pointForceDetector;
planetCFD._activeInheritedDetector = pointForceDetector;
planetCFD._inheritElement0 = false;
}
}
}

View File

@ -24,53 +24,150 @@ namespace NewHorizons.Builder.General
public static void Make(GameObject body, IPlanetConfig config, float SOI, GravityVolume bodyGravity, InitialMotion initialMotion)
{
var size = new Position.Size(config.Base.SurfaceSize, SOI);
var gravity = getGravity(bodyGravity);
var parent = GetBody(config.Orbit.PrimaryBody);
var gravity = GetGravity(bodyGravity);
var parent = config.Orbit.PrimaryBody != null ? GetBody(config.Orbit.PrimaryBody) : HeavenlyBody.None;
if (config.Orbit.PrimaryBody != null && parent == HeavenlyBody.None)
Logger.LogWarning($"Could not find [{config.Orbit.PrimaryBody}] parent of [{config.Name}]");
var orbit = OrbitalHelper.KeplerCoordinatesFromOrbitModule(config.Orbit);
if (parent == HeavenlyBody.None)
{
Helper.helper.Console.WriteLine($"Could not find planet ({config.Name}) reference to its parent {config.Orbit.PrimaryBody}", MessageType.Warning);
}
var hb = GetBody(config.Name);
if (hb == null)
{
hb = AddHeavenlyBody(config.Name);
}
if (hb == null) hb = AddHeavenlyBody(config.Name);
Planet.Plantoid planetoid;
if (!config.Orbit.IsStatic)
{
planetoid = new Planet.Plantoid(size, gravity, body.transform.rotation, initialMotion._initAngularSpeed, parent, orbit);
}
else
{
planetoid = new Planet.Plantoid(size, gravity, body.transform.rotation, 0f, HeavenlyBody.None, body.transform.position, Vector3.zero);
}
if (!config.Orbit.IsStatic) planetoid = new Planet.Plantoid(size, gravity, body.transform.rotation, initialMotion._initAngularSpeed, parent, orbit);
else planetoid = new Planet.Plantoid(size, gravity, body.transform.rotation, 0f, HeavenlyBody.None, body.transform.position, Vector3.zero);
var mapping = Planet.defaultMapping;
mapping[hb] = planetoid;
Planet.defaultMapping = mapping;
// Fix for binary focal points
if(parent != HeavenlyBody.None)
{
var focalPoint = Position.AstroLookup[parent].Invoke()?.gameObject.GetComponent<BinaryFocalPoint>();
if (focalPoint != null && mapping.ContainsKey(parent))
{
var primary = Position.getBody(GetBody(focalPoint.PrimaryName));
var secondary = Position.getBody(GetBody(focalPoint.SecondaryName));
GameObject primary = null;
GameObject secondary = null;
if(primary != null && secondary != null)
Gravity primaryGravity = null;
Gravity secondaryGravity = null;
// One of them is null if it's the one being loaded
if(config.Name.Equals(focalPoint.PrimaryName))
{
Logger.Log($"Fixing BinaryFocalPoint HeavenlyBody gravity value for {parent.name}");
var primaryGravity = getGravity(primary?.GetAttachedGravityVolume());
var secondaryGravity = getGravity(secondary?.GetAttachedGravityVolume());
primary = body;
primaryGravity = GetGravity(bodyGravity);
secondary = Position.getBody(GetBody(focalPoint.SecondaryName))?.gameObject;
var secondaryGV = Position.getBody(GetBody(focalPoint.SecondaryName))?.GetAttachedGravityVolume();
if (secondaryGV != null) secondaryGravity = GetGravity(secondaryGV);
}
else if (config.Name.Equals(focalPoint.SecondaryName))
{
secondary = body;
secondaryGravity = GetGravity(bodyGravity);
primary = Position.getBody(GetBody(focalPoint.PrimaryName))?.gameObject;
var primaryGV = Position.getBody(GetBody(focalPoint.PrimaryName))?.GetAttachedGravityVolume();
if (primaryGV != null) primaryGravity = GetGravity(primaryGV);
}
if (primaryGravity != null && secondaryGravity != null)
{
Logger.Log($"Fixing BinaryFocalPoint HeavenlyBody gravity value for {parent}");
var exponent = (primaryGravity.exponent + secondaryGravity.exponent) / 2f;
var mass = (primaryGravity.mass + secondaryGravity.mass) / 4f;
mapping[parent] = new Planet.Plantoid(mapping[parent].size, Gravity.of(exponent, mass), mapping[parent].state);
// Also have to fix the children
var primaryHB = GetBody(focalPoint.PrimaryName);
var secondaryHB = GetBody(focalPoint.SecondaryName);
var r = primary.transform.position - secondary.transform.position;
var m1 = primaryGravity.mass;
var m2 = secondaryGravity.mass;
float r1 = r.magnitude * m2 / (m1 + m2);
float r2 = r.magnitude * m1 / (m1 + m2);
ParameterizedAstroObject primaryAO = Position.AstroLookup[primaryHB].Invoke() as ParameterizedAstroObject;
ParameterizedAstroObject secondaryAO = Position.AstroLookup[secondaryHB].Invoke() as ParameterizedAstroObject;
float ecc = primaryAO.Eccentricity;
float i = primaryAO.Inclination;
float l = primaryAO.LongitudeOfAscendingNode;
float p = primaryAO.ArgumentOfPeriapsis;
var primaryKeplerCoordinates = KeplerCoordinates.fromEccentricAnomaly(ecc, r1 / (1 - ecc), i, p, l, 0);
var secondaryKeplerCoordinates = KeplerCoordinates.fromEccentricAnomaly(ecc, r2 / (1 - ecc), i, p, l, 180);
var totalMass = m1 + m2;
var primaryCartesianState = OrbitHelper.toCartesian(Gravity.of(exponent, totalMass), 0, primaryKeplerCoordinates);
var secondaryCartesianState = OrbitHelper.toCartesian(Gravity.of(exponent, totalMass), 0, secondaryKeplerCoordinates);
var point = Position.AstroLookup[parent].Invoke();
primary.transform.position = point.transform.position + primaryCartesianState.Item1;
secondary.transform.position = point.transform.position + secondaryCartesianState.Item1;
Logger.Log($"Positions: {primary.transform.position}, {secondary.transform.position}");
var primaryOriginal = mapping[primaryHB];
var secondaryOriginal = mapping[secondaryHB];
// TODO: Idk if this works at all... probably not
var primaryRotation = 0f;
try
{
primaryRotation = primaryOriginal.state.relative.angularVelocity.magnitude;
}
catch (Exception) { };
var secondaryRotation = 0f;
try
{
secondaryRotation = secondaryOriginal.state.relative.angularVelocity.magnitude;
}
catch (Exception) { };
mapping[primaryHB] = new Planet.Plantoid(
primaryOriginal.size,
primaryOriginal.gravity,
primary.transform.rotation,
primaryRotation,
parent,
primaryKeplerCoordinates);
mapping[secondaryHB] = new Planet.Plantoid(
secondaryOriginal.size,
secondaryOriginal.gravity,
secondary.transform.rotation,
secondaryRotation,
parent,
secondaryKeplerCoordinates);
Planet.defaultMapping = mapping;
var period = 2 * Mathf.PI * Mathf.Sqrt(Mathf.Pow(r.magnitude, exponent + 1) / (GravityVolume.GRAVITATIONAL_CONSTANT * totalMass));
var trackingOrbitPrimary = primary.GetComponentInChildren<TrackingOrbitLine>();
if (trackingOrbitPrimary != null)
{
trackingOrbitPrimary.TrailTime = period;
}
var trackingOrbitSecondary = secondary.GetComponentInChildren<TrackingOrbitLine>();
if (trackingOrbitSecondary != null)
{
trackingOrbitSecondary.TrailTime = period;
}
}
}
}
}
@ -84,7 +181,7 @@ namespace NewHorizons.Builder.General
Planet.defaultMapping = mapping;
}
private static Gravity getGravity(GravityVolume volume)
private static Gravity GetGravity(GravityVolume volume)
{
if (volume == null)
{

View File

@ -10,9 +10,6 @@ using NewHorizons.Utility;
using OWML.Common;
using OWML.ModHelper;
using OWML.Utils;
using PacificEngine.OW_CommonResources.Game.Resource;
using PacificEngine.OW_CommonResources.Game.State;
using PacificEngine.OW_CommonResources.Geometry.Orbits;
using System;
using System.Collections.Generic;
using System.IO;
@ -20,7 +17,6 @@ using System.Linq;
using System.Reflection;
using UnityEngine;
using UnityEngine.SceneManagement;
using static PacificEngine.OW_CommonResources.Game.State.Planet;
using Logger = NewHorizons.Utility.Logger;
namespace NewHorizons
@ -241,7 +237,6 @@ namespace NewHorizons
primaryBody = null;
}
Logger.Log($"Begin generation sequence of [{body.Config.Name}]");
var go = new GameObject(body.Config.Name.Replace(" ", "").Replace("'", "") + "_Body");