Files
RobustToolbox/Robust.Client/GameObjects/EntitySystems/SpriteSystem.cs
2020-02-06 16:10:14 +01:00

69 lines
2.6 KiB
C#

using Robust.Client.Graphics.ClientEye;
using Robust.Client.Interfaces.GameObjects.Components;
using Robust.Client.Interfaces.Graphics;
using Robust.Client.Interfaces.Graphics.ClientEye;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Map;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
namespace Robust.Client.GameObjects.EntitySystems
{
public class SpriteSystem : EntitySystem
{
#pragma warning disable 649
[Dependency] private readonly IClyde _clyde;
[Dependency] private readonly IEyeManager _eyeManager;
[Dependency] private readonly IMapManager _mapManager;
#pragma warning restore 649
public SpriteSystem()
{
EntityQuery = new TypeEntityQuery(typeof(ISpriteComponent));
}
public override void FrameUpdate(float frameTime)
{
var eye = _eyeManager.CurrentEye;
// So we could calculate the correct size of the entities based on the contents of their sprite...
// Or we can just assume that no entity is larger than 10x10 and get a stupid easy check.
// TODO: Make this check more accurate.
var worldBounds = Box2.CenteredAround(eye.Position.Position,
_clyde.ScreenSize / EyeManager.PIXELSPERMETER * eye.Zoom).Enlarged(5);
var mapEntity = _mapManager.GetMapEntityId(eye.Position.MapId);
var parentMatrix = Matrix3.Identity;
RunUpdatesRecurse(frameTime, worldBounds, EntityManager.GetEntity(mapEntity), ref parentMatrix);
}
private void RunUpdatesRecurse(float frameTime, Box2 bounds, IEntity entity, ref Matrix3 parentMatrix)
{
var localMatrix = entity.Transform.GetLocalMatrix();
Matrix3.Multiply(ref localMatrix, ref parentMatrix, out var matrix);
foreach (var childUid in entity.Transform.ChildEntityUids)
{
var child = EntityManager.GetEntity(childUid);
if (child.TryGetComponent(out ISpriteComponent sprite))
{
var worldPosition = Matrix3.Transform(matrix, child.Transform.LocalPosition);
if (!sprite.IsInert && bounds.Contains(worldPosition))
{
sprite.FrameUpdate(frameTime);
}
}
if (child.Transform.ChildCount != 0)
{
RunUpdatesRecurse(frameTime, bounds, child, ref matrix);
}
}
}
}
}