diff --git a/scenes/orbits/Barycenter.tscn b/scenes/orbits/Barycenter.tscn new file mode 100644 index 0000000..90bf3be --- /dev/null +++ b/scenes/orbits/Barycenter.tscn @@ -0,0 +1,18 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://scripts/orbits/Barycenter.cs" type="Script" id=1] +[ext_resource path="res://scenes/orbits/Planet.tscn" type="PackedScene" id=2] + +[node name="Barycenter" type="Spatial"] +script = ExtResource( 1 ) +SemiMajorAxis = 7.0 +Eccentricity = 0.752 +_pointMassPaths = [ NodePath("Planet A"), NodePath("Planet B") ] +_speed = 1.0 + +[node name="Planet A" parent="." instance=ExtResource( 2 )] +transform = Transform( 0.999977, 0.00603502, 0.00319089, -0.00604282, 0.999979, 0.0024369, -0.00317609, -0.00245615, 0.999992, -2.55711, 0, -4.25519 ) + +[node name="Planet B" parent="." instance=ExtResource( 2 )] +transform = Transform( 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, -11.9998, 0, 1.25565 ) +Mass = 0.125 diff --git a/scenes/orbits/OrbitSystem.tscn b/scenes/orbits/OrbitSystem.tscn deleted file mode 100644 index 3a5c227..0000000 --- a/scenes/orbits/OrbitSystem.tscn +++ /dev/null @@ -1,22 +0,0 @@ -[gd_scene load_steps=3 format=2] - -[ext_resource path="res://scripts/orbits/OrbitSystem.cs" type="Script" id=1] -[ext_resource path="res://scenes/orbits/Planet.tscn" type="PackedScene" id=2] - -[node name="Orbit System" type="Spatial"] -script = ExtResource( 1 ) -SemiMajorAxis = 6.881 -Eccentricity = 0.399 -Period = 10.0 -_a = NodePath("Planet A") -_b = NodePath("Planet B") -_barycenter = NodePath("Barycenter") - -[node name="Barycenter" type="Spatial" parent="."] - -[node name="Planet A" parent="." instance=ExtResource( 2 )] -transform = Transform( 0.999977, 0.00603502, 0.00319089, -0.00604282, 0.999979, 0.0024369, -0.00317609, -0.00245615, 0.999992, 0, 0, 0 ) - -[node name="Planet B" parent="." instance=ExtResource( 2 )] -transform = Transform( 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, -8.44634, 0, -3.53339 ) -Mass = 0.125 diff --git a/scripts/orbits/OrbitSystem.cs b/scripts/orbits/Barycenter.cs similarity index 50% rename from scripts/orbits/OrbitSystem.cs rename to scripts/orbits/Barycenter.cs index e60b2db..56ee541 100644 --- a/scripts/orbits/OrbitSystem.cs +++ b/scripts/orbits/Barycenter.cs @@ -1,13 +1,13 @@ using Godot; using System; +using System.Collections.Generic; using Vim.Math3d; [Tool] -public class OrbitSystem : Node, IMassive, ILocation +public class Barycenter : Node, IPointMass { - [Export] private NodePath _a; - [Export] private NodePath _b; - [Export] private NodePath _barycenter; + [Export] + private NodePath[] _pointMassPaths; private double _semiMajorAxis; [Export] @@ -40,79 +40,19 @@ public class OrbitSystem : Node, IMassive, ILocation } } - #region Point Masses - private IPointMass Primary + public double Mass { get { - if (_pointMasses[0] == null) + double mass = 0; + foreach (var orbiter in Orbiters) { - InitPointMasses(); + mass += orbiter.PointMass.Mass; } - return _pointMasses[0]; - } - } - private IPointMass Secondary - { - get - { - if (_pointMasses[1] == null) - { - InitPointMasses(); - } - return _pointMasses[1]; - } - } - private readonly IPointMass[] _pointMasses = new IPointMass[2]; - private void InitPointMasses() - { - var a = GetNode(_a); - var b = GetNode(_b); - - if (a.Mass > b.Mass) - { - _pointMasses[0] = a; - _pointMasses[1] = b; - } - else - { - _pointMasses[0] = b; - _pointMasses[1] = a; - } - } - #endregion - - public float Mass => Primary.Mass + Secondary.Mass; - public DVector3 Position - { - get => Barycenter; - set => Barycenter = value; - } - - public DVector3 Barycenter - { - get - { - var p0 = Primary.Position; - var p1 = Secondary.Position; - return p0.Lerp(p1, .5f); - } - // TODO - make setting the berycenter do something sensible? - set => _ = value; - } - - private Orbit _orbit = null; - private Orbit Orbit - { - get - { - if (_orbit == null) - { - _orbit = new Orbit(); - } - return _orbit; + return mass; } } + public DVector3 Position { get; set; } private ImmediateGeometry _orbitGeometry = null; public ImmediateGeometry OrbitGeometry @@ -132,6 +72,50 @@ public class OrbitSystem : Node, IMassive, ILocation } } + private struct Orbiter + { + public IPointMass PointMass { get; set; } + public IOrbit Orbit { get; set; } + } + private Orbiter[] _orbiters = null; + private Orbiter[] Orbiters + { + get + { + if (_orbiters == null) + { + var length = _pointMassPaths.Length; + _orbiters = new Orbiter[length]; + for (int i = 0; i < length; i++) + { + var pointMass = GetNode(_pointMassPaths[i]); + var orbit = new Orbit(this, pointMass); + + var orbiter = new Orbiter + { + PointMass = pointMass, + Orbit = orbit + }; + _orbiters[i] = orbiter; + } + } + return _orbiters; + } + } + + private IOrbit[] _orbits; + private IOrbit[] Orbits + { + get + { + if (_orbits == null) + { + + } + return _orbits; + } + } + private float _time = 0; [Export] @@ -145,9 +129,15 @@ public class OrbitSystem : Node, IMassive, ILocation private void InvalidateGeometry() { - Orbit.Ellipse = new Ellipse(SemiMajorAxis, Eccentricity); - Orbit.Draw(OrbitGeometry); + for (int i = 0; i < Orbiters.Length; i++) + { + var orbiter = Orbiters[i]; + var orbit = orbiter.Orbit; + orbit.Ellipse = new Ellipse(SemiMajorAxis, Eccentricity); + orbit.Draw(OrbitGeometry); - Secondary.Position = Orbit.GetPosition(_time); + var t = _time + i * Math.PI; + orbiter.PointMass.Position = orbit.GetPosition(t); + } } }