diff --git a/player/CameraController.cs b/player/CameraController.cs index bd77858..62fcdd7 100644 --- a/player/CameraController.cs +++ b/player/CameraController.cs @@ -1,7 +1,8 @@ public partial class CameraController : SpringArm3D { [Export] public Vector2 MouseSensitivity { get; set; } = new(0.2f, 0.2f); // Degrees per pixel. - [Export] public float PitchMinimum { get; set; } = -90; + [Export] public float MovementSmoothing { get; set; } = 8.0f; + [Export] public float PitchMinimum { get; set; } = -85; [Export] public float PitchMaximum { get; set; } = -25; // FIXME: Fix the "snappyness" when moving slowly. @@ -12,6 +13,15 @@ public partial class CameraController : SpringArm3D public static bool IsMouseCaptured => Input.MouseMode == Input.MouseModeEnum.Captured; + Vector3 _offset; + Node3D _player; + public override void _Ready() + { + _offset = Position; + _player = this.GetParentOrThrow(); + Transform = _player.GlobalTransform.Translated(_offset); + } + public override void _Input(InputEvent ev) { if (IsMouseCaptured && ev.IsActionPressed("ui_cancel")) { @@ -44,4 +54,9 @@ public partial class CameraController : SpringArm3D pitch = Clamp(pitch, DegToRad(PitchMinimum), DegToRad(PitchMaximum)); Rotation = new(pitch, yaw, 0); } + + public override void _Process(double delta) + { + Position = Position.Damp(_offset + _player.GlobalPosition, MovementSmoothing, delta); + } } diff --git a/player/character.tscn b/player/character.tscn index 38e7538..357099e 100644 --- a/player/character.tscn +++ b/player/character.tscn @@ -32,6 +32,7 @@ script = ExtResource("1_akh08") [node name="CameraArm" type="SpringArm3D" parent="."] transform = Transform3D(1, 0, 0, 0, 0.766044, 0.642788, 0, -0.642788, 0.766044, 0, 0.1, 0) +top_level = true collision_mask = 3 spring_length = 2.0 margin = 0.05 diff --git a/terrain/Terrain+Editing.cs b/terrain/Terrain+Editing.cs index 9c6fc58..382e2ff 100644 --- a/terrain/Terrain+Editing.cs +++ b/terrain/Terrain+Editing.cs @@ -1,5 +1,4 @@ using System.IO; -using System.Runtime.InteropServices; public partial class Terrain { diff --git a/terrain/TerrainChunk.cs b/terrain/TerrainChunk.cs index b397845..079270e 100644 --- a/terrain/TerrainChunk.cs +++ b/terrain/TerrainChunk.cs @@ -15,6 +15,12 @@ public partial class TerrainChunk [Export] public byte[] Data { get; set; } = new byte[SizeInBytes]; + public bool IsEmpty { get { + foreach (var b in Data) + if (b != 0) return false; + return true; + } } + public ref Tile this[TilePos pos] { get { var tiles = MemoryMarshal.Cast(Data); return ref tiles[GetIndex(pos)]; diff --git a/utility/GodotExtensions.cs b/utility/GodotExtensions.cs index b16fb01..a68910e 100644 --- a/utility/GodotExtensions.cs +++ b/utility/GodotExtensions.cs @@ -1,7 +1,23 @@ public static class GodotExtensions { - public static Vector2I RoundToVector2I(this Vector2 vector) - => new(RoundToInt(vector.X), RoundToInt(vector.Y)); + public static T GetParentOrThrow(this Node node) + where T : class + { + var parent = node.GetParent(); + if (parent == null) throw new InvalidOperationException($"Parent of {node} is null"); + if (parent is not T result) throw new InvalidCastException($"Parent of {node} is {node.GetType()}, not {typeof(T)}"); + return result; + } + + public static T GetNodeOrThrow(this Node parent, NodePath path) + where T : class + { + var node = parent.GetNodeOrNull(path); + if (node == null) throw new InvalidOperationException($"Could not find node {path} from {parent}"); + if (node is not T result) throw new InvalidCastException($"Node {path} from {parent} is {node.GetType()}, not {typeof(T)}"); + return result; + } + public static (Corner, Corner) GetCorners(this Side side) => side switch { diff --git a/utility/MathExtensions.cs b/utility/MathExtensions.cs new file mode 100644 index 0000000..5b6a3e9 --- /dev/null +++ b/utility/MathExtensions.cs @@ -0,0 +1,12 @@ +public static class MathExtensions +{ + // Framerate independent dampening functions, similar to lerp. + // https://rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/ + public static float Damp(this float from, float to, float lambda, double delta) + => Lerp(from, to, 1 - Exp(-lambda * (float)delta)); + public static Vector3 Damp(this Vector3 from, Vector3 to, float lambda, double delta) + => from.Lerp(to, 1 - Exp(-lambda * (float)delta)); + + public static Vector2I RoundToVector2I(this Vector2 vector) + => new(RoundToInt(vector.X), RoundToInt(vector.Y)); +}