using Editor; using Editor.Assets; using Editor.Inspectors; using Sandbox; using System; using System.Collections.Generic; using System.Threading.Tasks; namespace VeloX; [AssetPreview( "tire" )] class TirePresetPreview : AssetPreview { private Texture texture; public override bool IsAnimatedPreview => false; [Range( 0.01f, 1 )] private float Zoom { get; set; } = 1; private TirePreset Tire; public AssetPreviewWidget Widget { get; private set; } public override Widget CreateWidget( Widget parent ) { Widget = parent as AssetPreviewWidget; return null; } public override Widget CreateToolbar() { var info = new IconButton( "settings" ); info.Layout = Layout.Row(); info.MinimumSize = 16; info.MouseLeftPress = () => OpenSettings( info ); return info; } public void OpenSettings( Widget parent ) { var popup = new PopupWidget( parent ) { IsPopup = true, Layout = Layout.Column() }; popup.Layout.Margin = 16; var ps = new ControlSheet(); ps.AddProperty( this, x => x.Zoom ); popup.Layout.Add( ps ); popup.MaximumWidth = 300; popup.Show(); popup.Position = parent.ScreenRect.TopRight - popup.Size; popup.ConstrainToScreen(); } public override async Task InitializeAsset() { await Task.Yield(); using ( Scene.Push() ) { PrimaryObject = new() { WorldTransform = Transform.Zero }; var plane = PrimaryObject.AddComponent(); plane.Model = Model.Plane; plane.LocalScale = new Vector3( 1, 1, 1 ); plane.MaterialOverride = Material.Load( "materials/dev/reflectivity_30.vmat" ); plane.Tint = new Color( 0.02f, 0.04f, 0.03f ); var bounds = PrimaryObject.GetBounds(); SceneCenter = bounds.Center; SceneSize = bounds.Size; } return; } public override void UpdateScene( float cycle, float timeStep ) { if ( !Widget.IsValid() ) return; Camera.WorldPosition = Vector3.Up * 300; Camera.Orthographic = true; Camera.WorldRotation = new Angles( 90, 0, 0 ); var bitmap = new Bitmap( 512, 512 ); Draw( bitmap ); texture.Clear( Color.Black ); //texture.Update( bitmap ); DebugOverlaySystem.Current.Texture( texture, new Rect( 0, Widget.Size ) ); FrameScene(); } private readonly List pointCache = []; public TirePresetPreview( Asset asset ) : base( asset ) { texture = Texture.CreateRenderTarget().WithDynamicUsage().WithScreenFormat().WithSize( 512, 512 ).Create(); Tire = Asset.LoadResource(); } private void DrawPacejka( Bitmap bitmap ) { var tire = Tire.Pacejka; var width = bitmap.Width; var height = bitmap.Height; { // draw lateral line pointCache.Clear(); bitmap.SetPen( Color.Red, 1 ); for ( float x = 0; x <= 1; x += 0.01f ) { float val = tire.PacejkaFy( x ) * Zoom; pointCache.Add( new( width * x, height - height * val ) ); } bitmap.DrawLines( pointCache.ToArray() ); } { // draw longitudinal line pointCache.Clear(); bitmap.SetPen( Color.Green, 1 ); for ( float x = 0; x <= 1; x += 0.01f ) { float val = tire.PacejkaFx( x ) * Zoom; pointCache.Add( new( width * x, height - height * val ) ); } bitmap.DrawLines( pointCache.ToArray() ); } pointCache.Clear(); } private void Draw( Bitmap bitmap ) { bitmap.Clear( Color.Black ); bitmap.SetAntialias( true ); DrawPacejka( bitmap ); } }