mirror of
https://github.com/Facepunch/sbox-public.git
synced 2026-01-20 20:31:20 -05:00
This commit imports the C# engine code and game files, excluding C++ source code. [Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
103 lines
2.4 KiB
C#
103 lines
2.4 KiB
C#
using System.Linq;
|
|
using System.Runtime.CompilerServices;
|
|
using Editor;
|
|
using Facepunch.ActionGraphs.Nodes;
|
|
|
|
namespace Sandbox.ActionGraphs;
|
|
|
|
#nullable enable
|
|
|
|
public static class GameObjectThumbnail
|
|
{
|
|
public const int Size = 128;
|
|
|
|
private static ConditionalWeakTable<GameObject, Pixmap> _cache = new();
|
|
|
|
/// <summary>
|
|
/// If this game object is a prefab root, return the prefab asset.
|
|
/// </summary>
|
|
private static Asset? GetPrefabAsset( GameObject go )
|
|
{
|
|
if ( go.Scene is not PrefabScene { Source: { } source } || go.Scene != go )
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return AssetSystem.FindByPath( source.ResourcePath );
|
|
}
|
|
|
|
public static Pixmap GetGameObjectThumb( this GameObject go )
|
|
{
|
|
if ( GetPrefabAsset( go ) is { } prefabAsset )
|
|
{
|
|
return prefabAsset.GetAssetThumb();
|
|
}
|
|
|
|
if ( _cache.TryGetValue( go, out var cached ) )
|
|
{
|
|
return cached;
|
|
}
|
|
|
|
using var sceneScope = go.Scene.Push();
|
|
using var camera = new SceneCamera( "Thumbnail Cam" );
|
|
|
|
var bounds = go.GetBounds();
|
|
|
|
var center = bounds.Center;
|
|
var distance = Math.Max( 16f, (bounds.Maxs - bounds.Mins).Length * 0.5f ) * 4f;
|
|
var baseYaw = go.WorldRotation.Yaw();
|
|
var cameraRotation = Rotation.From( 30f, baseYaw + 60f, 0f );
|
|
var sunRotation = Rotation.From( 80f, baseYaw + 30f, 0f );
|
|
var lightRotation = Rotation.From( 60f, baseYaw + 120f, 0f );
|
|
|
|
var thumb = new Pixmap( Size, Size );
|
|
|
|
SceneDirectionalLight? sun = null;
|
|
SceneLight? light = null;
|
|
|
|
if ( !go.Scene.GetAllComponents<Light>().Any() )
|
|
{
|
|
sun = new SceneDirectionalLight( go.Scene.SceneWorld, sunRotation, Color.White * 2.5f + Color.Cyan * 0.05f )
|
|
{
|
|
ShadowsEnabled = true,
|
|
ShadowTextureResolution = 1024
|
|
};
|
|
|
|
light = new SceneLight( go.Scene.SceneWorld, center - lightRotation.Forward * distance, distance * 1.5f,
|
|
new Color( 1.0f, 0.9f, 0.9f ) * 10.0f );
|
|
}
|
|
|
|
try
|
|
{
|
|
camera.World = go.Scene.SceneWorld;
|
|
camera.Position = center - cameraRotation.Forward * distance;
|
|
camera.Rotation = cameraRotation;
|
|
camera.FieldOfView = 30f;
|
|
camera.BackgroundColor = Color.Transparent;
|
|
|
|
camera.RenderToPixmap( thumb );
|
|
|
|
_cache.TryAdd( go, thumb );
|
|
|
|
return thumb;
|
|
}
|
|
finally
|
|
{
|
|
sun?.Delete();
|
|
light?.Delete();
|
|
}
|
|
}
|
|
|
|
[Event( "scene.saved" )]
|
|
static void OnSceneSaved( Scene scene )
|
|
{
|
|
foreach ( var (key, value) in _cache.ToArray() )
|
|
{
|
|
if ( key.Scene == scene )
|
|
{
|
|
_cache.Remove( key );
|
|
}
|
|
}
|
|
}
|
|
}
|