Move to its own project

This commit is contained in:
ashlen
2025-07-25 18:56:55 +02:00
parent 390416df06
commit 86bcb079b0
3 changed files with 75 additions and 16 deletions

View File

@@ -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();

View File

@@ -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);
}
} }
} }

View 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>