2022-08-31 22:18:47 +02:00
|
|
|
using Godot;
|
|
|
|
using System;
|
2022-09-05 23:13:53 +02:00
|
|
|
using System.Collections.Generic;
|
2022-09-04 12:35:13 +02:00
|
|
|
using Vim.Math3d;
|
2022-08-31 22:18:47 +02:00
|
|
|
|
2022-09-04 12:35:13 +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
|
|
|
|
2022-09-04 12:35:13 +02:00
|
|
|
private double _semiMajorAxis;
|
2022-08-31 22:18:47 +02:00
|
|
|
[Export]
|
2022-09-04 12:35:13 +02:00
|
|
|
private double SemiMajorAxis
|
2022-08-31 22:18:47 +02:00
|
|
|
{
|
2022-09-04 12:35:13 +02:00
|
|
|
get => _semiMajorAxis;
|
|
|
|
set
|
2022-08-31 22:18:47 +02:00
|
|
|
{
|
2022-09-04 12:35:13 +02:00
|
|
|
_semiMajorAxis = value;
|
|
|
|
|
|
|
|
if (!Engine.EditorHint) return;
|
2022-08-31 22:18:47 +02:00
|
|
|
|
2022-09-04 12:35:13 +02:00
|
|
|
InvalidateGeometry();
|
2022-08-31 22:18:47 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-09-04 12:35:13 +02:00
|
|
|
private double _eccentricity;
|
|
|
|
[Export(PropertyHint.Range, "0,1")]
|
|
|
|
private double Eccentricity
|
2022-08-31 22:18:47 +02:00
|
|
|
{
|
2022-09-04 12:35:13 +02:00
|
|
|
get => _eccentricity;
|
|
|
|
set
|
|
|
|
{
|
|
|
|
_eccentricity = value;
|
2022-08-31 22:18:47 +02:00
|
|
|
|
2022-09-04 12:35:13 +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
|
|
|
{
|
2022-09-04 12:35:13 +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-04 12:35:13 +02:00
|
|
|
}
|
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
|
|
|
{
|
2022-09-04 12:35:13 +02:00
|
|
|
get
|
|
|
|
{
|
2022-09-05 23:13:53 +02:00
|
|
|
double mass = 0;
|
|
|
|
foreach (var pointMass in _pointMasses)
|
2022-09-04 12:35:13 +02:00
|
|
|
{
|
2022-09-05 23:13:53 +02:00
|
|
|
mass += pointMass.Mass;
|
2022-09-04 12:35:13 +02:00
|
|
|
}
|
2022-09-05 23:13:53 +02:00
|
|
|
return mass;
|
2022-09-04 12:35:13 +02:00
|
|
|
}
|
|
|
|
}
|
2022-09-05 23:13:53 +02:00
|
|
|
public DVector3 Position { get; set; }
|
2022-09-04 12:35:13 +02:00
|
|
|
|
|
|
|
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
|
|
|
|
2022-09-04 12:35:13 +02:00
|
|
|
private void InvalidateGeometry()
|
2022-08-31 22:18:47 +02:00
|
|
|
{
|
2022-09-04 12:35:13 +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
|
|
|
}
|
|
|
|
}
|