|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|