You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

79 lines
3.0 KiB

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<gaemstone.Client.Components.CameraComponents>]
[DependsOn<gaemstone.Client.Components.InputComponents>]
[DependsOn<gaemstone.Components.TransformComponents>]
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<Input>();
var mouse = universe.LookupByType<Mouse>();
var keyboard = universe.LookupByType<Keyboard>();
if ((input == null) || (mouse == null) || (keyboard == null)) return;
var module = universe.LookupByTypeOrThrow<FreeCameraController>();
var capturedBy = input.GetTargets<CursorCapturedBy>().FirstOrDefault();
var inputCapturedBy = input.GetTargets<MouseInputCapturedBy>().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<Active>() == true;
if (isMouseDown != isCaptured) {
if (isMouseDown)
input.Add<CursorCapturedBy>(module);
else {
input.Remove<CursorCapturedBy>(module);
input.Remove<InputCapturedBy>(module);
input.Remove<MouseInputCapturedBy>(module);
}
}
var mouseMovement = Vector2.Zero;
if (isCaptured) {
var raw = (Vector2?)mouse.LookupChild("Delta")?.GetOrThrow<RawValue2D>() ?? 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<Active>() == true;
var w = keyboard.LookupChild("W")?.Has<Active>() == true;
var a = keyboard.LookupChild("A")?.Has<Active>() == true;
var s = keyboard.LookupChild("S")?.Has<Active>() == true;
var d = keyboard.LookupChild("D")?.Has<Active>() == 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;
}
}
}