using System; using System.Linq; using System.Numerics; using gaemstone.ECS; using static gaemstone.Client.Components.CameraComponents; using static gaemstone.Client.Components.InputComponents; using static gaemstone.Components.TransformComponents; namespace gaemstone.Client.Systems; [Module] [DependsOn] [DependsOn] [DependsOn] public class FreeCameraController { [Component] public struct CameraController { public float MouseSensitivity { get; set; } } [System] public static void UpdateCamera( Universe universe, TimeSpan delta, in Camera camera, ref GlobalTransform transform, ref CameraController controller) { var input = universe.LookupByType(); var mouse = universe.LookupByType(); var keyboard = universe.LookupByType(); if ((input == null) || (mouse == null) || (keyboard == null)) return; var module = universe.LookupByTypeOrThrow(); var capturedBy = input.GetTargets().FirstOrDefault(); var inputCapturedBy = input.GetTargets().FirstOrDefault(); var isCaptured = (capturedBy != null); // If another system has the mouse captured, don't do anything here. if (isCaptured && (capturedBy != module)) return; var isMouseDown = ((inputCapturedBy == null) || (inputCapturedBy == module)) && mouse.LookupChild("Buttons/Right")?.Has() == true; if (isMouseDown != isCaptured) { if (isMouseDown) input.Add(module); else { input.Remove(module); input.Remove(module); input.Remove(module); } } var mouseMovement = Vector2.Zero; if (isCaptured) { var raw = (Vector2?)mouse.LookupChild("Delta")?.GetOrThrow() ?? default; mouseMovement = raw * controller.MouseSensitivity * (float)delta.TotalSeconds; } if (camera.IsOrthographic) { transform *= Matrix4x4.CreateTranslation(-mouseMovement.X, -mouseMovement.Y, 0); } else { var shift = keyboard.LookupChild("ShiftLeft")?.Has() == true; var w = keyboard.LookupChild("W")?.Has() == true; var a = keyboard.LookupChild("A")?.Has() == true; var s = keyboard.LookupChild("S")?.Has() == true; var d = keyboard.LookupChild("D")?.Has() == true; var speed = (shift ? 12 : 4) * (float)delta.TotalSeconds; var forwardMovement = ((w ? -1 : 0) + (s ? 1 : 0)) * speed; var sideMovement = ((a ? -1 : 0) + (d ? 1 : 0)) * speed; var curTranslation = new Vector3(transform.Value.M41, transform.Value.M42, transform.Value.M43); var yawRotation = Matrix4x4.CreateRotationY(-mouseMovement.X / 100, curTranslation); var pitchRotation = Matrix4x4.CreateRotationX(-mouseMovement.Y / 100); var translation = Matrix4x4.CreateTranslation(sideMovement, 0, forwardMovement); transform = translation * pitchRotation * transform * yawRotation; } } }