Don't use worldbounds for PVS (#2473)

This commit is contained in:
metalgearsloth
2022-02-15 21:07:41 +11:00
committed by GitHub
parent 162e646404
commit e7c4bf7341
3 changed files with 24 additions and 21 deletions

View File

@@ -5,30 +5,31 @@ namespace Robust.Server.GameStates;
public struct ChunkIndicesEnumerator
{
private Vector2i _topLeft;
private Vector2i _bottomRight;
private Vector2i _bottomLeft;
private Vector2i _topRight;
private int _x;
private int _y;
public ChunkIndicesEnumerator(Box2 viewBox, float chunkSize)
public ChunkIndicesEnumerator(Vector2 viewPos, float range, float chunkSize)
{
_topLeft = (viewBox.TopLeft / chunkSize).Floored();
_bottomRight = (viewBox.BottomRight / chunkSize).Floored();
_bottomLeft = ((viewPos - range) / chunkSize).Floored();
// Also floor this as we get the whole chunk anyway.
_topRight = ((viewPos + range) / chunkSize).Floored();
_x = _topLeft.X;
_y = _bottomRight.Y;
_x = _bottomLeft.X;
_y = _bottomLeft.Y;
}
public bool MoveNext([NotNullWhen(true)] out Vector2i? chunkIndices)
{
if (_y > _topLeft.Y)
if (_y > _topRight.Y)
{
_x++;
_y = _bottomRight.Y;
_y = _bottomLeft.Y;
}
if (_x > _bottomRight.X)
if (_x > _topRight.X)
{
chunkIndices = null;
return false;

View File

@@ -323,7 +323,7 @@ internal sealed partial class PVSSystem : EntitySystem
foreach (var eyeEuid in viewers)
{
var (viewBox, mapId) = CalcViewBounds(in eyeEuid, transformQuery);
var (viewPos, range, mapId) = CalcViewBounds(in eyeEuid, transformQuery);
uint visMask = EyeComponent.DefaultVisibilityMask;
if (eyeQuery.TryGetComponent(eyeEuid, out var eyeComp))
@@ -332,7 +332,7 @@ internal sealed partial class PVSSystem : EntitySystem
//todo at some point just register the viewerentities as localoverrides
TryAddToVisibleEnts(in eyeEuid, seenSet, playerVisibleSet, visibleEnts, fromTick, ref newEntitiesSent, ref entitiesSent, metadataQuery, transformQuery, visMask, dontSkip: true);
var mapChunkEnumerator = new ChunkIndicesEnumerator(viewBox, ChunkSize);
var mapChunkEnumerator = new ChunkIndicesEnumerator(viewPos, range, ChunkSize);
while (mapChunkEnumerator.MoveNext(out var chunkIndices))
{
@@ -345,13 +345,13 @@ internal sealed partial class PVSSystem : EntitySystem
}
}
_mapManager.FindGridsIntersectingEnumerator(mapId, viewBox, out var gridEnumerator, true);
_mapManager.FindGridsIntersectingEnumerator(mapId, new Box2(viewPos - range, viewPos + range), out var gridEnumerator, true);
while (gridEnumerator.MoveNext(out var mapGrid))
{
var gridXform = transformQuery.GetComponent(mapGrid.GridEntityId);
var localPos = transformQuery.GetComponent(mapGrid.GridEntityId).InvWorldMatrix.Transform(viewPos);
var gridChunkEnumerator =
new ChunkIndicesEnumerator(gridXform.InvWorldMatrix.TransformBox(viewBox), ChunkSize);
new ChunkIndicesEnumerator(localPos, range, ChunkSize);
while (gridChunkEnumerator.MoveNext(out var gridChunkIndices))
{
@@ -638,14 +638,10 @@ internal sealed partial class PVSSystem : EntitySystem
}
// Read Safe
private (Box2 view, MapId mapId) CalcViewBounds(in EntityUid euid, EntityQuery<TransformComponent> transformQuery)
private (Vector2 worldPos, float range, MapId mapId) CalcViewBounds(in EntityUid euid, EntityQuery<TransformComponent> transformQuery)
{
var xform = transformQuery.GetComponent(euid);
var view = Box2.UnitCentered.Scale(_viewSize).Translated(xform.WorldPosition);
var map = xform.MapID;
return (view, map);
return (xform.WorldPosition, _viewSize / 2f, xform.MapID);
}
}

View File

@@ -130,6 +130,12 @@ namespace Robust.Shared.Maths
return new((int) MathF.Floor(X), (int) MathF.Floor(Y));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector2i Ceiled()
{
return new((int) MathF.Ceiling(X), (int) MathF.Ceiling(Y));
}
/// <summary>
/// Subtracts a vector from another, returning a new vector.
/// </summary>