mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-09-06 17:58:05 +02:00
Refactors SpriteSystem to use the GetEntitiesIntersecting spatial query instead of depth-first traversal of the scene graph, for increased performance.
This commit is contained in:
@@ -1,67 +1,39 @@
|
||||
using Robust.Client.Graphics.ClientEye;
|
||||
using JetBrains.Annotations;
|
||||
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
|
||||
{
|
||||
/// <summary>
|
||||
/// Updates the layer animation for every visible sprite.
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
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));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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 pvsBounds = _eyeManager.GetWorldViewport().Enlarged(5);
|
||||
|
||||
var mapEntity = _mapManager.GetMapEntityId(eye.Position.MapId);
|
||||
var pvsEntities = EntityManager.GetEntitiesIntersecting(_eyeManager.CurrentMap, pvsBounds, true);
|
||||
|
||||
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)
|
||||
foreach (var entity in pvsEntities)
|
||||
{
|
||||
var child = EntityManager.GetEntity(childUid);
|
||||
if (child.TryGetComponent(out ISpriteComponent sprite))
|
||||
{
|
||||
var worldPosition = Matrix3.Transform(matrix, child.Transform.LocalPosition);
|
||||
if (!entity.TryGetComponent(out ISpriteComponent sprite))
|
||||
continue;
|
||||
|
||||
if (!sprite.IsInert && bounds.Contains(worldPosition))
|
||||
{
|
||||
sprite.FrameUpdate(frameTime);
|
||||
}
|
||||
}
|
||||
if (sprite.IsInert)
|
||||
continue;
|
||||
|
||||
if (child.Transform.ChildCount != 0)
|
||||
{
|
||||
RunUpdatesRecurse(frameTime, bounds, child, ref matrix);
|
||||
}
|
||||
sprite.FrameUpdate(frameTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user