shmodot/scripts/orbits/OrbitSystem.cs

125 lines
2.7 KiB
C#
Raw Normal View History

2022-08-31 22:18:47 +02:00
using Godot;
using System;
2022-09-05 23:13:53 +02:00
using System.Collections.Generic;
using Vim.Math3d;
2022-08-31 22:18:47 +02:00
[Tool]
2022-09-05 23:13:53 +02:00
public class OrbitSystem : Node, IPointMass
2022-08-31 22:18:47 +02:00
{
2022-09-05 23:13:53 +02:00
[Export]
private NodePath[] _pointMassPaths;
2022-08-31 22:18:47 +02:00
private double _semiMajorAxis;
2022-08-31 22:18:47 +02:00
[Export]
private double SemiMajorAxis
2022-08-31 22:18:47 +02:00
{
get => _semiMajorAxis;
set
2022-08-31 22:18:47 +02:00
{
_semiMajorAxis = value;
if (!Engine.EditorHint) return;
2022-08-31 22:18:47 +02:00
InvalidateGeometry();
2022-08-31 22:18:47 +02:00
}
}
private double _eccentricity;
[Export(PropertyHint.Range, "0,1")]
private double Eccentricity
2022-08-31 22:18:47 +02:00
{
get => _eccentricity;
set
{
_eccentricity = value;
2022-08-31 22:18:47 +02:00
if (!Engine.EditorHint) return;
InvalidateGeometry();
}
2022-08-31 22:18:47 +02:00
}
2022-09-05 23:13:53 +02:00
private IPointMass[] _pointMasses;
public IPointMass[] Orbiters
2022-08-31 22:18:47 +02:00
{
get
2022-08-31 22:18:47 +02:00
{
2022-09-05 23:13:53 +02:00
if (_pointMasses == null)
2022-08-31 22:18:47 +02:00
{
2022-09-05 23:13:53 +02:00
_pointMasses = new IPointMass[_pointMassPaths.Length];
// give each body an orbit around ourselves
for (int i = 0; i < _pointMassPaths.Length; i++)
{
_pointMasses[i] = GetNode<IPointMass>(_pointMassPaths[i]);
}
}
2022-09-05 23:13:53 +02:00
return _pointMasses;
2022-08-31 22:18:47 +02:00
}
}
2022-09-05 23:13:53 +02:00
public double Mass
2022-08-31 22:18:47 +02:00
{
get
{
2022-09-05 23:13:53 +02:00
double mass = 0;
foreach (var pointMass in _pointMasses)
{
2022-09-05 23:13:53 +02:00
mass += pointMass.Mass;
}
2022-09-05 23:13:53 +02:00
return mass;
}
}
2022-09-05 23:13:53 +02:00
public DVector3 Position { get; set; }
private Orbit _orbit = null;
private Orbit Orbit
{
get
{
if (_orbit == null)
{
_orbit = new Orbit();
}
return _orbit;
}
}
private ImmediateGeometry _orbitGeometry = null;
public ImmediateGeometry OrbitGeometry
{
get
{
if (_orbitGeometry == null)
{
_orbitGeometry = new ImmediateGeometry();
var m = new SpatialMaterial();
m.VertexColorUseAsAlbedo = true;
m.FlagsUnshaded = true;
_orbitGeometry.MaterialOverride = m;
AddChild(_orbitGeometry);
}
return _orbitGeometry;
}
}
private float _time = 0;
[Export]
private float _speed = 3f;
public override void _Process(float delta)
{
_time += delta * _speed;
InvalidateGeometry();
}
2022-08-31 22:18:47 +02:00
private void InvalidateGeometry()
2022-08-31 22:18:47 +02:00
{
Orbit.Ellipse = new Ellipse(SemiMajorAxis, Eccentricity);
Orbit.Draw(OrbitGeometry);
2022-08-31 22:18:47 +02:00
2022-09-05 23:13:53 +02:00
Orbiter.Position = Orbit.GetPosition(_time);
2022-08-31 22:18:47 +02:00
}
}