mirror of
https://github.com/Facepunch/sbox-public.git
synced 2026-04-20 22:38:16 -04:00
https://files.facepunch.com/antopilo/1b0311b1/sbox-dev_Ghn3TRf8eM.mp4 https://files.facepunch.com/antopilo/1b0311b1/sbox-dev_yALD2nMaPw.mp4
80 lines
1.7 KiB
C#
80 lines
1.7 KiB
C#
using System.Runtime.InteropServices;
|
|
|
|
namespace Sandbox.Clutter;
|
|
|
|
/// <summary>
|
|
/// Custom scene object for rendering batched clutter models.
|
|
/// Groups instances by model type for efficient GPU instanced rendering.
|
|
/// </summary>
|
|
internal class ClutterBatchSceneObject : SceneCustomObject
|
|
{
|
|
/// <summary>
|
|
/// Batches by model
|
|
/// </summary>
|
|
private readonly Dictionary<Model, ClutterModelBatch> _batches = [];
|
|
|
|
public ClutterBatchSceneObject( SceneWorld world ) : base( world )
|
|
{
|
|
Flags.IsOpaque = true;
|
|
Flags.IsTranslucent = false;
|
|
Flags.CastShadows = true;
|
|
Flags.WantsPrePass = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds a clutter instance to the appropriate batch.
|
|
/// </summary>
|
|
public void AddInstance( ClutterInstance instance )
|
|
{
|
|
if ( instance.Entry?.Model == null )
|
|
return;
|
|
|
|
var model = instance.Entry.Model;
|
|
|
|
if ( !_batches.TryGetValue( model, out var batch ) )
|
|
{
|
|
batch = new ClutterModelBatch( model );
|
|
_batches[model] = batch;
|
|
}
|
|
|
|
batch.AddInstance( instance.Transform );
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clears all batches.
|
|
/// </summary>
|
|
public void Clear()
|
|
{
|
|
foreach ( var batch in _batches.Values )
|
|
batch.Clear();
|
|
|
|
_batches.Clear();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called when the batch is deleted. Cleans up resources.
|
|
/// </summary>
|
|
public new void Delete()
|
|
{
|
|
Clear();
|
|
base.Delete();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Renders all batched instances using GPU instancing.
|
|
/// </summary>
|
|
public override void RenderSceneObject()
|
|
{
|
|
if ( _batches.Count == 0 )
|
|
return;
|
|
|
|
foreach ( var (model, batch) in _batches )
|
|
{
|
|
if ( batch.Transforms.Count == 0 || model == null )
|
|
continue;
|
|
|
|
Graphics.DrawModelInstanced( model, CollectionsMarshal.AsSpan( batch.Transforms ) );
|
|
}
|
|
}
|
|
}
|