Move to its own project
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
using NLog;
|
using NLog;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using SpineViewer.Views;
|
using SpineViewer.Views;
|
||||||
using System.Collections.Frozen;
|
using System.Collections.Frozen;
|
||||||
using System.Configuration;
|
using System.Configuration;
|
||||||
@@ -8,7 +7,6 @@ using System.Diagnostics;
|
|||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using SpineViewerCLI;
|
|
||||||
|
|
||||||
namespace SpineViewer
|
namespace SpineViewer
|
||||||
{
|
{
|
||||||
@@ -17,9 +15,6 @@ namespace SpineViewer
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class App : Application
|
public partial class App : Application
|
||||||
{
|
{
|
||||||
[DllImport("kernel32.dll")]
|
|
||||||
private static extern bool AttachConsole(int dwProcessId);
|
|
||||||
|
|
||||||
public static string Version => Assembly.GetExecutingAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion;
|
public static string Version => Assembly.GetExecutingAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion;
|
||||||
|
|
||||||
private static readonly Logger _logger;
|
private static readonly Logger _logger;
|
||||||
@@ -66,11 +61,6 @@ namespace SpineViewer
|
|||||||
protected override void OnStartup(StartupEventArgs e)
|
protected override void OnStartup(StartupEventArgs e)
|
||||||
{
|
{
|
||||||
base.OnStartup(e);
|
base.OnStartup(e);
|
||||||
if (e.Args.Length > 0)
|
|
||||||
{
|
|
||||||
AttachConsole(-1);
|
|
||||||
CLI.CliMain(e.Args);
|
|
||||||
}
|
|
||||||
|
|
||||||
var dict = new ResourceDictionary();
|
var dict = new ResourceDictionary();
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
|
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using SFML.Graphics;
|
using SFML.Graphics;
|
||||||
|
using SFML.System;
|
||||||
using Spine;
|
using Spine;
|
||||||
using Spine.Exporters;
|
using Spine.Exporters;
|
||||||
using SpineViewer.Extensions;
|
|
||||||
|
|
||||||
namespace SpineViewerCLI
|
namespace SpineViewerCLI
|
||||||
{
|
{
|
||||||
@@ -32,7 +31,7 @@ options:
|
|||||||
--quiet Removes console progress log, default false
|
--quiet Removes console progress log, default false
|
||||||
";
|
";
|
||||||
|
|
||||||
public static void CliMain(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
|
|
||||||
string? skelPath = null;
|
string? skelPath = null;
|
||||||
@@ -155,9 +154,7 @@ options:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var rect = sp.GetAnimationBounds();
|
var bounds = GetFloatRectCanvasBounds(GetSpineObjectAnimationBounds(sp, fps), new(width ?? 512, height ?? 512));
|
||||||
var bounds = new FloatRect((float)rect.X, (float)rect.Y, (float)rect.Width, (float)rect.Height).GetCanvasBounds(new(width ?? 512, height ?? 512));
|
|
||||||
|
|
||||||
exporter = new FFmpegVideoExporter(width ?? (uint)Math.Ceiling(bounds.Width), height ?? (uint)Math.Ceiling(bounds.Height))
|
exporter = new FFmpegVideoExporter(width ?? (uint)Math.Ceiling(bounds.Width), height ?? (uint)Math.Ceiling(bounds.Height))
|
||||||
{
|
{
|
||||||
Center = bounds.Position + bounds.Size / 2,
|
Center = bounds.Position + bounds.Size / 2,
|
||||||
@@ -183,5 +180,62 @@ options:
|
|||||||
|
|
||||||
Environment.Exit(0);
|
Environment.Exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static SpineObject CopySpineObject(SpineObject sp)
|
||||||
|
{
|
||||||
|
var spineObject = new SpineObject(sp, true);
|
||||||
|
foreach (var tr in sp.AnimationState.IterTracks().Where(t => t is not null))
|
||||||
|
{
|
||||||
|
var t = spineObject.AnimationState.SetAnimation(tr!.TrackIndex, tr.Animation, tr.Loop);
|
||||||
|
}
|
||||||
|
spineObject.Update(0);
|
||||||
|
return spineObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FloatRect GetSpineObjectBounds(SpineObject sp)
|
||||||
|
{
|
||||||
|
sp.Skeleton.GetBounds(out var x, out var y, out var w, out var h);
|
||||||
|
return new(x, y, Math.Max(w, 1e-6f), Math.Max(h, 1e-6f));
|
||||||
|
}
|
||||||
|
static FloatRect FloatRectUnion(FloatRect a, FloatRect b)
|
||||||
|
{
|
||||||
|
float left = Math.Min(a.Left, b.Left);
|
||||||
|
float top = Math.Min(a.Top, b.Top);
|
||||||
|
float right = Math.Max(a.Left + a.Width, b.Left + b.Width);
|
||||||
|
float bottom = Math.Max(a.Top + a.Height, b.Top + b.Height);
|
||||||
|
return new FloatRect(left, top, right - left, bottom - top);
|
||||||
|
}
|
||||||
|
static FloatRect GetSpineObjectAnimationBounds(SpineObject sp, float fps = 10)
|
||||||
|
{
|
||||||
|
sp = CopySpineObject(sp);
|
||||||
|
var bounds = GetSpineObjectBounds(sp);
|
||||||
|
var maxDuration = sp.AnimationState.IterTracks().Select(t => t?.Animation.Duration ?? 0).DefaultIfEmpty(0).Max();
|
||||||
|
sp.Update(0);
|
||||||
|
for (float tick = 0, delta = 1 / fps; tick < maxDuration; tick += delta)
|
||||||
|
{
|
||||||
|
bounds = FloatRectUnion(bounds, GetSpineObjectBounds(sp));
|
||||||
|
sp.Update(delta);
|
||||||
|
}
|
||||||
|
return bounds;
|
||||||
|
}
|
||||||
|
static FloatRect GetFloatRectCanvasBounds(FloatRect rect, Vector2u resolution)
|
||||||
|
{
|
||||||
|
float sizeW = rect.Width;
|
||||||
|
float sizeH = rect.Height;
|
||||||
|
float innerW = resolution.X;
|
||||||
|
float innerH = resolution.Y;
|
||||||
|
var scale = Math.Max(Math.Abs(sizeW / innerW), Math.Abs(sizeH / innerH));
|
||||||
|
var scaleW = scale * Math.Sign(sizeW);
|
||||||
|
var scaleH = scale * Math.Sign(sizeH);
|
||||||
|
|
||||||
|
innerW *= scaleW;
|
||||||
|
innerH *= scaleH;
|
||||||
|
|
||||||
|
var x = rect.Left - (innerW - sizeW) / 2;
|
||||||
|
var y = rect.Top - (innerH - sizeH) / 2;
|
||||||
|
var w = resolution.X * scaleW;
|
||||||
|
var h = resolution.Y * scaleH;
|
||||||
|
return new(x, y, w, h);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
15
SpineViewerCLI/SpineViewerCLI.csproj
Normal file
15
SpineViewerCLI/SpineViewerCLI.csproj
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net8.0-windows7.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\SFMLRenderer\SFMLRenderer.csproj" />
|
||||||
|
<ProjectReference Include="..\Spine\Spine.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
Reference in New Issue
Block a user