mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
Make PvsSystem consider offset and zoom from EyeComponent (#5228)
* Make PvsSystem consider offset and zoom from EyeComponent * Just use PvsScale float * float.IsFinite --------- Co-authored-by: geraeumig <alfenos@proton.me> Co-authored-by: ElectroJr <leonsfriedrich@gmail.com>
This commit is contained in:
@@ -80,14 +80,17 @@ internal sealed partial class PvsSystem
|
||||
// Update visibility masks & viewer positions
|
||||
// TODO PVS do this before sending state.
|
||||
// I,e, we already enumerate over all eyes when computing visible chunks.
|
||||
Span<MapCoordinates> positions = stackalloc MapCoordinates[session.Viewers.Length];
|
||||
Span<(MapCoordinates pos, float scale)> positions = stackalloc (MapCoordinates, float)[session.Viewers.Length];
|
||||
int i = 0;
|
||||
foreach (var viewer in session.Viewers)
|
||||
{
|
||||
if (viewer.Comp2 != null)
|
||||
session.VisMask |= viewer.Comp2.VisibilityMask;
|
||||
|
||||
positions[i++] = _transform.GetMapCoordinates(viewer.Owner, viewer.Comp1);
|
||||
var mapCoordinates = _transform.GetMapCoordinates(viewer.Owner, viewer.Comp1);
|
||||
mapCoordinates = mapCoordinates.Offset(viewer.Comp2?.Offset ?? Vector2.Zero);
|
||||
var scale = MathF.Max((viewer.Comp2?.PvsScale ?? 1), 0.1f);
|
||||
positions[i++] = (mapCoordinates, scale);
|
||||
}
|
||||
|
||||
if (!CullingEnabled || session.DisableCulling)
|
||||
@@ -112,7 +115,7 @@ internal sealed partial class PvsSystem
|
||||
DebugTools.Assert(!chunk.UpdateQueued);
|
||||
DebugTools.Assert(!chunk.Dirty);
|
||||
|
||||
foreach (var pos in positions)
|
||||
foreach (var (pos, scale) in positions)
|
||||
{
|
||||
if (pos.MapId != chunk.Position.MapId)
|
||||
continue;
|
||||
@@ -120,8 +123,9 @@ internal sealed partial class PvsSystem
|
||||
dist = Math.Min(dist, (pos.Position - chunk.Position.Position).LengthSquared());
|
||||
|
||||
var relative = Vector2.Transform(pos.Position, chunk.InvWorldMatrix) - chunk.Centre;
|
||||
|
||||
relative = Vector2.Abs(relative);
|
||||
chebDist = Math.Min(chebDist, Math.Max(relative.X, relative.Y));
|
||||
chebDist = Math.Min(chebDist, Math.Max(relative.X, relative.Y) / scale);
|
||||
}
|
||||
|
||||
distances.Add(dist);
|
||||
|
||||
@@ -362,8 +362,19 @@ internal sealed partial class PvsSystem : EntitySystem
|
||||
|
||||
private (Vector2 worldPos, float range, EntityUid? map) CalcViewBounds(Entity<TransformComponent, EyeComponent?> eye)
|
||||
{
|
||||
var size = Math.Max(eye.Comp2?.PvsSize ?? _priorityViewSize, 1);
|
||||
return (_transform.GetWorldPosition(eye.Comp1), size / 2f, eye.Comp1.MapUid);
|
||||
var size = _priorityViewSize;
|
||||
var worldPos = _transform.GetWorldPosition(eye.Comp1);
|
||||
|
||||
if (eye.Comp2 is not null)
|
||||
{
|
||||
// not using EyeComponent.Eye.Position, because it's updated only on the client's side
|
||||
worldPos += eye.Comp2.Offset;
|
||||
size *= eye.Comp2.PvsScale;
|
||||
}
|
||||
|
||||
size = Math.Max(size, 1);
|
||||
|
||||
return (worldPos, size / 2f, eye.Comp1.MapUid);
|
||||
}
|
||||
|
||||
private void CullDeletionHistoryUntil(GameTick tick)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System.Numerics;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
|
||||
@@ -41,6 +40,9 @@ namespace Robust.Shared.GameObjects
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField("zoom")]
|
||||
public Vector2 Zoom = Vector2.One;
|
||||
|
||||
/// <summary>
|
||||
/// Eye offset, relative to the map, and not affected by <see cref="Rotation"/>
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField("offset"), AutoNetworkedField]
|
||||
public Vector2 Offset;
|
||||
|
||||
@@ -52,9 +54,13 @@ namespace Robust.Shared.GameObjects
|
||||
public int VisibilityMask = DefaultVisibilityMask;
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the PVS view range of this eye, Effectively a per-eye <see cref="CVars.NetMaxUpdateRange"/> cvar.
|
||||
/// Scaling factor for the PVS view range of this eye. This effectively allows the
|
||||
/// <see cref="CVars.NetMaxUpdateRange"/> and <see cref="CVars.NetPvsPriorityRange"/> cvars to be configured per
|
||||
/// eye.
|
||||
/// </summary>
|
||||
[DataField] public float? PvsSize;
|
||||
[Access(typeof(SharedEyeSystem))]
|
||||
[DataField]
|
||||
public float PvsScale = 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Maths;
|
||||
@@ -97,6 +98,23 @@ public abstract class SharedEyeSystem : EntitySystem
|
||||
eyeComponent.Eye.Zoom = value;
|
||||
}
|
||||
|
||||
public void SetPvsScale(Entity<EyeComponent?> eye, float scale)
|
||||
{
|
||||
if (!Resolve(eye.Owner, ref eye.Comp, false))
|
||||
return;
|
||||
|
||||
// Prevent a admin or some other fuck-up from causing exception spam in PVS system due to divide-by-zero or
|
||||
// other such issues
|
||||
if (!float.IsFinite(scale))
|
||||
{
|
||||
Log.Error($"Attempted to set pvs scale to invalid value: {scale}. Eye: {ToPrettyString(eye)}");
|
||||
SetPvsScale(eye, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
eye.Comp.PvsScale = Math.Clamp(scale, 0.1f, 100f);
|
||||
}
|
||||
|
||||
public void SetVisibilityMask(EntityUid uid, int value, EyeComponent? eyeComponent = null)
|
||||
{
|
||||
if (!Resolve(uid, ref eyeComponent))
|
||||
|
||||
@@ -31,6 +31,9 @@ namespace Robust.Shared.Graphics
|
||||
set => _coords = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Eye offset, relative to the map, and not affected by <see cref="Rotation"/>
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public Vector2 Offset { get; set; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user