Files
sbox-public/engine/Sandbox.Engine/Scene/GameObjectSystems/InterpolationSystem.cs
Lorenz Junglas f4d40d54eb Optimize buffers walk in InterpolateFixedUpdate (#5125)
Drops interpolation buffer walks from 6 to 3 per object, this results in moderate perf gains for scenes with lots of moving objects.
2026-06-22 11:29:50 +02:00

72 lines
1.6 KiB
C#

using Sandbox.Utility;
namespace Sandbox;
/// <summary>
/// Updates interpolation for any <see cref="GameTransform"/> that needs it.
/// </summary>
[Expose]
sealed class InterpolationSystem : GameObjectSystem<InterpolationSystem>
{
HashSetEx<GameObject> _list { get; set; } = new();
[ConVar( "debug_interp", ConVarFlags.Protected | ConVarFlags.Cheat )]
static bool Debug { get; set; }
public InterpolationSystem( Scene scene ) : base( scene )
{
Listen( Stage.Interpolation, -1, Update, "UpdateInterpolation" );
}
/// <summary>
/// Add a <see cref="GameObject"/> to the interpolation list.
/// </summary>
internal void AddGameObject( GameObject go )
{
_list.Add( go );
}
/// <summary>
/// Remove a <see cref="GameObject"/> from the interpolation list.
/// </summary>
internal void RemoveGameObject( GameObject go )
{
_list.Remove( go );
}
private void Update()
{
var now = Time.NowDouble;
float updateFreq = ProjectSettings.Physics.FixedUpdateFrequency.Clamp( 1, 1000 );
// Keep more history to avoid culling data we might still need for interpolation
var cullBefore = now - (1f / updateFreq) * 2f;
foreach ( var go in _list.EnumerateLocked( true ) )
{
if ( go.IsValid() )
{
go.Transform.Update( now, cullBefore );
if ( Debug )
{
DrawDebug( go );
}
}
}
}
private void DrawDebug( GameObject go )
{
using var _ = Gizmo.Scope();
var targetWorld = go.WorldTransform;
var world = go.Transform.InterpolatedWorld;
Gizmo.Draw.Color = Color.White;
Gizmo.Draw.LineSphere( world.Position, 16f );
Gizmo.Draw.Color = Color.Cyan;
Gizmo.Draw.LineSphere( targetWorld.Position, 16f );
}
}