diff --git a/scenes/OrbitSystem.tscn b/scenes/OrbitSystem.tscn new file mode 100644 index 0000000..b0cb744 --- /dev/null +++ b/scenes/OrbitSystem.tscn @@ -0,0 +1,15 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://scripts/orbits/OrbitSystem.cs" type="Script" id=1] + +[node name="Orbit System" type="Spatial"] +script = ExtResource( 1 ) +_a = NodePath("A") +_b = NodePath("B") +_barycenter = NodePath("Barycenter") + +[node name="A" type="Spatial" parent="."] + +[node name="B" type="Spatial" parent="."] + +[node name="Barycenter" type="Spatial" parent="."] diff --git a/scripts/orbits/ILocation.cs b/scripts/orbits/ILocation.cs new file mode 100644 index 0000000..50c1af4 --- /dev/null +++ b/scripts/orbits/ILocation.cs @@ -0,0 +1,7 @@ +using Godot; +using System; + +public interface ILocation +{ + Vector3 Position { get; } +} diff --git a/scripts/orbits/IMassive.cs b/scripts/orbits/IMassive.cs new file mode 100644 index 0000000..a7d5f80 --- /dev/null +++ b/scripts/orbits/IMassive.cs @@ -0,0 +1,7 @@ +using Godot; +using System; + +public interface IMassive +{ + float Mass { get; } +} diff --git a/scripts/orbits/OrbitSystem.cs b/scripts/orbits/OrbitSystem.cs new file mode 100644 index 0000000..358ad53 --- /dev/null +++ b/scripts/orbits/OrbitSystem.cs @@ -0,0 +1,97 @@ +using Godot; +using System; + +public class OrbitSystem : Node, IMassive, ILocation +{ + [Export] private NodePath _a; + [Export] private NodePath _b; + [Export] private NodePath _barycenter; + + private readonly PointMass[] _pointMasses = new PointMass[2]; + + public Vector3 Position => Barycenter; + + [Export] + public Vector3 Barycenter + { + get + { + var p0 = _pointMasses[0].Position; + var p1 = _pointMasses[1].Position; + + return p0.LinearInterpolate(p1, .5f); + } + set => _ = value; + } + + public float Mass { get; } = 1; + + private ImmediateGeometry _orbit; + + public override void _Ready() + { + InitPointMasses(); + InitGeometry(); + } + + public override void _Process(float delta) + { + DrawOrbit(); + } + + private void DrawOrbit() + { + int steps = 100; + + _orbit.Clear(); + _orbit.Begin(Mesh.PrimitiveType.LineLoop); + _orbit.SetColor(new Color(1, 0, 0)); + for (int i = 0; i < steps; i++) + { + float t = i / (float)steps; + float a = t * Mathf.Tau; + + _orbit.AddVertex(new Vector3 + { + x = Mathf.Sin(a), + z = Mathf.Cos(a) + }); + } + _orbit.End(); + } + + private void InitGeometry() + { + _orbit = new ImmediateGeometry(); + var m = new SpatialMaterial(); + m.VertexColorUseAsAlbedo = true; + m.FlagsUnshaded = true; + _orbit.MaterialOverride = m; + AddChild(_orbit); + } + + private void InitPointMasses() + { + var a = GetPointMass(_a); + var b = GetPointMass(_b); + + if (a.Mass > b.Mass) + { + _pointMasses[0] = a; + _pointMasses[1] = b; + } + else + { + _pointMasses[0] = b; + _pointMasses[1] = a; + } + } + + private PointMass GetPointMass(NodePath path) + { + var spatial = GetNode(path); + //var massive = node.GetChild(0); + + return new PointMass(spatial, 1f); + } +} diff --git a/scripts/orbits/Planet.cs b/scripts/orbits/Planet.cs new file mode 100644 index 0000000..c93a33a --- /dev/null +++ b/scripts/orbits/Planet.cs @@ -0,0 +1,18 @@ +using Godot; +using System; + +public class Planet : Node +{ + [Export] + public float Mass { get; set; } + + public override void _Ready() + { + + } + + // public override void _Process(float delta) + // { + // + // } +} diff --git a/scripts/orbits/PointMass.cs b/scripts/orbits/PointMass.cs new file mode 100644 index 0000000..bb277c1 --- /dev/null +++ b/scripts/orbits/PointMass.cs @@ -0,0 +1,25 @@ +using Godot; + +struct PointMass : IMassive, ILocation +{ + public float Mass => _massive == null ? _mass : _massive.Mass; + public Vector3 Position => _spatial.Translation; + + private IMassive _massive; + private Spatial _spatial; + private float _mass; + + public PointMass(Spatial spatial, IMassive massive) + { + _spatial = spatial; + _massive = massive; + _mass = 0; + } + + public PointMass(Spatial spatial, float mass) + { + _spatial = spatial; + _massive = null; + _mass = mass; + } +}