Initial orbiting craft
This commit is contained in:
@@ -2,6 +2,7 @@ using System.Diagnostics;
|
||||
using Godot;
|
||||
using ImGuiNET;
|
||||
using Quadratic.Carto.MathExt;
|
||||
using Vim.Math3d;
|
||||
|
||||
namespace Quadratic.Carto.Craft;
|
||||
|
||||
@@ -20,8 +21,24 @@ public sealed partial class Krakensbane : Node3D
|
||||
public Node3D? FocusedVessel { get; set; }
|
||||
|
||||
const float maxDistance = 500.0f;
|
||||
const float planetRadius = 6372.0f;
|
||||
|
||||
DVector3 originPosition = DVector3.Zero;
|
||||
DVector3 originPosition = DVector3.UnitY * planetRadius;
|
||||
|
||||
/// <summary>
|
||||
/// Something to manage the non-inertial frame of reference.
|
||||
/// </summary>
|
||||
/// <para>
|
||||
/// It's good to have an inertial frame of reference when you're close to
|
||||
/// a lot of static stuff, like on the ground. However, a non-inertial frame
|
||||
/// of reference might be more appropriate when you're in deep space.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// This provider field is null if we're using an inertial frame of reference.
|
||||
/// When it's not null, it should be responsible for managing the acceleration,
|
||||
/// angular acceleration, and even positions and/or rotations of children
|
||||
/// objects.
|
||||
INonInertialFrameProvider? nonInertialFrameProvider;
|
||||
|
||||
public override void _PhysicsProcess(double delta)
|
||||
{
|
||||
@@ -52,6 +69,27 @@ public sealed partial class Krakensbane : Node3D
|
||||
|
||||
originPosition += vesselPosition.AsVim().AsDouble();
|
||||
}
|
||||
|
||||
// Apply gravity
|
||||
foreach (var child in GetChildren())
|
||||
{
|
||||
if (child is RigidBody3D rb)
|
||||
{
|
||||
var localPosition = rb.Transform.Origin.AsVim().AsDouble();
|
||||
var globalPosition = originPosition + localPosition;
|
||||
var gravityVector = -globalPosition.Normalize();
|
||||
var floatGravityVector = gravityVector.AsSingle().AsGodot();
|
||||
var distance = globalPosition.Length();
|
||||
var gravity = 9.81f * planetRadius * planetRadius / (distance * distance);
|
||||
rb.ApplyCentralForce(floatGravityVector * (float)gravity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public DVector3 GetPositionOf(Node3D node)
|
||||
{
|
||||
var localPosition = node.Transform.Origin.AsVim().AsDouble();
|
||||
return originPosition + localPosition;
|
||||
}
|
||||
|
||||
public override void _Process(double delta)
|
||||
@@ -61,3 +99,9 @@ public sealed partial class Krakensbane : Node3D
|
||||
ImGui.End();
|
||||
}
|
||||
}
|
||||
|
||||
public interface INonInertialFrameProvider
|
||||
{
|
||||
public DVector3 GetCurrentAcceleration();
|
||||
public DVector3 GetCurrentAngularAcceleration();
|
||||
}
|
||||
|
||||
14
src/Craft/Vessel.cs
Normal file
14
src/Craft/Vessel.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using Godot;
|
||||
|
||||
namespace Quadratic.Carto.Craft;
|
||||
|
||||
/// <summary>
|
||||
/// A Vessel is the smallest unit of object in the game that is considered a
|
||||
/// whole on its own, such as a space station or an astronaut. Connections can
|
||||
/// be made between vessels, but each vessel is still a separate entity.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Vessel is an abstract class, and is meant to be extended by concrete
|
||||
/// implementations.
|
||||
/// </remarks>
|
||||
public abstract class Vessel { }
|
||||
9
src/Craft/VesselNode.cs
Normal file
9
src/Craft/VesselNode.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using Godot;
|
||||
|
||||
namespace Quadratic.Carto.Craft;
|
||||
|
||||
/// <summary>
|
||||
/// A VesselNode is the node that represents a <see cref="Vessel"/> currently
|
||||
/// loaded into the game world.
|
||||
/// </summary>
|
||||
public abstract partial class VesselNode : Node3D { }
|
||||
64
src/Testing/DebugUI.cs
Normal file
64
src/Testing/DebugUI.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
using System.Collections.Generic;
|
||||
using Godot;
|
||||
using Quadratic.Carto.Craft;
|
||||
using Quadratic.Carto.MathExt;
|
||||
|
||||
namespace Quadratic.Carto.Testing;
|
||||
|
||||
public partial class DebugUI : Control
|
||||
{
|
||||
[Export]
|
||||
Control minimapContainer = null!;
|
||||
|
||||
[Export]
|
||||
Vector2 minimapSize = new Vector2(360, 360);
|
||||
|
||||
[Export]
|
||||
float minimapSizeUnit = 6372;
|
||||
|
||||
[Export]
|
||||
float minimapUnitLength = 90;
|
||||
|
||||
[Export]
|
||||
Polygon2D planetOutline = null!;
|
||||
|
||||
[Export]
|
||||
Control vesselIndicator = null!;
|
||||
|
||||
[Export]
|
||||
Krakensbane krakensbane = null!;
|
||||
|
||||
[Export]
|
||||
Label displayLabel = null!;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
// draw the planet outline
|
||||
var polygon = new List<Vector2>();
|
||||
const int maxPoints = 360;
|
||||
var minimapCenter = minimapSize / 2;
|
||||
for (int i = 0; i < maxPoints; i++)
|
||||
{
|
||||
var angle = (float)i / maxPoints * Mathf.Pi * 2;
|
||||
var point = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)) * minimapUnitLength + minimapCenter;
|
||||
polygon.Add(point);
|
||||
}
|
||||
planetOutline.Polygon = polygon.ToArray();
|
||||
}
|
||||
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
if (krakensbane.FocusedVessel == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var vesselPosition = krakensbane.GetPositionOf(krakensbane.FocusedVessel);
|
||||
var minimapCenter = minimapSize / 2;
|
||||
var minimapPosition3D = (vesselPosition / minimapSizeUnit).AsSingle().AsGodot() * minimapUnitLength;
|
||||
var minimapPosition2D = new Vector2(-minimapPosition3D.Y, minimapPosition3D.X) + minimapCenter;
|
||||
vesselIndicator.Position = minimapPosition2D;
|
||||
|
||||
displayLabel.Text = $"Vessel position:\n{vesselPosition.X},\n{vesselPosition.Y},\n{vesselPosition.Z}";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user