protected override void OnDecalRemoved(EntityUid gridId, uint decalId, DecalGridComponent component, Vector2i indices, DecalChunk chunk)
{
base.OnDecalRemoved(gridId, decalId, component, indices, chunk);
-
- if (!component.DecalZIndexIndex.Remove(decalId, out var zIndex))
- return;
-
- if (!component.DecalRenderIndex.TryGetValue(zIndex, out var renderIndex))
- return;
-
- renderIndex.Remove(decalId);
- if (renderIndex.Count == 0)
- component.DecalRenderIndex.Remove(zIndex);
+ DebugTools.Assert(chunk.Decals.ContainsKey(decalId));
+ chunk.Decals.Remove(decalId);
}
private void OnHandleState(EntityUid gridUid, DecalGridComponent gridComp, ref ComponentHandleState args)
private void UpdateChunks(EntityUid gridId, DecalGridComponent gridComp, Dictionary<Vector2i, DecalChunk> updatedGridChunks)
{
var chunkCollection = gridComp.ChunkCollection.ChunkCollection;
- var renderIndex = gridComp.DecalRenderIndex;
- var zIndexIndex = gridComp.DecalZIndexIndex;
// Update any existing data / remove decals we didn't receive data for.
foreach (var (indices, newChunkData) in updatedGridChunks)
foreach (var (uid, decal) in newChunkData.Decals)
{
- if (zIndexIndex.TryGetValue(uid, out var zIndex))
- renderIndex[zIndex].Remove(uid);
-
- renderIndex.GetOrNew(decal.ZIndex)[uid] = decal;
- zIndexIndex[uid] = decal.ZIndex;
gridComp.DecalIndex[uid] = indices;
}
}
using Robust.Client.Graphics;
using Robust.Shared.Enums;
using Robust.Shared.Map;
+using Robust.Shared.Map.Enumerators;
using Robust.Shared.Prototypes;
namespace Content.Client.Decals.Overlays
private readonly Dictionary<string, (Texture Texture, bool SnapCardinals)> _cachedTextures = new(64);
+ private readonly List<(uint Id, Decal Decal)> _decals = new();
+
public DecalOverlay(
SpriteSystem sprites,
IEntityManager entManager,
if (args.MapId == MapId.Nullspace)
return;
- var grid = Grid;
+ var owner = Grid.Owner;
- if (!_entManager.TryGetComponent(grid, out DecalGridComponent? decalGrid) ||
- !_entManager.TryGetComponent(grid, out TransformComponent? xform))
+ if (!_entManager.TryGetComponent(owner, out DecalGridComponent? decalGrid) ||
+ !_entManager.TryGetComponent(owner, out TransformComponent? xform))
{
return;
}
var xformSystem = _entManager.System<TransformSystem>();
var eyeAngle = args.Viewport.Eye?.Rotation ?? Angle.Zero;
- var zIndexDictionary = decalGrid.DecalRenderIndex;
+ var gridAABB = xformSystem.GetInvWorldMatrix(xform).TransformBox(args.WorldBounds.Enlarged(1f));
+ var chunkEnumerator = new ChunkIndicesEnumerator(gridAABB, SharedDecalSystem.ChunkSize);
+ _decals.Clear();
+
+ while (chunkEnumerator.MoveNext(out var index))
+ {
+ if (!decalGrid.ChunkCollection.ChunkCollection.TryGetValue(index.Value, out var chunk))
+ continue;
+
+ foreach (var (id, decal) in chunk.Decals)
+ {
+ if (!gridAABB.Contains(decal.Coordinates))
+ continue;
+
+ _decals.Add((id, decal));
+ }
+ }
- if (zIndexDictionary.Count == 0)
+ if (_decals.Count == 0)
return;
- var (_, worldRot, worldMatrix) = xformSystem.GetWorldPositionRotationMatrix(xform);
+ _decals.Sort((x, y) =>
+ {
+ var zComp = x.Decal.ZIndex.CompareTo(y.Decal.ZIndex);
+ if (zComp != 0)
+ return zComp;
+
+ return x.Id.CompareTo(y.Id);
+ });
+
+ var (_, worldRot, worldMatrix) = xformSystem.GetWorldPositionRotationMatrix(xform);
handle.SetTransform(worldMatrix);
- foreach (var decals in zIndexDictionary.Values)
+ foreach (var (_, decal) in _decals)
{
- foreach (var decal in decals.Values)
+ if (!_cachedTextures.TryGetValue(decal.Id, out var cache))
{
- if (!_cachedTextures.TryGetValue(decal.Id, out var cache))
+ // Nothing to cache someone messed up
+ if (!_prototypeManager.TryIndex<DecalPrototype>(decal.Id, out var decalProto))
{
- // Nothing to cache someone messed up
- if (!_prototypeManager.TryIndex<DecalPrototype>(decal.Id, out var decalProto))
- {
- continue;
- }
-
- cache = (_sprites.Frame0(decalProto.Sprite), decalProto.SnapCardinals);
- _cachedTextures[decal.Id] = cache;
+ continue;
}
- var cardinal = Angle.Zero;
-
- if (cache.SnapCardinals)
- {
- var worldAngle = eyeAngle + worldRot;
- cardinal = worldAngle.GetCardinalDir().ToAngle();
- }
+ cache = (_sprites.Frame0(decalProto.Sprite), decalProto.SnapCardinals);
+ _cachedTextures[decal.Id] = cache;
+ }
- var angle = decal.Angle - cardinal;
+ var cardinal = Angle.Zero;
- if (angle.Equals(Angle.Zero))
- handle.DrawTexture(cache.Texture, decal.Coordinates, decal.Color);
- else
- handle.DrawTexture(cache.Texture, decal.Coordinates, angle, decal.Color);
+ if (cache.SnapCardinals)
+ {
+ var worldAngle = eyeAngle + worldRot;
+ cardinal = worldAngle.GetCardinalDir().ToAngle();
}
+
+ var angle = decal.Angle - cardinal;
+
+ if (angle.Equals(Angle.Zero))
+ handle.DrawTexture(cache.Texture, decal.Coordinates, decal.Color);
+ else
+ handle.DrawTexture(cache.Texture, decal.Coordinates, angle, decal.Color);
}
handle.SetTransform(Matrix3.Identity);