VividPanelRenderer.cs
using Sandbox;
using System.Linq;
using VividPanels;
namespace VividPanels;
[Icon("preview")]
[Category("UI")]
internal class VividPanelRenderer : Component, CameraComponent.ISceneCameraSetup
{
public void SetupCamera( CameraComponent camera, SceneCamera sceneCamera )
{
sceneCamera.OnRenderOverlay = () =>
{
if ( !Game.IsPlaying )
return;
var panels = Game.ActiveScene.GetAllComponents<VividPanel>().ToList();
panels.Sort( ( a, b ) =>
{
float dist0 = a.Source.Panel.Style.ZIndex.GetValueOrDefault();
float dist1 = b.Source.Panel.Style.ZIndex.GetValueOrDefault();
if ( dist0.AlmostEqual( dist1, 0.1f ) )
return 0;
if ( dist0 < dist1 )
return 1;
return -1;
} );
foreach ( var panel in panels )
{
if ( panel.RenderDistance != 0f && Vector3.DistanceBetween( Scene.Camera.WorldPosition, panel.WorldPosition ) > panel.RenderDistance )
{
continue;
}
if ( !panel.RenderBackFace )
{
Vector3 objectForward = panel.WorldRotation.Forward;
Vector3 toCamera = (Scene.Camera.WorldPosition - panel.WorldPosition).Normal;
float dot = Vector3.Dot( objectForward, toCamera );
if ( dot <= 0 )
continue;
}
Graphics.Attributes.SetCombo( "D_WORLDPANEL", 1 );
Matrix value = Matrix.CreateRotation( Rotation.From( 0f, 90f, 90f ) );
value *= Matrix.CreateScale( Sandbox.UI.WorldPanel.ScreenToWorldScale * panel.WorldScale * panel.WorldRenderScale );
value *= Matrix.CreateRotation( panel.WorldRotation );
value *= Matrix.CreateTranslation( panel.WorldPosition );
var scale = panel.WorldRenderScale;
Graphics.Attributes.Set( "WorldMat", in value );
Rect panelBounds = panel.CalculateRect();
panelBounds.Left /= scale;
panelBounds.Right /= scale;
panelBounds.Top /= scale;
panelBounds.Bottom /= scale;
panel.RootPanel.PanelBounds = panelBounds;
panel.RootPanel?.RenderManual();
}
};
}
}