From a8ba625bfa0060dd18df765ea3b05e3afbb642b3 Mon Sep 17 00:00:00 2001 From: Yuki Kitagawa Date: Thu, 31 Oct 2024 22:46:27 +0800 Subject: [PATCH] Add krakensbane --- src/Craft/Krakensbane.cs | 51 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/Craft/Krakensbane.cs diff --git a/src/Craft/Krakensbane.cs b/src/Craft/Krakensbane.cs new file mode 100644 index 0000000..18f85f6 --- /dev/null +++ b/src/Craft/Krakensbane.cs @@ -0,0 +1,51 @@ +using System.Diagnostics; +using Godot; + +namespace Quadratic.Carto.Craft; + +/// +/// Krakensbane manages the position of its direct descendants, to ensure the +/// focused vessel is not too far from the origin. +/// +/// +/// The name Krakensbane is a legacy of the original KSP module which does the +/// same thing, i.e. preventing floating point errors from causing the vessel +/// to be thrown into deep space. +/// +public sealed partial class Krakensbane : Node3D +{ + Node3D? focusedVessel = null; + + const float maxDistance = 500.0f; + + public override void _PhysicsProcess(double delta) + { + Debug.Assert( + focusedVessel == null || focusedVessel.GetParent() == this, + "Focused vessel must be a direct descendant of Krakensbane" + ); + + if (focusedVessel == null) + { + return; + } + + var vesselPosition = focusedVessel.Transform.Origin; + var vesselDistance = vesselPosition.Length(); + if (vesselDistance > maxDistance) + { + // Reset the vessel's position to the origin + // TODO: save the total offset; we don't yet have a double-precision vector3 + var applyTransform = Transform3D.Identity.Translated(-vesselPosition); + + int n_children = GetChildCount(); + for (int i = 0; i < n_children; i++) + { + var child = GetChild(i); + child.Transform = applyTransform * child.Transform; + } + + GD.Print($"Resetting position; delta = {-vesselPosition}"); + } + } +}