Remove Eye Lerping from engine. (#2371)

This commit is contained in:
Vera Aguilera Puerto
2021-12-25 19:05:07 +01:00
committed by GitHub
parent 394f51f70d
commit fcc16d67f7
6 changed files with 36 additions and 101 deletions

View File

@@ -7,8 +7,10 @@ using Robust.Shared.GameObjects;
using Robust.Shared.Input;
using Robust.Shared.Input.Binding;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Timing;
#nullable enable
@@ -18,26 +20,8 @@ namespace Robust.Client.GameObjects
/// Updates the position of every Eye every frame, so that the camera follows the player around.
/// </summary>
[UsedImplicitly]
internal class EyeUpdateSystem : EntitySystem
public class EyeUpdateSystem : EntitySystem
{
[Dependency] private readonly IEyeManager _eyeManager = default!;
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
private TransformComponent? _lastParent;
private TransformComponent? _lerpTo;
private Angle LerpStartRotation;
private float _accumulator;
public bool IsLerping { get => _lerpTo != null; }
// How fast the camera rotates in radians / s
private const float CameraRotateSpeed = MathF.PI;
// PER THIS AMOUNT OF TIME MILLISECONDS
private const float CameraRotateTimeUnit = 1.2f;
// Safety override
private const float _lerpTimeMax = CameraRotateTimeUnit + 0.4f;
/// <inheritdoc />
public override void Initialize()
{
@@ -65,77 +49,6 @@ namespace Robust.Client.GameObjects
/// <inheritdoc />
public override void FrameUpdate(float frameTime)
{
var currentEye = _eyeManager.CurrentEye;
// TODO: Content should have its own way of handling this. We should have a default behavior that they can overwrite.
EntityUid tempQualifier = _playerManager.LocalPlayer?.ControlledEntity ?? EntityUid.Invalid;
var playerTransform = (tempQualifier != EntityUid.Invalid ? EntityManager.GetComponent<TransformComponent>(tempQualifier) : null);
if (playerTransform == null) return;
var gridId = playerTransform.GridID;
TransformComponent parent;
if (gridId != GridId.Invalid &&
_mapManager.GetGrid(gridId).GridEntityId is var gridEnt &&
EntityManager.EntityExists(gridEnt))
parent = EntityManager.GetComponent<TransformComponent>(gridEnt);
else
{
parent = EntityManager.GetComponent<TransformComponent>(
_mapManager.GetMapEntityId(playerTransform.MapID));
}
// Make sure that we don't fire the vomit carousel when we spawn in
if (_lastParent is null)
_lastParent = parent;
// Set a default for target rotation
var parentRotation = -parent.WorldRotation;
// Reuse current rotation when stepping into space
if (parent.GridID == GridId.Invalid)
parentRotation = currentEye.Rotation;
// Handle grid change in general
if (_lastParent != parent)
_lerpTo = parent;
// And we are up and running!
if (_lerpTo is not null)
{
// Handle a case where we have beeing spinning around, but suddenly got off onto a different grid
if (parent != _lerpTo) {
LerpStartRotation = currentEye.Rotation;
_lerpTo = parent;
_accumulator = 0f;
}
_accumulator += frameTime;
var changeNeeded = (float) (LerpStartRotation - parentRotation).Theta;
var changeLerp = _accumulator / (Math.Abs(changeNeeded % MathF.PI) / CameraRotateSpeed * CameraRotateTimeUnit);
currentEye.Rotation = Angle.Lerp(LerpStartRotation, parentRotation, changeLerp);
// Either we have overshot, or we have taken way too long on this, emergency reset time
if (changeLerp > 1.0f || _accumulator >= _lerpTimeMax)
{
_lastParent = parent;
_lerpTo = null;
_accumulator = 0f;
}
}
// We are just fine, or we finished a lerp (and probably overshot)
if (_lerpTo is null)
{
currentEye.Rotation = parentRotation;
LerpStartRotation = parentRotation;
}
foreach (var eyeComponent in EntityManager.EntityQuery<EyeComponent>(true))
{
eyeComponent.UpdateEyePosition();

View File

@@ -14,7 +14,7 @@ namespace Robust.Client.GameObjects
/// Handles interpolation of transform positions.
/// </summary>
[UsedImplicitly]
internal sealed class TransformSystem : SharedTransformSystem
public sealed class TransformSystem : SharedTransformSystem
{
// Max distance per tick how far an entity can move before it is considered teleporting.
// TODO: Make these values somehow dependent on server TPS.

View File

@@ -32,14 +32,20 @@ namespace Robust.Client.Graphics
public IEye CurrentEye
{
get => _currentEye ?? _defaultEye;
set => _currentEye = value;
set
{
var old = _currentEye;
_currentEye = value;
_entityManager.EventBus.RaiseEvent(EventSource.Local, new CurrentEyeChangedEvent(old, _currentEye));
}
}
public IViewportControl MainViewport { get; set; } = default!;
public void ClearCurrentEye()
{
_currentEye = _defaultEye;
CurrentEye = _defaultEye;
}
void IEyeManager.Initialize()
@@ -146,4 +152,16 @@ namespace Robust.Client.Graphics
return MainViewport.ScreenToMap(point);
}
}
public class CurrentEyeChangedEvent : EntityEventArgs
{
public IEye? Old { get; }
public IEye New { get; }
public CurrentEyeChangedEvent(IEye? oldEye, IEye newEye)
{
Old = oldEye;
New = newEye;
}
}
}

View File

@@ -2,7 +2,7 @@ using Robust.Shared.GameObjects;
namespace Robust.Server.GameObjects
{
internal sealed class TransformSystem : SharedTransformSystem
public sealed class TransformSystem : SharedTransformSystem
{
}

View File

@@ -229,12 +229,16 @@ namespace Robust.Shared.Maths
/// </summary>
public static Angle Lerp(in Angle a, in Angle b, float factor)
{
var degA = MathHelper.RadiansToDegrees(Reduce(a));
var degB = MathHelper.RadiansToDegrees(Reduce(b));
var delta = MathHelper.Mod((degB - degA), 360);
if (delta > 180)
delta -= 360;
return new Angle(MathHelper.DegreesToRadians(degA + delta * MathHelper.Clamp(factor, 0, 1)));
return a + ShortestDistance(a, b) * factor;
}
/// <summary>
/// Returns the shortest distance between two angles.
/// </summary>
public static Angle ShortestDistance(in Angle a, in Angle b)
{
var delta = (b - a) % Math.Tau;
return 2 * delta % Math.Tau - delta;
}
/// <summary>

View File

@@ -8,7 +8,7 @@ using Robust.Shared.Utility;
namespace Robust.Shared.GameObjects
{
internal abstract class SharedTransformSystem : EntitySystem
public abstract class SharedTransformSystem : EntitySystem
{
[Dependency] private readonly IMapManager _mapManager = default!;