Editor/AssetGenerator.cs
using System;
using Sandbox;
using Editor;
public class AssetSprayerSettings
{
public Model AssetModel { get; set; }
public float Width = 1024;
public float Height = 1024;
public float Spacing = 32;
}
[EditorTool]
[Title("Asset Sprayer")]
[Icon("shower")]
public class AssetSprayerTool : EditorTool
{
AssetSprayerSettings Settings { get; set; } = new AssetSprayerSettings();
private int K = 30;
public AssetSprayerTool()
{
// create a widget window. This is a window that
// can be dragged around in the scene view
var window = new WidgetWindow( SceneOverlay );
window.WindowTitle = "Asset Generator";
window.Layout = Layout.Column();
window.Layout.Margin = 16;
window.FixedWidth = 480f;
var controlSheet = new ControlSheet();
controlSheet.AddObject( Settings.GetSerialized() );
controlSheet.Margin = 8f;
window.Layout.Add( controlSheet );
// Create a button for us to press
var button = new Button( "Generate Random" );
button.MaximumWidth = 128f;
button.Pressed = GenerateSamples;
var row = window.Layout.AddRow( 1 );
row.AddStretchCell();
row.AddStretchCell();
row.AddStretchCell();
row.AddStretchCell();
row.AddStretchCell();
row.AddStretchCell();
row.AddStretchCell();
row.AddStretchCell();
row.AddStretchCell();
row.AddStretchCell();
row.AddStretchCell();
row.AddStretchCell();
row.Add( button );
row.AddStretchCell();
// Add the button to the window's layout
//window.Layout.Add( button );
AddOverlay( window, TextFlag.RightTop, 10 );
}
public override void OnUpdate()
{
var tr = Scene.Trace.Ray( Gizmo.CurrentRay, 5000 )
.UseRenderMeshes( true )
.UsePhysicsWorld( false )
.WithoutTags( "sprinkled" )
.Run();
if ( tr.Hit )
{
using ( Gizmo.Scope( "cursor" ) )
{
Gizmo.Transform = new Transform( tr.HitPosition, Rotation.LookAt( tr.Normal ) );
Gizmo.Draw.LineCircle( 0, 86 );
}
}
}
private void GenerateSamples()
{
var size = Settings.AssetModel.Bounds.Size;
Vector2 rect = new Vector2( size.x, size.y );
var radius = (float) Math.Sqrt( (rect.x * rect.x) + (rect.y * rect.y) ) / 2;
var poisson = new PoissonDiscSamples( Settings.Width, Settings.Height, radius+Settings.Spacing, K );
var points = poisson.GetPoints();
var root = SceneEditorSession.Active.Scene.CreateObject();
root.Name = "Generated Assets";
foreach ( var point in points )
{
var gameObject = SceneEditorSession.Active.Scene.CreateObject();
gameObject.Parent = root;
gameObject.WorldPosition = new Vector3( point.x - (Settings.Width/2), point.y-(Settings.Height/2), 0 );
var model = gameObject.Components.GetOrCreate<ModelRenderer>().Model = Settings.AssetModel;
}
}
}