Compare commits
44 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2fecf4223a | ||
|
|
2953ec44fb | ||
|
|
77399b4524 | ||
|
|
c0e2bb81e5 | ||
|
|
55ebcc1857 | ||
|
|
292ede8461 | ||
|
|
63ed8d7ca4 | ||
|
|
ce7c6f3802 | ||
|
|
0b478cab18 | ||
|
|
b7f5f24e6f | ||
|
|
150331d2e4 | ||
|
|
4d1aec9ed8 | ||
|
|
0cb325820b | ||
|
|
2a862b28be | ||
|
|
c2935f49e9 | ||
|
|
22043f8f38 | ||
|
|
3020a818f0 | ||
|
|
30177e8d7f | ||
|
|
3ad49838be | ||
|
|
3e480abd44 | ||
|
|
49f6b28aef | ||
|
|
b81d13b582 | ||
|
|
04eb3cb640 | ||
|
|
0ac75a088a | ||
|
|
cd652a72a1 | ||
|
|
828ff30dbf | ||
|
|
f452fe8a71 | ||
|
|
15e29a3b8a | ||
|
|
5c6e98f5e1 | ||
|
|
ef06073119 | ||
|
|
bca8b0ad85 | ||
|
|
4983b1fa88 | ||
|
|
f6b6d9f0e7 | ||
|
|
12a168df92 | ||
|
|
e06d2012d6 | ||
|
|
faed2448eb | ||
|
|
a80aed54a0 | ||
|
|
3f9c4dfe99 | ||
|
|
3c91f335fc | ||
|
|
1ea4586360 | ||
|
|
45e08b5b60 | ||
|
|
43ce5a5288 | ||
|
|
887315ceda | ||
|
|
30b5c8dd74 |
70
.github/workflows/dotnet-desktop.yml
vendored
70
.github/workflows/dotnet-desktop.yml
vendored
@@ -1,46 +1,80 @@
|
||||
name: Build & Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*.*.*'
|
||||
pull_request:
|
||||
branches:
|
||||
- release/wf
|
||||
types:
|
||||
- closed
|
||||
|
||||
jobs:
|
||||
build-release:
|
||||
if: ${{ github.event.pull_request.merged == true }}
|
||||
runs-on: windows-latest
|
||||
env:
|
||||
PROJECT_NAME: SpineViewer
|
||||
VERSION: ${{ github.ref_name }}
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
with:
|
||||
fetch-tags: true
|
||||
|
||||
- name: Setup .NET SDK
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: '8.0.x'
|
||||
dotnet-version: "8.0.x"
|
||||
|
||||
- name: Extract version from csproj
|
||||
shell: pwsh
|
||||
run: |
|
||||
[xml]$proj = Get-Content "$env:PROJECT_NAME\$env:PROJECT_NAME.csproj"
|
||||
$VERSION_NUM = $proj.Project.PropertyGroup.Version
|
||||
$VERSION_TAG = "v$VERSION_NUM"
|
||||
"VERSION=$VERSION_TAG" >> $env:GITHUB_ENV
|
||||
|
||||
- name: Check Version Tag
|
||||
shell: pwsh
|
||||
run: |
|
||||
if (-not $env:VERSION) {
|
||||
Write-Error "Version tag not found in csproj file."
|
||||
exit 1
|
||||
}
|
||||
Write-Host "Version tag found: $env:VERSION"
|
||||
|
||||
- name: Tag merge commit
|
||||
shell: pwsh
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git tag $env:VERSION
|
||||
git push --tags
|
||||
|
||||
- name: Publish FrameworkDependent version
|
||||
shell: pwsh
|
||||
run: |
|
||||
dotnet publish ${{ env.PROJECT_NAME }}/${{ env.PROJECT_NAME }}.csproj -c Release -r win-x64 --sc false -p:PublishSingleFile=true -o publish/${{ env.PROJECT_NAME }}-${{ env.VERSION }}
|
||||
|
||||
dotnet publish "$env:PROJECT_NAME\$env:PROJECT_NAME.csproj" -c Release -r win-x64 --sc false -o "publish\$env:PROJECT_NAME-$env:VERSION"
|
||||
|
||||
- name: Publish SelfContained version
|
||||
shell: pwsh
|
||||
run: |
|
||||
dotnet publish ${{ env.PROJECT_NAME }}/${{ env.PROJECT_NAME }}.csproj -c Release -r win-x64 --sc true -p:PublishSingleFile=true -o publish/${{ env.PROJECT_NAME }}-${{ env.VERSION }}-SelfContained
|
||||
|
||||
dotnet publish "$env:PROJECT_NAME\$env:PROJECT_NAME.csproj" -c Release -r win-x64 --sc true -o "publish\$env:PROJECT_NAME-$env:VERSION-SelfContained"
|
||||
|
||||
- name: Create release directory
|
||||
run: mkdir release
|
||||
|
||||
shell: pwsh
|
||||
run: |
|
||||
New-Item -ItemType Directory -Path release -Force | Out-Null
|
||||
|
||||
- name: Compress FrameworkDependent version
|
||||
shell: pwsh
|
||||
run: |
|
||||
Compress-Archive -Path "publish/${env:PROJECT_NAME}-${env:VERSION}" -DestinationPath "release/${env:PROJECT_NAME}-${env:VERSION}.zip" -Force
|
||||
|
||||
Compress-Archive -Path "publish\$env:PROJECT_NAME-$env:VERSION\*" -DestinationPath "release\$env:PROJECT_NAME-$env:VERSION.zip" -Force
|
||||
|
||||
- name: Compress SelfContained version
|
||||
shell: pwsh
|
||||
run: |
|
||||
Compress-Archive -Path "publish/${env:PROJECT_NAME}-${env:VERSION}-SelfContained" -DestinationPath "release/${env:PROJECT_NAME}-${env:VERSION}-SelfContained.zip" -Force
|
||||
|
||||
Compress-Archive -Path "publish\$env:PROJECT_NAME-$env:VERSION-SelfContained\*" -DestinationPath "release\$env:PROJECT_NAME-$env:VERSION-SelfContained.zip" -Force
|
||||
|
||||
- name: Create GitHub Release
|
||||
id: create_release
|
||||
uses: actions/create-release@v1
|
||||
@@ -51,7 +85,7 @@ jobs:
|
||||
release_name: Release ${{ env.VERSION }}
|
||||
draft: false
|
||||
prerelease: false
|
||||
|
||||
|
||||
- name: Upload FrameworkDependent zip
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
@@ -61,7 +95,7 @@ jobs:
|
||||
asset_path: release/${{ env.PROJECT_NAME }}-${{ env.VERSION }}.zip
|
||||
asset_name: ${{ env.PROJECT_NAME }}-${{ env.VERSION }}.zip
|
||||
asset_content_type: application/zip
|
||||
|
||||
|
||||
- name: Upload SelfContained zip
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
|
||||
32
CHANGELOG.md
32
CHANGELOG.md
@@ -1,5 +1,37 @@
|
||||
# CHANGELOG
|
||||
|
||||
## v0.12.17
|
||||
|
||||
- 动画边界检测的帧率提高到100帧每秒
|
||||
|
||||
## v0.12.16
|
||||
|
||||
- 导出多个时允许自动时长
|
||||
|
||||
## v0.12.15
|
||||
|
||||
- 修复附件类型枚举量字符串大小写问题
|
||||
|
||||
## v0.12.14
|
||||
|
||||
- 修复 v38 文件读取的小 bug
|
||||
|
||||
## v0.12.13
|
||||
|
||||
- 导出文件名增加额外的随机字符串
|
||||
|
||||
## v0.12.12
|
||||
|
||||
- 修复 2.1 版本遗漏的 SkinnedMeshAttachment 附件渲染
|
||||
|
||||
## v0.12.11
|
||||
|
||||
- 修复可能的闪退错误
|
||||
|
||||
## v0.12.10
|
||||
|
||||
- 增加纹理全局加载选项
|
||||
|
||||
## v0.12.9
|
||||
|
||||
- 修复由于未调用 UpdateCache 导致的约束 bug
|
||||
|
||||
156
SpineViewer/Forms/SpineViewerForm.Designer.cs
generated
156
SpineViewer/Forms/SpineViewerForm.Designer.cs
generated
@@ -64,6 +64,10 @@
|
||||
toolStripMenuItem_ExportCustom = new ToolStripMenuItem();
|
||||
toolStripSeparator2 = new ToolStripSeparator();
|
||||
toolStripMenuItem_Exit = new ToolStripMenuItem();
|
||||
toolStripMenuItem_Texture = new ToolStripMenuItem();
|
||||
toolStripMenuItem_ForceSmooth = new ToolStripMenuItem();
|
||||
toolStripMenuItem_ForceRepeated = new ToolStripMenuItem();
|
||||
toolStripMenuItem_ForceMipmap = new ToolStripMenuItem();
|
||||
toolStripMenuItem_Tool = new ToolStripMenuItem();
|
||||
toolStripMenuItem_ConvertFileFormat = new ToolStripMenuItem();
|
||||
toolStripMenuItem_Download = new ToolStripMenuItem();
|
||||
@@ -106,98 +110,80 @@
|
||||
//
|
||||
// splitContainer_MainForm
|
||||
//
|
||||
resources.ApplyResources(splitContainer_MainForm, "splitContainer_MainForm");
|
||||
splitContainer_MainForm.Cursor = Cursors.SizeNS;
|
||||
resources.ApplyResources(splitContainer_MainForm, "splitContainer_MainForm");
|
||||
splitContainer_MainForm.FixedPanel = FixedPanel.Panel2;
|
||||
splitContainer_MainForm.Name = "splitContainer_MainForm";
|
||||
//
|
||||
// splitContainer_MainForm.Panel1
|
||||
//
|
||||
resources.ApplyResources(splitContainer_MainForm.Panel1, "splitContainer_MainForm.Panel1");
|
||||
splitContainer_MainForm.Panel1.Controls.Add(splitContainer_Functional);
|
||||
splitContainer_MainForm.Panel1.Cursor = Cursors.Default;
|
||||
toolTip.SetToolTip(splitContainer_MainForm.Panel1, resources.GetString("splitContainer_MainForm.Panel1.ToolTip"));
|
||||
//
|
||||
// splitContainer_MainForm.Panel2
|
||||
//
|
||||
resources.ApplyResources(splitContainer_MainForm.Panel2, "splitContainer_MainForm.Panel2");
|
||||
splitContainer_MainForm.Panel2.Controls.Add(rtbLog);
|
||||
splitContainer_MainForm.Panel2.Cursor = Cursors.Default;
|
||||
toolTip.SetToolTip(splitContainer_MainForm.Panel2, resources.GetString("splitContainer_MainForm.Panel2.ToolTip"));
|
||||
splitContainer_MainForm.TabStop = false;
|
||||
toolTip.SetToolTip(splitContainer_MainForm, resources.GetString("splitContainer_MainForm.ToolTip"));
|
||||
splitContainer_MainForm.SplitterMoved += splitContainer_SplitterMoved;
|
||||
splitContainer_MainForm.MouseUp += splitContainer_MouseUp;
|
||||
//
|
||||
// splitContainer_Functional
|
||||
//
|
||||
resources.ApplyResources(splitContainer_Functional, "splitContainer_Functional");
|
||||
splitContainer_Functional.Cursor = Cursors.SizeWE;
|
||||
resources.ApplyResources(splitContainer_Functional, "splitContainer_Functional");
|
||||
splitContainer_Functional.FixedPanel = FixedPanel.Panel1;
|
||||
splitContainer_Functional.Name = "splitContainer_Functional";
|
||||
//
|
||||
// splitContainer_Functional.Panel1
|
||||
//
|
||||
resources.ApplyResources(splitContainer_Functional.Panel1, "splitContainer_Functional.Panel1");
|
||||
splitContainer_Functional.Panel1.Controls.Add(splitContainer_Information);
|
||||
splitContainer_Functional.Panel1.Cursor = Cursors.Default;
|
||||
toolTip.SetToolTip(splitContainer_Functional.Panel1, resources.GetString("splitContainer_Functional.Panel1.ToolTip"));
|
||||
//
|
||||
// splitContainer_Functional.Panel2
|
||||
//
|
||||
resources.ApplyResources(splitContainer_Functional.Panel2, "splitContainer_Functional.Panel2");
|
||||
splitContainer_Functional.Panel2.Controls.Add(groupBox_Preview);
|
||||
splitContainer_Functional.Panel2.Cursor = Cursors.Default;
|
||||
toolTip.SetToolTip(splitContainer_Functional.Panel2, resources.GetString("splitContainer_Functional.Panel2.ToolTip"));
|
||||
splitContainer_Functional.TabStop = false;
|
||||
toolTip.SetToolTip(splitContainer_Functional, resources.GetString("splitContainer_Functional.ToolTip"));
|
||||
splitContainer_Functional.SplitterMoved += splitContainer_SplitterMoved;
|
||||
splitContainer_Functional.MouseUp += splitContainer_MouseUp;
|
||||
//
|
||||
// splitContainer_Information
|
||||
//
|
||||
resources.ApplyResources(splitContainer_Information, "splitContainer_Information");
|
||||
splitContainer_Information.Cursor = Cursors.SizeWE;
|
||||
resources.ApplyResources(splitContainer_Information, "splitContainer_Information");
|
||||
splitContainer_Information.Name = "splitContainer_Information";
|
||||
//
|
||||
// splitContainer_Information.Panel1
|
||||
//
|
||||
resources.ApplyResources(splitContainer_Information.Panel1, "splitContainer_Information.Panel1");
|
||||
splitContainer_Information.Panel1.Controls.Add(groupBox_SkelList);
|
||||
splitContainer_Information.Panel1.Cursor = Cursors.Default;
|
||||
toolTip.SetToolTip(splitContainer_Information.Panel1, resources.GetString("splitContainer_Information.Panel1.ToolTip"));
|
||||
//
|
||||
// splitContainer_Information.Panel2
|
||||
//
|
||||
resources.ApplyResources(splitContainer_Information.Panel2, "splitContainer_Information.Panel2");
|
||||
splitContainer_Information.Panel2.Controls.Add(splitContainer_Config);
|
||||
splitContainer_Information.Panel2.Cursor = Cursors.Default;
|
||||
toolTip.SetToolTip(splitContainer_Information.Panel2, resources.GetString("splitContainer_Information.Panel2.ToolTip"));
|
||||
splitContainer_Information.TabStop = false;
|
||||
toolTip.SetToolTip(splitContainer_Information, resources.GetString("splitContainer_Information.ToolTip"));
|
||||
splitContainer_Information.SplitterMoved += splitContainer_SplitterMoved;
|
||||
splitContainer_Information.MouseUp += splitContainer_MouseUp;
|
||||
//
|
||||
// groupBox_SkelList
|
||||
//
|
||||
resources.ApplyResources(groupBox_SkelList, "groupBox_SkelList");
|
||||
groupBox_SkelList.Controls.Add(spineListView);
|
||||
resources.ApplyResources(groupBox_SkelList, "groupBox_SkelList");
|
||||
groupBox_SkelList.Name = "groupBox_SkelList";
|
||||
groupBox_SkelList.TabStop = false;
|
||||
toolTip.SetToolTip(groupBox_SkelList, resources.GetString("groupBox_SkelList.ToolTip"));
|
||||
//
|
||||
// spineListView
|
||||
//
|
||||
resources.ApplyResources(spineListView, "spineListView");
|
||||
spineListView.Name = "spineListView";
|
||||
spineListView.SpinePropertyGrid = spineViewPropertyGrid;
|
||||
toolTip.SetToolTip(spineListView, resources.GetString("spineListView.ToolTip"));
|
||||
//
|
||||
// spineViewPropertyGrid
|
||||
//
|
||||
resources.ApplyResources(spineViewPropertyGrid, "spineViewPropertyGrid");
|
||||
spineViewPropertyGrid.Name = "spineViewPropertyGrid";
|
||||
toolTip.SetToolTip(spineViewPropertyGrid, resources.GetString("spineViewPropertyGrid.ToolTip"));
|
||||
//
|
||||
// splitContainer_Config
|
||||
//
|
||||
@@ -206,47 +192,38 @@
|
||||
//
|
||||
// splitContainer_Config.Panel1
|
||||
//
|
||||
resources.ApplyResources(splitContainer_Config.Panel1, "splitContainer_Config.Panel1");
|
||||
splitContainer_Config.Panel1.Controls.Add(groupBox_PreviewConfig);
|
||||
toolTip.SetToolTip(splitContainer_Config.Panel1, resources.GetString("splitContainer_Config.Panel1.ToolTip"));
|
||||
//
|
||||
// splitContainer_Config.Panel2
|
||||
//
|
||||
resources.ApplyResources(splitContainer_Config.Panel2, "splitContainer_Config.Panel2");
|
||||
splitContainer_Config.Panel2.Controls.Add(groupBox_SkelConfig);
|
||||
toolTip.SetToolTip(splitContainer_Config.Panel2, resources.GetString("splitContainer_Config.Panel2.ToolTip"));
|
||||
toolTip.SetToolTip(splitContainer_Config, resources.GetString("splitContainer_Config.ToolTip"));
|
||||
//
|
||||
// groupBox_PreviewConfig
|
||||
//
|
||||
resources.ApplyResources(groupBox_PreviewConfig, "groupBox_PreviewConfig");
|
||||
groupBox_PreviewConfig.Controls.Add(propertyGrid_Previewer);
|
||||
resources.ApplyResources(groupBox_PreviewConfig, "groupBox_PreviewConfig");
|
||||
groupBox_PreviewConfig.Name = "groupBox_PreviewConfig";
|
||||
groupBox_PreviewConfig.TabStop = false;
|
||||
toolTip.SetToolTip(groupBox_PreviewConfig, resources.GetString("groupBox_PreviewConfig.ToolTip"));
|
||||
//
|
||||
// propertyGrid_Previewer
|
||||
//
|
||||
resources.ApplyResources(propertyGrid_Previewer, "propertyGrid_Previewer");
|
||||
propertyGrid_Previewer.Name = "propertyGrid_Previewer";
|
||||
propertyGrid_Previewer.ToolbarVisible = false;
|
||||
toolTip.SetToolTip(propertyGrid_Previewer, resources.GetString("propertyGrid_Previewer.ToolTip"));
|
||||
//
|
||||
// groupBox_SkelConfig
|
||||
//
|
||||
resources.ApplyResources(groupBox_SkelConfig, "groupBox_SkelConfig");
|
||||
groupBox_SkelConfig.Controls.Add(spineViewPropertyGrid);
|
||||
resources.ApplyResources(groupBox_SkelConfig, "groupBox_SkelConfig");
|
||||
groupBox_SkelConfig.Name = "groupBox_SkelConfig";
|
||||
groupBox_SkelConfig.TabStop = false;
|
||||
toolTip.SetToolTip(groupBox_SkelConfig, resources.GetString("groupBox_SkelConfig.ToolTip"));
|
||||
//
|
||||
// groupBox_Preview
|
||||
//
|
||||
resources.ApplyResources(groupBox_Preview, "groupBox_Preview");
|
||||
groupBox_Preview.Controls.Add(spinePreviewPanel);
|
||||
resources.ApplyResources(groupBox_Preview, "groupBox_Preview");
|
||||
groupBox_Preview.Name = "groupBox_Preview";
|
||||
groupBox_Preview.TabStop = false;
|
||||
toolTip.SetToolTip(groupBox_Preview, resources.GetString("groupBox_Preview.ToolTip"));
|
||||
//
|
||||
// spinePreviewPanel
|
||||
//
|
||||
@@ -254,230 +231,250 @@
|
||||
spinePreviewPanel.Name = "spinePreviewPanel";
|
||||
spinePreviewPanel.PropertyGrid = propertyGrid_Previewer;
|
||||
spinePreviewPanel.SpineListView = spineListView;
|
||||
toolTip.SetToolTip(spinePreviewPanel, resources.GetString("spinePreviewPanel.ToolTip"));
|
||||
//
|
||||
// rtbLog
|
||||
//
|
||||
resources.ApplyResources(rtbLog, "rtbLog");
|
||||
rtbLog.BackColor = SystemColors.Window;
|
||||
rtbLog.BorderStyle = BorderStyle.None;
|
||||
resources.ApplyResources(rtbLog, "rtbLog");
|
||||
rtbLog.Name = "rtbLog";
|
||||
rtbLog.ReadOnly = true;
|
||||
toolTip.SetToolTip(rtbLog, resources.GetString("rtbLog.ToolTip"));
|
||||
//
|
||||
// menuStrip
|
||||
//
|
||||
resources.ApplyResources(menuStrip, "menuStrip");
|
||||
menuStrip.BackColor = SystemColors.Control;
|
||||
menuStrip.ImageScalingSize = new Size(24, 24);
|
||||
menuStrip.Items.AddRange(new ToolStripItem[] { toolStripMenuItem_File, toolStripMenuItem_Tool, toolStripMenuItem_Download, toolStripMenuItem_Help, toolStripMenuItem_Experiment, ToolStripMenuItem_Language });
|
||||
menuStrip.Items.AddRange(new ToolStripItem[] { toolStripMenuItem_File, toolStripMenuItem_Texture, toolStripMenuItem_Tool, toolStripMenuItem_Download, toolStripMenuItem_Help, toolStripMenuItem_Experiment, ToolStripMenuItem_Language });
|
||||
resources.ApplyResources(menuStrip, "menuStrip");
|
||||
menuStrip.Name = "menuStrip";
|
||||
toolTip.SetToolTip(menuStrip, resources.GetString("menuStrip.ToolTip"));
|
||||
//
|
||||
// toolStripMenuItem_File
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_File, "toolStripMenuItem_File");
|
||||
toolStripMenuItem_File.DropDownItems.AddRange(new ToolStripItem[] { toolStripMenuItem_Open, toolStripMenuItem_BatchOpen, toolStripSeparator1, toolStripMenuItem_Export, toolStripSeparator2, toolStripMenuItem_Exit });
|
||||
toolStripMenuItem_File.Name = "toolStripMenuItem_File";
|
||||
resources.ApplyResources(toolStripMenuItem_File, "toolStripMenuItem_File");
|
||||
//
|
||||
// toolStripMenuItem_Open
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_Open, "toolStripMenuItem_Open");
|
||||
toolStripMenuItem_Open.Name = "toolStripMenuItem_Open";
|
||||
resources.ApplyResources(toolStripMenuItem_Open, "toolStripMenuItem_Open");
|
||||
toolStripMenuItem_Open.Click += toolStripMenuItem_Open_Click;
|
||||
//
|
||||
// toolStripMenuItem_BatchOpen
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_BatchOpen, "toolStripMenuItem_BatchOpen");
|
||||
toolStripMenuItem_BatchOpen.Name = "toolStripMenuItem_BatchOpen";
|
||||
resources.ApplyResources(toolStripMenuItem_BatchOpen, "toolStripMenuItem_BatchOpen");
|
||||
toolStripMenuItem_BatchOpen.Click += toolStripMenuItem_BatchOpen_Click;
|
||||
//
|
||||
// toolStripSeparator1
|
||||
//
|
||||
resources.ApplyResources(toolStripSeparator1, "toolStripSeparator1");
|
||||
toolStripSeparator1.Name = "toolStripSeparator1";
|
||||
resources.ApplyResources(toolStripSeparator1, "toolStripSeparator1");
|
||||
//
|
||||
// toolStripMenuItem_Export
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_Export, "toolStripMenuItem_Export");
|
||||
toolStripMenuItem_Export.DropDownItems.AddRange(new ToolStripItem[] { toolStripMenuItem_ExportFrame, toolStripMenuItem_ExportFrameSequence, toolStripSeparator4, toolStripMenuItem_ExportGif, toolStripMenuItem_ExportWebp, toolStripMenuItem_ExportAvif, toolStripSeparator5, toolStripMenuItem_ExportMp4, toolStripMenuItem_ExportWebm, toolStripMenuItem_ExportMkv, toolStripMenuItem_ExportMov, toolStripSeparator6, toolStripMenuItem_ExportCustom });
|
||||
toolStripMenuItem_Export.Name = "toolStripMenuItem_Export";
|
||||
resources.ApplyResources(toolStripMenuItem_Export, "toolStripMenuItem_Export");
|
||||
//
|
||||
// toolStripMenuItem_ExportFrame
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_ExportFrame, "toolStripMenuItem_ExportFrame");
|
||||
toolStripMenuItem_ExportFrame.Name = "toolStripMenuItem_ExportFrame";
|
||||
resources.ApplyResources(toolStripMenuItem_ExportFrame, "toolStripMenuItem_ExportFrame");
|
||||
toolStripMenuItem_ExportFrame.Click += toolStripMenuItem_ExportFrame_Click;
|
||||
//
|
||||
// toolStripMenuItem_ExportFrameSequence
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_ExportFrameSequence, "toolStripMenuItem_ExportFrameSequence");
|
||||
toolStripMenuItem_ExportFrameSequence.Name = "toolStripMenuItem_ExportFrameSequence";
|
||||
resources.ApplyResources(toolStripMenuItem_ExportFrameSequence, "toolStripMenuItem_ExportFrameSequence");
|
||||
toolStripMenuItem_ExportFrameSequence.Click += toolStripMenuItem_ExportFrameSequence_Click;
|
||||
//
|
||||
// toolStripSeparator4
|
||||
//
|
||||
resources.ApplyResources(toolStripSeparator4, "toolStripSeparator4");
|
||||
toolStripSeparator4.Name = "toolStripSeparator4";
|
||||
resources.ApplyResources(toolStripSeparator4, "toolStripSeparator4");
|
||||
//
|
||||
// toolStripMenuItem_ExportGif
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_ExportGif, "toolStripMenuItem_ExportGif");
|
||||
toolStripMenuItem_ExportGif.Name = "toolStripMenuItem_ExportGif";
|
||||
resources.ApplyResources(toolStripMenuItem_ExportGif, "toolStripMenuItem_ExportGif");
|
||||
toolStripMenuItem_ExportGif.Click += toolStripMenuItem_ExportGif_Click;
|
||||
//
|
||||
// toolStripMenuItem_ExportWebp
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_ExportWebp, "toolStripMenuItem_ExportWebp");
|
||||
toolStripMenuItem_ExportWebp.Name = "toolStripMenuItem_ExportWebp";
|
||||
resources.ApplyResources(toolStripMenuItem_ExportWebp, "toolStripMenuItem_ExportWebp");
|
||||
toolStripMenuItem_ExportWebp.Click += toolStripMenuItem_ExportWebp_Click;
|
||||
//
|
||||
// toolStripMenuItem_ExportAvif
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_ExportAvif, "toolStripMenuItem_ExportAvif");
|
||||
toolStripMenuItem_ExportAvif.Name = "toolStripMenuItem_ExportAvif";
|
||||
resources.ApplyResources(toolStripMenuItem_ExportAvif, "toolStripMenuItem_ExportAvif");
|
||||
toolStripMenuItem_ExportAvif.Click += toolStripMenuItem_ExportAvif_Click;
|
||||
//
|
||||
// toolStripSeparator5
|
||||
//
|
||||
resources.ApplyResources(toolStripSeparator5, "toolStripSeparator5");
|
||||
toolStripSeparator5.Name = "toolStripSeparator5";
|
||||
resources.ApplyResources(toolStripSeparator5, "toolStripSeparator5");
|
||||
//
|
||||
// toolStripMenuItem_ExportMp4
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_ExportMp4, "toolStripMenuItem_ExportMp4");
|
||||
toolStripMenuItem_ExportMp4.Name = "toolStripMenuItem_ExportMp4";
|
||||
resources.ApplyResources(toolStripMenuItem_ExportMp4, "toolStripMenuItem_ExportMp4");
|
||||
toolStripMenuItem_ExportMp4.Click += toolStripMenuItem_ExportMp4_Click;
|
||||
//
|
||||
// toolStripMenuItem_ExportWebm
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_ExportWebm, "toolStripMenuItem_ExportWebm");
|
||||
toolStripMenuItem_ExportWebm.Name = "toolStripMenuItem_ExportWebm";
|
||||
resources.ApplyResources(toolStripMenuItem_ExportWebm, "toolStripMenuItem_ExportWebm");
|
||||
toolStripMenuItem_ExportWebm.Click += toolStripMenuItem_ExportWebm_Click;
|
||||
//
|
||||
// toolStripMenuItem_ExportMkv
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_ExportMkv, "toolStripMenuItem_ExportMkv");
|
||||
toolStripMenuItem_ExportMkv.Name = "toolStripMenuItem_ExportMkv";
|
||||
resources.ApplyResources(toolStripMenuItem_ExportMkv, "toolStripMenuItem_ExportMkv");
|
||||
toolStripMenuItem_ExportMkv.Click += toolStripMenuItem_ExportMkv_Click;
|
||||
//
|
||||
// toolStripMenuItem_ExportMov
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_ExportMov, "toolStripMenuItem_ExportMov");
|
||||
toolStripMenuItem_ExportMov.Name = "toolStripMenuItem_ExportMov";
|
||||
resources.ApplyResources(toolStripMenuItem_ExportMov, "toolStripMenuItem_ExportMov");
|
||||
toolStripMenuItem_ExportMov.Click += toolStripMenuItem_ExportMov_Click;
|
||||
//
|
||||
// toolStripSeparator6
|
||||
//
|
||||
resources.ApplyResources(toolStripSeparator6, "toolStripSeparator6");
|
||||
toolStripSeparator6.Name = "toolStripSeparator6";
|
||||
resources.ApplyResources(toolStripSeparator6, "toolStripSeparator6");
|
||||
//
|
||||
// toolStripMenuItem_ExportCustom
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_ExportCustom, "toolStripMenuItem_ExportCustom");
|
||||
toolStripMenuItem_ExportCustom.Name = "toolStripMenuItem_ExportCustom";
|
||||
resources.ApplyResources(toolStripMenuItem_ExportCustom, "toolStripMenuItem_ExportCustom");
|
||||
toolStripMenuItem_ExportCustom.Click += toolStripMenuItem_ExportCustom_Click;
|
||||
//
|
||||
// toolStripSeparator2
|
||||
//
|
||||
resources.ApplyResources(toolStripSeparator2, "toolStripSeparator2");
|
||||
toolStripSeparator2.Name = "toolStripSeparator2";
|
||||
resources.ApplyResources(toolStripSeparator2, "toolStripSeparator2");
|
||||
//
|
||||
// toolStripMenuItem_Exit
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_Exit, "toolStripMenuItem_Exit");
|
||||
toolStripMenuItem_Exit.Name = "toolStripMenuItem_Exit";
|
||||
resources.ApplyResources(toolStripMenuItem_Exit, "toolStripMenuItem_Exit");
|
||||
toolStripMenuItem_Exit.Click += toolStripMenuItem_Exit_Click;
|
||||
//
|
||||
// toolStripMenuItem_Texture
|
||||
//
|
||||
toolStripMenuItem_Texture.DropDownItems.AddRange(new ToolStripItem[] { toolStripMenuItem_ForceSmooth, toolStripMenuItem_ForceRepeated, toolStripMenuItem_ForceMipmap });
|
||||
toolStripMenuItem_Texture.Name = "toolStripMenuItem_Texture";
|
||||
resources.ApplyResources(toolStripMenuItem_Texture, "toolStripMenuItem_Texture");
|
||||
//
|
||||
// toolStripMenuItem_ForceSmooth
|
||||
//
|
||||
toolStripMenuItem_ForceSmooth.Name = "toolStripMenuItem_ForceSmooth";
|
||||
resources.ApplyResources(toolStripMenuItem_ForceSmooth, "toolStripMenuItem_ForceSmooth");
|
||||
toolStripMenuItem_ForceSmooth.Click += toolStripMenuItem_ForceSmooth_Click;
|
||||
//
|
||||
// toolStripMenuItem_ForceRepeated
|
||||
//
|
||||
toolStripMenuItem_ForceRepeated.Name = "toolStripMenuItem_ForceRepeated";
|
||||
resources.ApplyResources(toolStripMenuItem_ForceRepeated, "toolStripMenuItem_ForceRepeated");
|
||||
toolStripMenuItem_ForceRepeated.Click += toolStripMenuItem_ForceRepeated_Click;
|
||||
//
|
||||
// toolStripMenuItem_ForceMipmap
|
||||
//
|
||||
toolStripMenuItem_ForceMipmap.Name = "toolStripMenuItem_ForceMipmap";
|
||||
resources.ApplyResources(toolStripMenuItem_ForceMipmap, "toolStripMenuItem_ForceMipmap");
|
||||
toolStripMenuItem_ForceMipmap.Click += toolStripMenuItem_ForceMipmap_Click;
|
||||
//
|
||||
// toolStripMenuItem_Tool
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_Tool, "toolStripMenuItem_Tool");
|
||||
toolStripMenuItem_Tool.DropDownItems.AddRange(new ToolStripItem[] { toolStripMenuItem_ConvertFileFormat });
|
||||
toolStripMenuItem_Tool.Name = "toolStripMenuItem_Tool";
|
||||
resources.ApplyResources(toolStripMenuItem_Tool, "toolStripMenuItem_Tool");
|
||||
//
|
||||
// toolStripMenuItem_ConvertFileFormat
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_ConvertFileFormat, "toolStripMenuItem_ConvertFileFormat");
|
||||
toolStripMenuItem_ConvertFileFormat.Name = "toolStripMenuItem_ConvertFileFormat";
|
||||
resources.ApplyResources(toolStripMenuItem_ConvertFileFormat, "toolStripMenuItem_ConvertFileFormat");
|
||||
toolStripMenuItem_ConvertFileFormat.Click += toolStripMenuItem_ConvertFileFormat_Click;
|
||||
//
|
||||
// toolStripMenuItem_Download
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_Download, "toolStripMenuItem_Download");
|
||||
toolStripMenuItem_Download.DropDownItems.AddRange(new ToolStripItem[] { toolStripMenuItem_ManageResource });
|
||||
toolStripMenuItem_Download.Name = "toolStripMenuItem_Download";
|
||||
resources.ApplyResources(toolStripMenuItem_Download, "toolStripMenuItem_Download");
|
||||
//
|
||||
// toolStripMenuItem_ManageResource
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_ManageResource, "toolStripMenuItem_ManageResource");
|
||||
toolStripMenuItem_ManageResource.Name = "toolStripMenuItem_ManageResource";
|
||||
resources.ApplyResources(toolStripMenuItem_ManageResource, "toolStripMenuItem_ManageResource");
|
||||
toolStripMenuItem_ManageResource.Click += toolStripMenuItem_ManageResource_Click;
|
||||
//
|
||||
// toolStripMenuItem_Help
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_Help, "toolStripMenuItem_Help");
|
||||
toolStripMenuItem_Help.DropDownItems.AddRange(new ToolStripItem[] { toolStripMenuItem_Diagnostics, toolStripSeparator3, toolStripMenuItem_About, toolStripMenuItem_Debug });
|
||||
toolStripMenuItem_Help.Name = "toolStripMenuItem_Help";
|
||||
resources.ApplyResources(toolStripMenuItem_Help, "toolStripMenuItem_Help");
|
||||
//
|
||||
// toolStripMenuItem_Diagnostics
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_Diagnostics, "toolStripMenuItem_Diagnostics");
|
||||
toolStripMenuItem_Diagnostics.Name = "toolStripMenuItem_Diagnostics";
|
||||
resources.ApplyResources(toolStripMenuItem_Diagnostics, "toolStripMenuItem_Diagnostics");
|
||||
toolStripMenuItem_Diagnostics.Click += toolStripMenuItem_Diagnostics_Click;
|
||||
//
|
||||
// toolStripSeparator3
|
||||
//
|
||||
resources.ApplyResources(toolStripSeparator3, "toolStripSeparator3");
|
||||
toolStripSeparator3.Name = "toolStripSeparator3";
|
||||
resources.ApplyResources(toolStripSeparator3, "toolStripSeparator3");
|
||||
//
|
||||
// toolStripMenuItem_About
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_About, "toolStripMenuItem_About");
|
||||
toolStripMenuItem_About.Name = "toolStripMenuItem_About";
|
||||
resources.ApplyResources(toolStripMenuItem_About, "toolStripMenuItem_About");
|
||||
toolStripMenuItem_About.Click += toolStripMenuItem_About_Click;
|
||||
//
|
||||
// toolStripMenuItem_Debug
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_Debug, "toolStripMenuItem_Debug");
|
||||
toolStripMenuItem_Debug.Name = "toolStripMenuItem_Debug";
|
||||
resources.ApplyResources(toolStripMenuItem_Debug, "toolStripMenuItem_Debug");
|
||||
toolStripMenuItem_Debug.Click += toolStripMenuItem_Debug_Click;
|
||||
//
|
||||
// toolStripMenuItem_Experiment
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_Experiment, "toolStripMenuItem_Experiment");
|
||||
toolStripMenuItem_Experiment.DropDownItems.AddRange(new ToolStripItem[] { toolStripMenuItem_DesktopProjection });
|
||||
toolStripMenuItem_Experiment.Name = "toolStripMenuItem_Experiment";
|
||||
resources.ApplyResources(toolStripMenuItem_Experiment, "toolStripMenuItem_Experiment");
|
||||
//
|
||||
// toolStripMenuItem_DesktopProjection
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_DesktopProjection, "toolStripMenuItem_DesktopProjection");
|
||||
toolStripMenuItem_DesktopProjection.Name = "toolStripMenuItem_DesktopProjection";
|
||||
resources.ApplyResources(toolStripMenuItem_DesktopProjection, "toolStripMenuItem_DesktopProjection");
|
||||
toolStripMenuItem_DesktopProjection.Click += toolStripMenuItem_DesktopProjection_Click;
|
||||
//
|
||||
// ToolStripMenuItem_Language
|
||||
//
|
||||
resources.ApplyResources(ToolStripMenuItem_Language, "ToolStripMenuItem_Language");
|
||||
ToolStripMenuItem_Language.DropDownItems.AddRange(new ToolStripItem[] { ToolStripMenuItem_English, ToolStripMenuItem_Chinese });
|
||||
ToolStripMenuItem_Language.Name = "ToolStripMenuItem_Language";
|
||||
resources.ApplyResources(ToolStripMenuItem_Language, "ToolStripMenuItem_Language");
|
||||
//
|
||||
// ToolStripMenuItem_English
|
||||
//
|
||||
resources.ApplyResources(ToolStripMenuItem_English, "ToolStripMenuItem_English");
|
||||
ToolStripMenuItem_English.Name = "ToolStripMenuItem_English";
|
||||
resources.ApplyResources(ToolStripMenuItem_English, "ToolStripMenuItem_English");
|
||||
ToolStripMenuItem_English.Click += ToolStripMenuItem_English_Click;
|
||||
//
|
||||
// ToolStripMenuItem_Chinese
|
||||
//
|
||||
resources.ApplyResources(ToolStripMenuItem_Chinese, "ToolStripMenuItem_Chinese");
|
||||
ToolStripMenuItem_Chinese.Name = "ToolStripMenuItem_Chinese";
|
||||
resources.ApplyResources(ToolStripMenuItem_Chinese, "ToolStripMenuItem_Chinese");
|
||||
ToolStripMenuItem_Chinese.Click += ToolStripMenuItem_Chinese_Click;
|
||||
//
|
||||
// panel_MainForm
|
||||
//
|
||||
resources.ApplyResources(panel_MainForm, "panel_MainForm");
|
||||
panel_MainForm.Controls.Add(splitContainer_MainForm);
|
||||
resources.ApplyResources(panel_MainForm, "panel_MainForm");
|
||||
panel_MainForm.Name = "panel_MainForm";
|
||||
toolTip.SetToolTip(panel_MainForm, resources.GetString("panel_MainForm.ToolTip"));
|
||||
//
|
||||
// toolTip
|
||||
//
|
||||
@@ -491,7 +488,6 @@
|
||||
Controls.Add(menuStrip);
|
||||
MainMenuStrip = menuStrip;
|
||||
Name = "SpineViewerForm";
|
||||
toolTip.SetToolTip(this, resources.GetString("$this.ToolTip"));
|
||||
FormClosing += MainForm_FormClosing;
|
||||
Load += MainForm_Load;
|
||||
splitContainer_MainForm.Panel1.ResumeLayout(false);
|
||||
@@ -573,5 +569,9 @@
|
||||
private ToolStripMenuItem ToolStripMenuItem_Language;
|
||||
private ToolStripMenuItem ToolStripMenuItem_English;
|
||||
private ToolStripMenuItem ToolStripMenuItem_Chinese;
|
||||
}
|
||||
private ToolStripMenuItem toolStripMenuItem_Texture;
|
||||
private ToolStripMenuItem toolStripMenuItem_ForceSmooth;
|
||||
private ToolStripMenuItem toolStripMenuItem_ForceRepeated;
|
||||
private ToolStripMenuItem toolStripMenuItem_ForceMipmap;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -119,7 +119,7 @@
|
||||
</resheader>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="groupBox_SkelList.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>350, 808</value>
|
||||
<value>350, 804</value>
|
||||
</data>
|
||||
<data name="groupBox_SkelList.Text" xml:space="preserve">
|
||||
<value>Model List</value>
|
||||
@@ -131,7 +131,7 @@
|
||||
<value />
|
||||
</data>
|
||||
<data name="groupBox_PreviewConfig.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>430, 267</value>
|
||||
<value>430, 265</value>
|
||||
</data>
|
||||
<data name="groupBox_PreviewConfig.Text" xml:space="preserve">
|
||||
<value>Image Parameters</value>
|
||||
@@ -143,7 +143,7 @@
|
||||
<value />
|
||||
</data>
|
||||
<data name="groupBox_SkelConfig.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>430, 533</value>
|
||||
<value>430, 531</value>
|
||||
</data>
|
||||
<data name="groupBox_SkelConfig.Text" xml:space="preserve">
|
||||
<value>Model Parameters</value>
|
||||
@@ -155,11 +155,11 @@
|
||||
<value />
|
||||
</data>
|
||||
<data name="splitContainer_Config.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>430, 808</value>
|
||||
<value>430, 804</value>
|
||||
</data>
|
||||
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="splitContainer_Config.SplitterDistance" type="System.Int32, mscorlib">
|
||||
<value>267</value>
|
||||
<value>265</value>
|
||||
</data>
|
||||
<data name="splitContainer_Config.ToolTip" xml:space="preserve">
|
||||
<value />
|
||||
@@ -168,7 +168,7 @@
|
||||
<value />
|
||||
</data>
|
||||
<data name="splitContainer_Information.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>788, 808</value>
|
||||
<value>788, 804</value>
|
||||
</data>
|
||||
<data name="splitContainer_Information.ToolTip" xml:space="preserve">
|
||||
<value />
|
||||
@@ -177,7 +177,7 @@
|
||||
<value />
|
||||
</data>
|
||||
<data name="groupBox_Preview.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>962, 808</value>
|
||||
<value>962, 804</value>
|
||||
</data>
|
||||
<data name="groupBox_Preview.Text" xml:space="preserve">
|
||||
<value>Preview Screen</value>
|
||||
@@ -189,7 +189,7 @@
|
||||
<value />
|
||||
</data>
|
||||
<data name="splitContainer_Functional.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>1758, 808</value>
|
||||
<value>1758, 804</value>
|
||||
</data>
|
||||
<data name="splitContainer_Functional.ToolTip" xml:space="preserve">
|
||||
<value />
|
||||
@@ -198,7 +198,7 @@
|
||||
<value />
|
||||
</data>
|
||||
<data name="rtbLog.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>1758, 188</value>
|
||||
<value>1758, 192</value>
|
||||
</data>
|
||||
<data name="rtbLog.ToolTip" xml:space="preserve">
|
||||
<value />
|
||||
@@ -207,16 +207,16 @@
|
||||
<value />
|
||||
</data>
|
||||
<data name="splitContainer_MainForm.SplitterDistance" type="System.Int32, mscorlib">
|
||||
<value>808</value>
|
||||
<value>804</value>
|
||||
</data>
|
||||
<data name="splitContainer_MainForm.ToolTip" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="spineListView.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>346, 781</value>
|
||||
<value>346, 777</value>
|
||||
</data>
|
||||
<data name="spineViewPropertyGrid.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>426, 506</value>
|
||||
<value>426, 504</value>
|
||||
</data>
|
||||
<data name="spineViewPropertyGrid.ToolTip" xml:space="preserve">
|
||||
<value />
|
||||
@@ -225,13 +225,13 @@
|
||||
<value />
|
||||
</data>
|
||||
<data name="propertyGrid_Previewer.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>426, 240</value>
|
||||
<value>426, 238</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Previewer.ToolTip" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="spinePreviewPanel.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>958, 781</value>
|
||||
<value>958, 777</value>
|
||||
</data>
|
||||
<data name="spinePreviewPanel.ToolTip" xml:space="preserve">
|
||||
<value />
|
||||
@@ -246,22 +246,22 @@
|
||||
<value>File(&F)</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Open.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>270, 34</value>
|
||||
<value>266, 34</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Open.Text" xml:space="preserve">
|
||||
<value>Open(&O)...</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_BatchOpen.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>270, 34</value>
|
||||
<value>266, 34</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_BatchOpen.Text" xml:space="preserve">
|
||||
<value>Batch Open(&B)...</value>
|
||||
</data>
|
||||
<data name="toolStripSeparator1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>267, 6</value>
|
||||
<value>263, 6</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Export.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>270, 34</value>
|
||||
<value>266, 34</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Export.Text" xml:space="preserve">
|
||||
<value>Export(&E)</value>
|
||||
@@ -315,14 +315,29 @@
|
||||
<value>FFmpeg Custom Export...</value>
|
||||
</data>
|
||||
<data name="toolStripSeparator2.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>267, 6</value>
|
||||
<value>263, 6</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Exit.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>270, 34</value>
|
||||
<value>266, 34</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Exit.Text" xml:space="preserve">
|
||||
<value>Exit(&X)</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Texture.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>112, 32</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Texture.Text" xml:space="preserve">
|
||||
<value>Texture(&E)</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_ForceSmooth.Text" xml:space="preserve">
|
||||
<value>Force Smooth</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_ForceRepeated.Text" xml:space="preserve">
|
||||
<value>Force Repeated</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_ForceMipmap.Text" xml:space="preserve">
|
||||
<value>Force Mipmap</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Tool.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>93, 32</value>
|
||||
</data>
|
||||
@@ -392,12 +407,6 @@
|
||||
<data name="ToolStripMenuItem_Language.Text" xml:space="preserve">
|
||||
<value>Language(&L)</value>
|
||||
</data>
|
||||
<data name="ToolStripMenuItem_English.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>270, 34</value>
|
||||
</data>
|
||||
<data name="ToolStripMenuItem_Chinese.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>270, 34</value>
|
||||
</data>
|
||||
<data name="panel_MainForm.ToolTip" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,5 @@
|
||||
using NLog;
|
||||
using SpineViewer.Spine.Implementations.SkeletonConverter;
|
||||
using SpineViewer.Utils;
|
||||
using SpineViewer.Utils.Localize;
|
||||
using System.Configuration;
|
||||
@@ -45,16 +46,16 @@ namespace SpineViewer
|
||||
{
|
||||
// 此处先初始化全局配置再触发静态字段 Logger 引用构造, 才能将配置应用到新的日志器上
|
||||
InitializeLogConfiguration();
|
||||
logger.Info("Program Started");
|
||||
logger.Info("Program Started");
|
||||
|
||||
// To customize application configuration such as set high DPI settings or default font,
|
||||
// see https://aka.ms/applicationconfiguration.
|
||||
ApplicationConfiguration.Initialize();
|
||||
// To customize application configuration such as set high DPI settings or default font,
|
||||
// see https://aka.ms/applicationconfiguration.
|
||||
ApplicationConfiguration.Initialize();
|
||||
LocalizeConfiguration.SetCulture();
|
||||
|
||||
try
|
||||
try
|
||||
{
|
||||
Application.Run(new SpineViewerForm() { Text = $"SpineViewer - v{Version}"});
|
||||
Application.Run(new SpineViewerForm() { Text = $"SpineViewer - v{Version}" });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -51,6 +51,17 @@ namespace SpineViewer.Spine.Implementations.SkeletonConverter
|
||||
[RotateMode.ChainScale] = "chainScale",
|
||||
};
|
||||
|
||||
private static readonly Dictionary<AttachmentType, string> AttachmentTypeJsonValue = new()
|
||||
{
|
||||
[AttachmentType.Region] = "region",
|
||||
[AttachmentType.Boundingbox] = "bounding",
|
||||
[AttachmentType.Mesh] = "mesh",
|
||||
[AttachmentType.Linkedmesh] = "linkedmesh",
|
||||
[AttachmentType.Path] = "path",
|
||||
[AttachmentType.Point] = "point",
|
||||
[AttachmentType.Clipping] = "clipping",
|
||||
};
|
||||
|
||||
private BinaryReader reader = null;
|
||||
private JsonObject root = null;
|
||||
private bool nonessential = false;
|
||||
@@ -298,7 +309,7 @@ namespace SpineViewer.Spine.Implementations.SkeletonConverter
|
||||
var name = reader.ReadStringRef() ?? keyName;
|
||||
var type = (AttachmentType)reader.ReadByte();
|
||||
attachment["name"] = name;
|
||||
attachment["type"] = type.ToString();
|
||||
attachment["type"] = AttachmentTypeJsonValue[type];
|
||||
switch (type)
|
||||
{
|
||||
case AttachmentType.Region:
|
||||
@@ -586,7 +597,7 @@ namespace SpineViewer.Spine.Implementations.SkeletonConverter
|
||||
["compress"] = reader.ReadBoolean(),
|
||||
["stretch"] = reader.ReadBoolean(),
|
||||
};
|
||||
if (frameCount > 1) ReadCurve(o);
|
||||
if (frameIdx < frameCount - 1) ReadCurve(o);
|
||||
frames.Add(o);
|
||||
}
|
||||
}
|
||||
@@ -613,7 +624,7 @@ namespace SpineViewer.Spine.Implementations.SkeletonConverter
|
||||
["scaleMix"] = reader.ReadFloat(),
|
||||
["shearMix"] = reader.ReadFloat(),
|
||||
};
|
||||
if (frameCount > 1) ReadCurve(o);
|
||||
if (frameIdx < frameCount - 1) ReadCurve(o);
|
||||
frames.Add(o);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -52,7 +52,7 @@ namespace SpineViewer.Spine.Implementations.SkeletonConverter
|
||||
[AttachmentType.Region] = "region",
|
||||
[AttachmentType.Boundingbox] = "bounding",
|
||||
[AttachmentType.Mesh] = "mesh",
|
||||
[AttachmentType.Linkedmesh] = "linkedMesh",
|
||||
[AttachmentType.Linkedmesh] = "linkedmesh",
|
||||
[AttachmentType.Path] = "path",
|
||||
[AttachmentType.Point] = "point",
|
||||
[AttachmentType.Clipping] = "clipping",
|
||||
@@ -294,7 +294,7 @@ namespace SpineViewer.Spine.Implementations.SkeletonConverter
|
||||
data["inertia"] = reader.ReadFloat();
|
||||
data["strength"] = reader.ReadFloat();
|
||||
data["damping"] = reader.ReadFloat();
|
||||
if ((flags & 128) != 0) data["mass"] = reader.ReadFloat();
|
||||
if ((flags & 128) != 0) data["mass"] = 1.0f / reader.ReadFloat(); //在binary中存储的是质量的倒数,在json中存储的是质量
|
||||
data["wind"] = reader.ReadFloat();
|
||||
data["gravity"] = reader.ReadFloat();
|
||||
|
||||
@@ -325,6 +325,21 @@ namespace SpineViewer.Spine.Implementations.SkeletonConverter
|
||||
// other skins
|
||||
for (int n = reader.ReadVarInt(); n > 0; n--)
|
||||
skins.Add(ReadSkin());
|
||||
|
||||
//处理linkedmesh的问题,后面有相关代码和注释
|
||||
foreach (JsonObject skin in skins)
|
||||
{
|
||||
foreach (var (_, slot) in skin["attachments"].AsObject())
|
||||
{
|
||||
foreach (var (_, attachment) in slot.AsObject())
|
||||
{
|
||||
if ((string)attachment["type"] == "linkedMesh")
|
||||
{
|
||||
attachment["skin"] = (string)skins[(int)attachment["skin"]]["name"];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private JsonObject? ReadSkin(bool isDefault = false)
|
||||
@@ -423,7 +438,9 @@ namespace SpineViewer.Spine.Implementations.SkeletonConverter
|
||||
if ((flags & 32) != 0) attachment["color"] = reader.ReadInt().ToString("x8");
|
||||
if ((flags & 64) != 0) attachment["sequence"] = ReadSequence();
|
||||
if ((flags & 128) == 0) attachment["timelines"] = false;
|
||||
attachment["skin"] = (string)skins[reader.ReadVarInt()]["name"];
|
||||
//attachment["skin"] = (string)skins[reader.ReadVarInt()]["name"];
|
||||
//还是那个mix-and-match,4.2版本的mix-and-match,出现了读取错误,后面写的时候也一样,linkedmesh的skin为后面还未访问的skin
|
||||
attachment["skin"] = reader.ReadVarInt();
|
||||
attachment["parent"] = reader.ReadStringRef();
|
||||
if (nonessential)
|
||||
{
|
||||
@@ -1052,14 +1069,14 @@ namespace SpineViewer.Spine.Implementations.SkeletonConverter
|
||||
{
|
||||
["time"] = reader.ReadFloat(),
|
||||
};
|
||||
ReadCurve(frame, 1);
|
||||
frame = o;
|
||||
end = reader.ReadVarInt();
|
||||
if (end > 0)
|
||||
{
|
||||
frame["offset"] = reader.ReadVarInt();
|
||||
frame["vertices"] = ReadFloatArray(end);
|
||||
}
|
||||
ReadCurve(frame, 1);
|
||||
frame = o;
|
||||
frames.Add(frame);
|
||||
}
|
||||
break;
|
||||
@@ -1084,7 +1101,7 @@ namespace SpineViewer.Spine.Implementations.SkeletonConverter
|
||||
}
|
||||
return attachmentTimelines.Count > 0 ? attachmentTimelines : null;
|
||||
}
|
||||
|
||||
|
||||
private JsonArray? ReadDrawOrderTimelines()
|
||||
{
|
||||
JsonArray slots = root["slots"].AsArray();
|
||||
@@ -1500,7 +1517,7 @@ namespace SpineViewer.Spine.Implementations.SkeletonConverter
|
||||
writer.WriteFloat((float)(data["inertia"] ?? 1f));
|
||||
writer.WriteFloat((float)(data["strength"] ?? 100f));
|
||||
writer.WriteFloat((float)(data["damping"] ?? 1f));
|
||||
if ((flags & 128) != 0) writer.WriteFloat(1f / (float)data["mass"]);
|
||||
if ((flags & 128) != 0) writer.WriteFloat(1f / (float)data["mass"]);
|
||||
writer.WriteFloat((float)(data["wind"] ?? 0f));
|
||||
writer.WriteFloat((float)(data["gravity"] ?? 0f));
|
||||
|
||||
@@ -1528,8 +1545,26 @@ namespace SpineViewer.Spine.Implementations.SkeletonConverter
|
||||
writer.WriteVarInt(0); // 其他皮肤数量
|
||||
return;
|
||||
}
|
||||
|
||||
//此处还是得先把数据全读了,反面例子还是那个mix-and-match,4.2版本的mix-and-match中,default用到了后面的skin,转换失败
|
||||
//mix-and-match的full-skins/boy这个skin,他的linkedmesh调用了后面的full-skins/boy
|
||||
JsonArray skins = root["skins"].AsArray();
|
||||
|
||||
foreach (JsonObject sk in skins)
|
||||
{
|
||||
if ((string)sk["name"] == "default")
|
||||
{
|
||||
skin2idx["default"] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
foreach (JsonObject sk in skins)
|
||||
{
|
||||
if ((string)sk["name"] != "default")
|
||||
{
|
||||
skin2idx["default"] = skin2idx.Count;
|
||||
}
|
||||
}
|
||||
|
||||
bool hasDefault = false;
|
||||
foreach (JsonObject skin in skins)
|
||||
{
|
||||
@@ -1537,7 +1572,7 @@ namespace SpineViewer.Spine.Implementations.SkeletonConverter
|
||||
{
|
||||
hasDefault = true;
|
||||
WriteSkin(skin, true);
|
||||
skin2idx["default"] = skin2idx.Count;
|
||||
//skin2idx["default"] = skin2idx.Count;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1558,7 +1593,7 @@ namespace SpineViewer.Spine.Implementations.SkeletonConverter
|
||||
if (name != "default")
|
||||
{
|
||||
WriteSkin(skin);
|
||||
skin2idx[name] = skin2idx.Count;
|
||||
//skin2idx[name] = skin2idx.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1960,7 +1995,7 @@ namespace SpineViewer.Spine.Implementations.SkeletonConverter
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (type == "rotate")
|
||||
{
|
||||
writer.WriteByte(SkeletonBinary.BONE_ROTATE);
|
||||
|
||||
@@ -29,26 +29,6 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
// };
|
||||
//}
|
||||
|
||||
private class TextureLoader : SpineRuntime21.TextureLoader
|
||||
{
|
||||
public void Load(AtlasPage page, string path)
|
||||
{
|
||||
var texture = new SFML.Graphics.Texture(path);
|
||||
if (page.magFilter == TextureFilter.Linear)
|
||||
texture.Smooth = true;
|
||||
if (page.uWrap == TextureWrap.Repeat && page.vWrap == TextureWrap.Repeat)
|
||||
texture.Repeated = true;
|
||||
|
||||
page.rendererObject = texture;
|
||||
}
|
||||
|
||||
public void Unload(object texture)
|
||||
{
|
||||
((SFML.Graphics.Texture)texture).Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private readonly static TextureLoader textureLoader = new();
|
||||
private static readonly Animation EmptyAnimation = new(EMPTY_ANIMATION, [], 0);
|
||||
|
||||
private readonly Atlas atlas;
|
||||
@@ -70,7 +50,8 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
|
||||
public SpineObject21(string skelPath, string atlasPath) : base(skelPath, atlasPath)
|
||||
{
|
||||
atlas = new Atlas(AtlasPath, textureLoader);
|
||||
try { atlas = new Atlas(AtlasPath, textureLoader); }
|
||||
catch (Exception ex) { throw new InvalidDataException($"Failed to load atlas '{atlasPath}'", ex); }
|
||||
try
|
||||
{
|
||||
// 先尝试二进制文件
|
||||
@@ -90,6 +71,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
catch
|
||||
{
|
||||
// 都不行就报错
|
||||
atlas.Dispose();
|
||||
throw new InvalidDataException($"Unknown skeleton file format {SkelPath}");
|
||||
}
|
||||
}
|
||||
@@ -116,7 +98,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
atlas.Dispose();
|
||||
atlas?.Dispose();
|
||||
}
|
||||
|
||||
public override string FileVersion { get => skeletonData.Version; }
|
||||
@@ -240,10 +222,10 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
tmpSkeleton.Update(0);
|
||||
tmpSkeleton.UpdateWorldTransform();
|
||||
|
||||
// 按 10 帧每秒计算边框
|
||||
// 按 100 帧每秒计算边框
|
||||
var bounds = getCurrentBounds();
|
||||
float[] _ = [];
|
||||
for (float tick = 0, delta = 0.1f; tick < maxDuration; tick += delta)
|
||||
for (float tick = 0, delta = 0.01f; tick < maxDuration; tick += delta)
|
||||
{
|
||||
tmpSkeleton.GetBounds(out var x, out var y, out var w, out var h);
|
||||
bounds = bounds.Union(new(x, y, w, h));
|
||||
@@ -278,7 +260,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
SFML.Graphics.Texture texture;
|
||||
|
||||
float[] worldVertices = worldVerticesBuffer; // 顶点世界坐标, 连续的 [x0, y0, x1, y1, ...] 坐标值
|
||||
int worldVerticesCount; // 等于顶点数组的长度除以 2
|
||||
//int worldVerticesCount; // 等于顶点数组的长度除以 2
|
||||
int[] worldTriangleIndices; // 三角形索引, 从顶点坐标数组取的时候要乘以 2, 最大值是 worldVerticesCount - 1
|
||||
int worldTriangleIndicesLength; // 三角形索引数组长度
|
||||
float[] uvs; // 纹理坐标
|
||||
@@ -292,7 +274,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
texture = (SFML.Graphics.Texture)((AtlasRegion)regionAttachment.RendererObject).page.rendererObject;
|
||||
|
||||
regionAttachment.ComputeWorldVertices(slot.Bone, worldVertices);
|
||||
worldVerticesCount = 4;
|
||||
//worldVerticesCount = 4;
|
||||
worldTriangleIndices = [0, 1, 2, 2, 3, 0];
|
||||
worldTriangleIndicesLength = 6;
|
||||
uvs = regionAttachment.UVs;
|
||||
@@ -308,7 +290,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
if (meshAttachment.Vertices.Length > worldVertices.Length)
|
||||
worldVertices = worldVerticesBuffer = new float[meshAttachment.Vertices.Length * 2];
|
||||
meshAttachment.ComputeWorldVertices(slot, worldVertices);
|
||||
worldVerticesCount = meshAttachment.Vertices.Length / 2;
|
||||
//worldVerticesCount = meshAttachment.Vertices.Length / 2;
|
||||
worldTriangleIndices = meshAttachment.Triangles;
|
||||
worldTriangleIndicesLength = meshAttachment.Triangles.Length;
|
||||
uvs = meshAttachment.UVs;
|
||||
@@ -317,6 +299,22 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
tintB *= meshAttachment.B;
|
||||
tintA *= meshAttachment.A;
|
||||
}
|
||||
else if (attachment is SkinnedMeshAttachment skinnedMeshAttachment)
|
||||
{
|
||||
texture = (SFML.Graphics.Texture)((AtlasRegion)skinnedMeshAttachment.RendererObject).page.rendererObject;
|
||||
|
||||
if (skinnedMeshAttachment.UVs.Length > worldVertices.Length)
|
||||
worldVertices = worldVerticesBuffer = new float[skinnedMeshAttachment.UVs.Length * 2];
|
||||
skinnedMeshAttachment.ComputeWorldVertices(slot, worldVertices);
|
||||
//worldVerticesCount = skinnedMeshAttachment.Vertices.Length / 2;
|
||||
worldTriangleIndices = skinnedMeshAttachment.Triangles;
|
||||
worldTriangleIndicesLength = skinnedMeshAttachment.Triangles.Length;
|
||||
uvs = skinnedMeshAttachment.UVs;
|
||||
tintR *= skinnedMeshAttachment.R;
|
||||
tintG *= skinnedMeshAttachment.G;
|
||||
tintB *= skinnedMeshAttachment.B;
|
||||
tintA *= skinnedMeshAttachment.A;
|
||||
}
|
||||
// 2.1.x 不支持剪裁
|
||||
//else if (attachment is ClippingAttachment clippingAttachment)
|
||||
//{
|
||||
@@ -450,6 +448,37 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
vt.Position.Y = worldVerticesBuffer[idx2 + 1];
|
||||
lineVertices.Append(vt); lineVertices.Append(vt);
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[idx0];
|
||||
vt.Position.Y = worldVerticesBuffer[idx0 + 1];
|
||||
lineVertices.Append(vt);
|
||||
}
|
||||
}
|
||||
else if (slot.Attachment is SkinnedMeshAttachment skinnedMeshAttachment)
|
||||
{
|
||||
if (skinnedMeshAttachment.UVs.Length > worldVerticesBuffer.Length)
|
||||
worldVerticesBuffer = new float[skinnedMeshAttachment.UVs.Length * 2];
|
||||
|
||||
skinnedMeshAttachment.ComputeWorldVertices(slot, worldVerticesBuffer);
|
||||
|
||||
var triangleIndices = skinnedMeshAttachment.Triangles;
|
||||
for (int i = 0; i < triangleIndices.Length; i += 3)
|
||||
{
|
||||
var idx0 = triangleIndices[i] * 2;
|
||||
var idx1 = triangleIndices[i + 1] * 2;
|
||||
var idx2 = triangleIndices[i + 2] * 2;
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[idx0];
|
||||
vt.Position.Y = worldVerticesBuffer[idx0 + 1];
|
||||
lineVertices.Append(vt);
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[idx1];
|
||||
vt.Position.Y = worldVerticesBuffer[idx1 + 1];
|
||||
lineVertices.Append(vt); lineVertices.Append(vt);
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[idx2];
|
||||
vt.Position.Y = worldVerticesBuffer[idx2 + 1];
|
||||
lineVertices.Append(vt); lineVertices.Append(vt);
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[idx0];
|
||||
vt.Position.Y = worldVerticesBuffer[idx0 + 1];
|
||||
lineVertices.Append(vt);
|
||||
@@ -472,6 +501,34 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
|
||||
var hullLength = (meshAttachment.HullLength >> 1) << 1;
|
||||
|
||||
if (debugMeshHulls && hullLength > 2)
|
||||
{
|
||||
vt.Position.X = worldVerticesBuffer[0];
|
||||
vt.Position.Y = worldVerticesBuffer[1];
|
||||
lineVertices.Append(vt);
|
||||
|
||||
for (int i = 2; i < hullLength; i += 2)
|
||||
{
|
||||
vt.Position.X = worldVerticesBuffer[i];
|
||||
vt.Position.Y = worldVerticesBuffer[i + 1];
|
||||
lineVertices.Append(vt);
|
||||
lineVertices.Append(vt);
|
||||
}
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[0];
|
||||
vt.Position.Y = worldVerticesBuffer[1];
|
||||
lineVertices.Append(vt);
|
||||
}
|
||||
}
|
||||
else if (slot.Attachment is SkinnedMeshAttachment skinnedMeshAttachment)
|
||||
{
|
||||
if (skinnedMeshAttachment.UVs.Length > worldVerticesBuffer.Length)
|
||||
worldVerticesBuffer = new float[skinnedMeshAttachment.UVs.Length * 2];
|
||||
|
||||
skinnedMeshAttachment.ComputeWorldVertices(slot, worldVerticesBuffer);
|
||||
|
||||
var hullLength = (skinnedMeshAttachment.HullLength >> 1) << 1;
|
||||
|
||||
if (debugMeshHulls && hullLength > 2)
|
||||
{
|
||||
vt.Position.X = worldVerticesBuffer[0];
|
||||
|
||||
@@ -29,26 +29,6 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
};
|
||||
}
|
||||
|
||||
private class TextureLoader : SpineRuntime36.TextureLoader
|
||||
{
|
||||
public void Load(AtlasPage page, string path)
|
||||
{
|
||||
var texture = new SFML.Graphics.Texture(path);
|
||||
if (page.magFilter == TextureFilter.Linear)
|
||||
texture.Smooth = true;
|
||||
if (page.uWrap == TextureWrap.Repeat && page.vWrap == TextureWrap.Repeat)
|
||||
texture.Repeated = true;
|
||||
|
||||
page.rendererObject = texture;
|
||||
}
|
||||
|
||||
public void Unload(object texture)
|
||||
{
|
||||
((SFML.Graphics.Texture)texture).Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly TextureLoader textureLoader = new();
|
||||
private static readonly Animation EmptyAnimation = new(EMPTY_ANIMATION, [], 0);
|
||||
|
||||
private readonly Atlas atlas;
|
||||
@@ -69,7 +49,8 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
|
||||
public SpineObject36(string skelPath, string atlasPath) : base(skelPath, atlasPath)
|
||||
{
|
||||
atlas = new Atlas(AtlasPath, textureLoader);
|
||||
try { atlas = new Atlas(AtlasPath, textureLoader); }
|
||||
catch (Exception ex) { throw new InvalidDataException($"Failed to load atlas '{atlasPath}'", ex); }
|
||||
try
|
||||
{
|
||||
// 先尝试二进制文件
|
||||
@@ -89,6 +70,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
catch
|
||||
{
|
||||
// 都不行就报错
|
||||
atlas.Dispose();
|
||||
throw new InvalidDataException($"Unknown skeleton file format {SkelPath}");
|
||||
}
|
||||
}
|
||||
@@ -115,7 +97,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
atlas.Dispose();
|
||||
atlas?.Dispose();
|
||||
}
|
||||
|
||||
public override string FileVersion { get => skeletonData.Version; }
|
||||
@@ -240,10 +222,10 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
tmpSkeleton.Update(0);
|
||||
tmpSkeleton.UpdateWorldTransform();
|
||||
|
||||
// 按 10 帧每秒计算边框
|
||||
// 按 100 帧每秒计算边框
|
||||
var bounds = getCurrentBounds();
|
||||
float[] _ = [];
|
||||
for (float tick = 0, delta = 0.1f; tick < maxDuration; tick += delta)
|
||||
for (float tick = 0, delta = 0.01f; tick < maxDuration; tick += delta)
|
||||
{
|
||||
tmpSkeleton.GetBounds(out var x, out var y, out var w, out var h, ref _);
|
||||
bounds = bounds.Union(new(x, y, w, h));
|
||||
|
||||
@@ -26,26 +26,6 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
};
|
||||
}
|
||||
|
||||
private class TextureLoader : SpineRuntime37.TextureLoader
|
||||
{
|
||||
public void Load(AtlasPage page, string path)
|
||||
{
|
||||
var texture = new SFML.Graphics.Texture(path);
|
||||
if (page.magFilter == TextureFilter.Linear)
|
||||
texture.Smooth = true;
|
||||
if (page.uWrap == TextureWrap.Repeat && page.vWrap == TextureWrap.Repeat)
|
||||
texture.Repeated = true;
|
||||
|
||||
page.rendererObject = texture;
|
||||
}
|
||||
|
||||
public void Unload(object texture)
|
||||
{
|
||||
((SFML.Graphics.Texture)texture).Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly TextureLoader textureLoader = new();
|
||||
private static readonly Animation EmptyAnimation = new(EMPTY_ANIMATION, [], 0);
|
||||
|
||||
private readonly Atlas atlas;
|
||||
@@ -66,7 +46,8 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
|
||||
public SpineObject37(string skelPath, string atlasPath) : base(skelPath, atlasPath)
|
||||
{
|
||||
atlas = new Atlas(AtlasPath, textureLoader);
|
||||
try { atlas = new Atlas(AtlasPath, textureLoader); }
|
||||
catch (Exception ex) { throw new InvalidDataException($"Failed to load atlas '{atlasPath}'", ex); }
|
||||
try
|
||||
{
|
||||
// 先尝试二进制文件
|
||||
@@ -86,6 +67,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
catch
|
||||
{
|
||||
// 都不行就报错
|
||||
atlas.Dispose();
|
||||
throw new InvalidDataException($"Unknown skeleton file format {SkelPath}");
|
||||
}
|
||||
}
|
||||
@@ -112,7 +94,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
atlas.Dispose();
|
||||
atlas?.Dispose();
|
||||
}
|
||||
|
||||
public override string FileVersion { get => skeletonData.Version; }
|
||||
@@ -237,10 +219,10 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
tmpSkeleton.Update(0);
|
||||
tmpSkeleton.UpdateWorldTransform();
|
||||
|
||||
// 按 10 帧每秒计算边框
|
||||
// 按 100 帧每秒计算边框
|
||||
var bounds = getCurrentBounds();
|
||||
float[] _ = [];
|
||||
for (float tick = 0, delta = 0.1f; tick < maxDuration; tick += delta)
|
||||
for (float tick = 0, delta = 0.01f; tick < maxDuration; tick += delta)
|
||||
{
|
||||
tmpSkeleton.GetBounds(out var x, out var y, out var w, out var h, ref _);
|
||||
bounds = bounds.Union(new(x, y, w, h));
|
||||
|
||||
@@ -30,29 +30,6 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
};
|
||||
}
|
||||
|
||||
private class TextureLoader : SpineRuntime38.TextureLoader
|
||||
{
|
||||
public void Load(AtlasPage page, string path)
|
||||
{
|
||||
var texture = new SFML.Graphics.Texture(path);
|
||||
if (page.magFilter == TextureFilter.Linear)
|
||||
texture.Smooth = true;
|
||||
if (page.uWrap == TextureWrap.Repeat && page.vWrap == TextureWrap.Repeat)
|
||||
texture.Repeated = true;
|
||||
|
||||
page.rendererObject = texture;
|
||||
// 似乎是不需要设置的, 因为存在某些 png 和 atlas 大小不同的情况, 一般是有一些缩放, 如果设置了反而渲染异常
|
||||
// page.width = (int)texture.Size.X;
|
||||
// page.height = (int)texture.Size.Y;
|
||||
}
|
||||
|
||||
public void Unload(object texture)
|
||||
{
|
||||
((SFML.Graphics.Texture)texture).Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly TextureLoader textureLoader = new();
|
||||
private static readonly Animation EmptyAnimation = new(EMPTY_ANIMATION, [], 0);
|
||||
|
||||
private readonly Atlas atlas;
|
||||
@@ -73,7 +50,8 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
|
||||
public SpineObject38(string skelPath, string atlasPath) : base(skelPath, atlasPath)
|
||||
{
|
||||
atlas = new Atlas(AtlasPath, textureLoader);
|
||||
try { atlas = new Atlas(AtlasPath, textureLoader); }
|
||||
catch (Exception ex) { throw new InvalidDataException($"Failed to load atlas '{atlasPath}'", ex); }
|
||||
try
|
||||
{
|
||||
// 先尝试二进制文件
|
||||
@@ -93,6 +71,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 都不行就报错
|
||||
atlas.Dispose();
|
||||
throw new InvalidDataException($"Unknown skeleton file format {SkelPath}", ex);
|
||||
}
|
||||
}
|
||||
@@ -119,7 +98,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
atlas.Dispose();
|
||||
atlas?.Dispose();
|
||||
}
|
||||
|
||||
public override string FileVersion { get => skeletonData.Version; }
|
||||
@@ -238,10 +217,10 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
tmpSkeleton.Update(0);
|
||||
tmpSkeleton.UpdateWorldTransform();
|
||||
|
||||
// 按 10 帧每秒计算边框
|
||||
// 按 100 帧每秒计算边框
|
||||
var bounds = getCurrentBounds();
|
||||
float[] _ = [];
|
||||
for (float tick = 0, delta = 0.1f; tick < maxDuration; tick += delta)
|
||||
for (float tick = 0, delta = 0.01f; tick < maxDuration; tick += delta)
|
||||
{
|
||||
tmpSkeleton.GetBounds(out var x, out var y, out var w, out var h, ref _);
|
||||
bounds = bounds.Union(new(x, y, w, h));
|
||||
|
||||
@@ -28,26 +28,6 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
};
|
||||
}
|
||||
|
||||
private class TextureLoader : SpineRuntime40.TextureLoader
|
||||
{
|
||||
public void Load(AtlasPage page, string path)
|
||||
{
|
||||
var texture = new SFML.Graphics.Texture(path);
|
||||
if (page.magFilter == TextureFilter.Linear)
|
||||
texture.Smooth = true;
|
||||
if (page.uWrap == TextureWrap.Repeat && page.vWrap == TextureWrap.Repeat)
|
||||
texture.Repeated = true;
|
||||
|
||||
page.rendererObject = texture;
|
||||
}
|
||||
|
||||
public void Unload(object texture)
|
||||
{
|
||||
((SFML.Graphics.Texture)texture).Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly TextureLoader textureLoader = new();
|
||||
private static readonly Animation EmptyAnimation = new(EMPTY_ANIMATION, [], 0);
|
||||
|
||||
private readonly Atlas atlas;
|
||||
@@ -68,7 +48,8 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
|
||||
public SpineObject40(string skelPath, string atlasPath) : base(skelPath, atlasPath)
|
||||
{
|
||||
atlas = new Atlas(AtlasPath, textureLoader);
|
||||
try { atlas = new Atlas(AtlasPath, textureLoader); }
|
||||
catch (Exception ex) { throw new InvalidDataException($"Failed to load atlas '{atlasPath}'", ex); }
|
||||
try
|
||||
{
|
||||
// 先尝试二进制文件
|
||||
@@ -88,6 +69,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
catch
|
||||
{
|
||||
// 都不行就报错
|
||||
atlas.Dispose();
|
||||
throw new InvalidDataException($"Unknown skeleton file format {SkelPath}");
|
||||
}
|
||||
}
|
||||
@@ -115,7 +97,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
atlas.Dispose();
|
||||
atlas?.Dispose();
|
||||
}
|
||||
|
||||
public override string FileVersion { get => skeletonData.Version; }
|
||||
@@ -234,10 +216,10 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
tmpSkeleton.Update(0);
|
||||
tmpSkeleton.UpdateWorldTransform();
|
||||
|
||||
// 按 10 帧每秒计算边框
|
||||
// 按 100 帧每秒计算边框
|
||||
var bounds = getCurrentBounds();
|
||||
float[] _ = [];
|
||||
for (float tick = 0, delta = 0.1f; tick < maxDuration; tick += delta)
|
||||
for (float tick = 0, delta = 0.01f; tick < maxDuration; tick += delta)
|
||||
{
|
||||
tmpSkeleton.GetBounds(out var x, out var y, out var w, out var h, ref _);
|
||||
bounds = bounds.Union(new(x, y, w, h));
|
||||
|
||||
@@ -28,26 +28,6 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
};
|
||||
}
|
||||
|
||||
private class TextureLoader : SpineRuntime41.TextureLoader
|
||||
{
|
||||
public void Load(AtlasPage page, string path)
|
||||
{
|
||||
var texture = new SFML.Graphics.Texture(path);
|
||||
if (page.magFilter == TextureFilter.Linear)
|
||||
texture.Smooth = true;
|
||||
if (page.uWrap == TextureWrap.Repeat && page.vWrap == TextureWrap.Repeat)
|
||||
texture.Repeated = true;
|
||||
|
||||
page.rendererObject = texture;
|
||||
}
|
||||
|
||||
public void Unload(object texture)
|
||||
{
|
||||
((SFML.Graphics.Texture)texture).Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private static TextureLoader textureLoader = new();
|
||||
private static readonly Animation EmptyAnimation = new(EMPTY_ANIMATION, [], 0);
|
||||
|
||||
private readonly Atlas atlas;
|
||||
@@ -68,7 +48,8 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
|
||||
public SpineObject41(string skelPath, string atlasPath) : base(skelPath, atlasPath)
|
||||
{
|
||||
atlas = new Atlas(AtlasPath, textureLoader);
|
||||
try { atlas = new Atlas(AtlasPath, textureLoader); }
|
||||
catch (Exception ex) { throw new InvalidDataException($"Failed to load atlas '{atlasPath}'", ex); }
|
||||
try
|
||||
{
|
||||
// 先尝试二进制文件
|
||||
@@ -88,6 +69,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
catch
|
||||
{
|
||||
// 都不行就报错
|
||||
atlas.Dispose();
|
||||
throw new InvalidDataException($"Unknown skeleton file format {SkelPath}");
|
||||
}
|
||||
}
|
||||
@@ -115,7 +97,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
atlas.Dispose();
|
||||
atlas?.Dispose();
|
||||
}
|
||||
|
||||
public override string FileVersion { get => skeletonData.Version; }
|
||||
@@ -234,10 +216,10 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
//tmpSkeleton.Update(0);
|
||||
tmpSkeleton.UpdateWorldTransform();
|
||||
|
||||
// 按 10 帧每秒计算边框
|
||||
// 按 100 帧每秒计算边框
|
||||
var bounds = getCurrentBounds();
|
||||
float[] _ = [];
|
||||
for (float tick = 0, delta = 0.1f; tick < maxDuration; tick += delta)
|
||||
for (float tick = 0, delta = 0.01f; tick < maxDuration; tick += delta)
|
||||
{
|
||||
tmpSkeleton.GetBounds(out var x, out var y, out var w, out var h, ref _);
|
||||
bounds = bounds.Union(new(x, y, w, h));
|
||||
|
||||
@@ -28,26 +28,6 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
};
|
||||
}
|
||||
|
||||
private class TextureLoader : SpineRuntime42.TextureLoader
|
||||
{
|
||||
public void Load(AtlasPage page, string path)
|
||||
{
|
||||
var texture = new SFML.Graphics.Texture(path);
|
||||
if (page.magFilter == TextureFilter.Linear)
|
||||
texture.Smooth = true;
|
||||
if (page.uWrap == TextureWrap.Repeat && page.vWrap == TextureWrap.Repeat)
|
||||
texture.Repeated = true;
|
||||
|
||||
page.rendererObject = texture;
|
||||
}
|
||||
|
||||
public void Unload(object texture)
|
||||
{
|
||||
((SFML.Graphics.Texture)texture).Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly TextureLoader textureLoader = new();
|
||||
private static readonly Animation EmptyAnimation = new(EMPTY_ANIMATION, [], 0);
|
||||
|
||||
private readonly Atlas atlas;
|
||||
@@ -68,7 +48,8 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
|
||||
public SpineObject42(string skelPath, string atlasPath) : base(skelPath, atlasPath)
|
||||
{
|
||||
atlas = new Atlas(AtlasPath, textureLoader);
|
||||
try { atlas = new Atlas(AtlasPath, textureLoader); }
|
||||
catch (Exception ex) { throw new InvalidDataException($"Failed to load atlas '{atlasPath}'", ex); }
|
||||
try
|
||||
{
|
||||
// 先尝试二进制文件
|
||||
@@ -88,6 +69,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
catch
|
||||
{
|
||||
// 都不行就报错
|
||||
atlas.Dispose();
|
||||
throw new InvalidDataException($"Unknown skeleton file format {SkelPath}");
|
||||
}
|
||||
}
|
||||
@@ -115,7 +97,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
atlas.Dispose();
|
||||
atlas?.Dispose();
|
||||
}
|
||||
|
||||
public override string FileVersion { get => skeletonData.Version; }
|
||||
@@ -234,10 +216,10 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
tmpSkeleton.Update(0);
|
||||
tmpSkeleton.UpdateWorldTransform(Skeleton.Physics.Update);
|
||||
|
||||
// 按 10 帧每秒计算边框
|
||||
// 按 100 帧每秒计算边框
|
||||
var bounds = getCurrentBounds();
|
||||
float[] _ = [];
|
||||
for (float tick = 0, delta = 0.1f; tick < maxDuration; tick += delta)
|
||||
for (float tick = 0, delta = 0.01f; tick < maxDuration; tick += delta)
|
||||
{
|
||||
tmpSkeleton.GetBounds(out var x, out var y, out var w, out var h, ref _);
|
||||
bounds = bounds.Union(new(x, y, w, h));
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace SpineViewer.Spine.SpineExporter
|
||||
var noteSuffix = FileNameNoteSuffix;
|
||||
if (!string.IsNullOrWhiteSpace(noteSuffix)) noteSuffix = $"_{noteSuffix}";
|
||||
|
||||
var filename = $"ffmpeg_{timestamp}_{FPS:f0}{noteSuffix}{Suffix}";
|
||||
var filename = $"ffmpeg_{timestamp}_{Guid.NewGuid().ToString()[..6]}_{FPS:f0}{noteSuffix}{Suffix}";
|
||||
|
||||
// 导出单个时必定提供输出文件夹
|
||||
var savePath = Path.Combine(OutputDir, filename);
|
||||
@@ -86,7 +86,7 @@ namespace SpineViewer.Spine.SpineExporter
|
||||
{
|
||||
if (worker?.CancellationPending == true) break; // 取消的日志在 GetFrames 里输出
|
||||
|
||||
var filename = $"{spine.Name}_{timestamp}_{FPS:f0}{noteSuffix}{Suffix}";
|
||||
var filename = $"{spine.Name}_{timestamp}_{spine.ID[..6]}_{FPS:f0}{noteSuffix}{Suffix}";
|
||||
|
||||
// 如果提供了输出文件夹, 则全部导出到输出文件夹, 否则导出到各自的文件夹下
|
||||
var savePath = Path.Combine(OutputDir ?? spine.AssetsDir, filename);
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace SpineViewer.Spine.SpineExporter
|
||||
protected override void ExportSingle(SpineObject[] spinesToRender, BackgroundWorker? worker = null)
|
||||
{
|
||||
// 导出单个时必定提供输出文件夹
|
||||
var filename = $"frame_{timestamp}{ImageFormat.GetSuffix()}";
|
||||
var filename = $"frame_{timestamp}_{Guid.NewGuid().ToString()[..6]}{ImageFormat.GetSuffix()}";
|
||||
var savePath = Path.Combine(OutputDir, filename);
|
||||
|
||||
worker?.ReportProgress(0, $"{Properties.Resources.process} 0/1");
|
||||
@@ -78,7 +78,7 @@ namespace SpineViewer.Spine.SpineExporter
|
||||
var spine = spinesToRender[i];
|
||||
|
||||
// 逐个导出时如果提供了输出文件夹, 则全部导出到输出文件夹, 否则输出到各自的文件夹
|
||||
var filename = $"{spine.Name}_{timestamp}{ImageFormat.GetSuffix()}";
|
||||
var filename = $"{spine.Name}_{timestamp}_{spine.ID[..6]}{ImageFormat.GetSuffix()}";
|
||||
var savePath = Path.Combine(OutputDir ?? spine.AssetsDir, filename);
|
||||
|
||||
try
|
||||
|
||||
@@ -22,14 +22,16 @@ namespace SpineViewer.Spine.SpineExporter
|
||||
|
||||
protected override void ExportSingle(SpineObject[] spinesToRender, BackgroundWorker? worker = null)
|
||||
{
|
||||
var uniqueSuffix = Guid.NewGuid().ToString()[..6];
|
||||
|
||||
// 导出单个时必定提供输出文件夹,
|
||||
var saveDir = Path.Combine(OutputDir, $"frames_{timestamp}_{FPS:f0}");
|
||||
var saveDir = Path.Combine(OutputDir, $"frames_{timestamp}_{uniqueSuffix}_{FPS:f0}");
|
||||
Directory.CreateDirectory(saveDir);
|
||||
|
||||
int frameIdx = 0;
|
||||
foreach (var frame in GetFrames(spinesToRender, worker))
|
||||
{
|
||||
var filename = $"frames_{timestamp}_{FPS:f0}_{frameIdx:d6}{Suffix}";
|
||||
var filename = $"frames_{timestamp}_{uniqueSuffix}_{FPS:f0}_{frameIdx:d6}{Suffix}";
|
||||
var savePath = Path.Combine(saveDir, filename);
|
||||
|
||||
try
|
||||
@@ -56,14 +58,14 @@ namespace SpineViewer.Spine.SpineExporter
|
||||
if (worker?.CancellationPending == true) break; // 取消的日志在 GetFrames 里输出
|
||||
|
||||
// 如果提供了输出文件夹, 则全部导出到输出文件夹, 否则导出到各自的文件夹下
|
||||
var subDir = $"{spine.Name}_{timestamp}_{FPS:f0}";
|
||||
var subDir = $"{spine.Name}_{timestamp}_{spine.ID[..6]}_{FPS:f0}";
|
||||
var saveDir = Path.Combine(OutputDir ?? spine.AssetsDir, subDir);
|
||||
Directory.CreateDirectory(saveDir);
|
||||
|
||||
int frameIdx = 0;
|
||||
foreach (var frame in GetFrames(spine, worker))
|
||||
{
|
||||
var filename = $"{spine.Name}_{timestamp}_{FPS:f0}_{frameIdx:d6}{Suffix}";
|
||||
var filename = $"{spine.Name}_{timestamp}_{spine.ID[..6]}_{FPS:f0}_{frameIdx:d6}{Suffix}";
|
||||
var savePath = Path.Combine(saveDir, filename);
|
||||
|
||||
try
|
||||
|
||||
@@ -30,15 +30,6 @@ namespace SpineViewer.Spine.SpineExporter
|
||||
/// </summary>
|
||||
public bool KeepLast { get; set; } = true;
|
||||
|
||||
public override string? Validate()
|
||||
{
|
||||
if (base.Validate() is string error)
|
||||
return error;
|
||||
if (IsExportSingle && Duration < 0)
|
||||
return Properties.Resources.negativeDuration;
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成单个模型的帧序列
|
||||
/// </summary>
|
||||
@@ -93,8 +84,16 @@ namespace SpineViewer.Spine.SpineExporter
|
||||
/// </summary>
|
||||
protected IEnumerable<SFMLImageVideoFrame> GetFrames(SpineObject[] spinesToRender, BackgroundWorker? worker = null)
|
||||
{
|
||||
// 导出单个时必须根据 Duration 决定导出时长
|
||||
// 导出单个时取所有模型的所有轨道时长最大值
|
||||
var duration = Duration;
|
||||
if (duration < 0)
|
||||
{
|
||||
duration = spinesToRender.Select(
|
||||
sp => sp.GetTrackIndices().Select(
|
||||
i => sp.GetAnimationDuration(sp.GetAnimation(i))
|
||||
).DefaultIfEmpty(0).Max()
|
||||
).Max();
|
||||
}
|
||||
|
||||
float delta = 1f / FPS;
|
||||
int total = (int)(duration * FPS); // 完整帧的数量
|
||||
|
||||
@@ -32,6 +32,12 @@ namespace SpineViewer.Spine
|
||||
/// </summary>
|
||||
protected static readonly Size PreviewResolution = new(256, 256);
|
||||
|
||||
/// <summary>
|
||||
/// 纹理加载器
|
||||
/// </summary>
|
||||
public static TextureLoader TextureLoader => textureLoader;
|
||||
protected readonly static TextureLoader textureLoader = new();
|
||||
|
||||
/// <summary>
|
||||
/// 创建特定版本的 Spine
|
||||
/// </summary>
|
||||
|
||||
287
SpineViewer/Spine/TextureLoader.cs
Normal file
287
SpineViewer/Spine/TextureLoader.cs
Normal file
@@ -0,0 +1,287 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SpineViewer.Spine
|
||||
{
|
||||
/// <summary>
|
||||
/// 实现不同版本的 TextureLoader
|
||||
/// </summary>
|
||||
public class TextureLoader :
|
||||
SpineRuntime21.TextureLoader,
|
||||
SpineRuntime36.TextureLoader,
|
||||
SpineRuntime37.TextureLoader,
|
||||
SpineRuntime38.TextureLoader,
|
||||
SpineRuntime40.TextureLoader,
|
||||
SpineRuntime41.TextureLoader,
|
||||
SpineRuntime42.TextureLoader
|
||||
{
|
||||
/// <summary>
|
||||
/// 强制启用 Smooth
|
||||
/// </summary>
|
||||
public bool ForceSmooth { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 强制启用 Repeated
|
||||
/// </summary>
|
||||
public bool ForceRepeated { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 强制启用 Mipmap
|
||||
/// </summary>
|
||||
public bool ForceMipmap { get; set; } = false;
|
||||
|
||||
public void Load(SpineRuntime21.AtlasPage page, string path)
|
||||
{
|
||||
var texture = new SFML.Graphics.Texture(path);
|
||||
if (page.magFilter == SpineRuntime21.TextureFilter.Linear)
|
||||
{
|
||||
texture.Smooth = true;
|
||||
}
|
||||
if (page.uWrap == SpineRuntime21.TextureWrap.Repeat && page.vWrap == SpineRuntime21.TextureWrap.Repeat)
|
||||
{
|
||||
texture.Repeated = true;
|
||||
}
|
||||
switch (page.minFilter)
|
||||
{
|
||||
case SpineRuntime21.TextureFilter.Linear:
|
||||
texture.Smooth = true;
|
||||
break;
|
||||
case SpineRuntime21.TextureFilter.MipMap:
|
||||
case SpineRuntime21.TextureFilter.MipMapNearestNearest:
|
||||
texture.GenerateMipmap();
|
||||
break;
|
||||
case SpineRuntime21.TextureFilter.MipMapLinearNearest:
|
||||
case SpineRuntime21.TextureFilter.MipMapNearestLinear:
|
||||
case SpineRuntime21.TextureFilter.MipMapLinearLinear:
|
||||
texture.Smooth = true;
|
||||
texture.GenerateMipmap();
|
||||
break;
|
||||
}
|
||||
|
||||
if (ForceSmooth) texture.Smooth = true;
|
||||
if (ForceRepeated) texture.Repeated = true;
|
||||
if (ForceMipmap) texture.GenerateMipmap();
|
||||
|
||||
page.rendererObject = texture;
|
||||
}
|
||||
|
||||
public void Load(SpineRuntime36.AtlasPage page, string path)
|
||||
{
|
||||
var texture = new SFML.Graphics.Texture(path);
|
||||
if (page.magFilter == SpineRuntime36.TextureFilter.Linear)
|
||||
{
|
||||
texture.Smooth = true;
|
||||
}
|
||||
if (page.uWrap == SpineRuntime36.TextureWrap.Repeat && page.vWrap == SpineRuntime36.TextureWrap.Repeat)
|
||||
{
|
||||
texture.Repeated = true;
|
||||
}
|
||||
switch (page.minFilter)
|
||||
{
|
||||
case SpineRuntime36.TextureFilter.Linear:
|
||||
texture.Smooth = true;
|
||||
break;
|
||||
case SpineRuntime36.TextureFilter.MipMap:
|
||||
case SpineRuntime36.TextureFilter.MipMapNearestNearest:
|
||||
texture.GenerateMipmap();
|
||||
break;
|
||||
case SpineRuntime36.TextureFilter.MipMapLinearNearest:
|
||||
case SpineRuntime36.TextureFilter.MipMapNearestLinear:
|
||||
case SpineRuntime36.TextureFilter.MipMapLinearLinear:
|
||||
texture.Smooth = true;
|
||||
texture.GenerateMipmap();
|
||||
break;
|
||||
}
|
||||
|
||||
if (ForceSmooth) texture.Smooth = true;
|
||||
if (ForceRepeated) texture.Repeated = true;
|
||||
if (ForceMipmap) texture.GenerateMipmap();
|
||||
|
||||
page.rendererObject = texture;
|
||||
}
|
||||
|
||||
public void Load(SpineRuntime37.AtlasPage page, string path)
|
||||
{
|
||||
var texture = new SFML.Graphics.Texture(path);
|
||||
if (page.magFilter == SpineRuntime37.TextureFilter.Linear)
|
||||
{
|
||||
texture.Smooth = true;
|
||||
}
|
||||
if (page.uWrap == SpineRuntime37.TextureWrap.Repeat && page.vWrap == SpineRuntime37.TextureWrap.Repeat)
|
||||
{
|
||||
texture.Repeated = true;
|
||||
}
|
||||
switch (page.minFilter)
|
||||
{
|
||||
case SpineRuntime37.TextureFilter.Linear:
|
||||
texture.Smooth = true;
|
||||
break;
|
||||
case SpineRuntime37.TextureFilter.MipMap:
|
||||
case SpineRuntime37.TextureFilter.MipMapNearestNearest:
|
||||
texture.GenerateMipmap();
|
||||
break;
|
||||
case SpineRuntime37.TextureFilter.MipMapLinearNearest:
|
||||
case SpineRuntime37.TextureFilter.MipMapNearestLinear:
|
||||
case SpineRuntime37.TextureFilter.MipMapLinearLinear:
|
||||
texture.Smooth = true;
|
||||
texture.GenerateMipmap();
|
||||
break;
|
||||
}
|
||||
|
||||
if (ForceSmooth) texture.Smooth = true;
|
||||
if (ForceRepeated) texture.Repeated = true;
|
||||
if (ForceMipmap) texture.GenerateMipmap();
|
||||
|
||||
page.rendererObject = texture;
|
||||
}
|
||||
|
||||
public void Load(SpineRuntime38.AtlasPage page, string path)
|
||||
{
|
||||
var texture = new SFML.Graphics.Texture(path);
|
||||
if (page.magFilter == SpineRuntime38.TextureFilter.Linear)
|
||||
{
|
||||
texture.Smooth = true;
|
||||
}
|
||||
if (page.uWrap == SpineRuntime38.TextureWrap.Repeat && page.vWrap == SpineRuntime38.TextureWrap.Repeat)
|
||||
{
|
||||
texture.Repeated = true;
|
||||
}
|
||||
switch (page.minFilter)
|
||||
{
|
||||
case SpineRuntime38.TextureFilter.Linear:
|
||||
texture.Smooth = true;
|
||||
break;
|
||||
case SpineRuntime38.TextureFilter.MipMap:
|
||||
case SpineRuntime38.TextureFilter.MipMapNearestNearest:
|
||||
texture.GenerateMipmap();
|
||||
break;
|
||||
case SpineRuntime38.TextureFilter.MipMapLinearNearest:
|
||||
case SpineRuntime38.TextureFilter.MipMapNearestLinear:
|
||||
case SpineRuntime38.TextureFilter.MipMapLinearLinear:
|
||||
texture.Smooth = true;
|
||||
texture.GenerateMipmap();
|
||||
break;
|
||||
}
|
||||
|
||||
if (ForceSmooth) texture.Smooth = true;
|
||||
if (ForceRepeated) texture.Repeated = true;
|
||||
if (ForceMipmap) texture.GenerateMipmap();
|
||||
|
||||
page.rendererObject = texture;
|
||||
}
|
||||
|
||||
public void Load(SpineRuntime40.AtlasPage page, string path)
|
||||
{
|
||||
var texture = new SFML.Graphics.Texture(path);
|
||||
if (page.magFilter == SpineRuntime40.TextureFilter.Linear)
|
||||
{
|
||||
texture.Smooth = true;
|
||||
}
|
||||
if (page.uWrap == SpineRuntime40.TextureWrap.Repeat && page.vWrap == SpineRuntime40.TextureWrap.Repeat)
|
||||
{
|
||||
texture.Repeated = true;
|
||||
}
|
||||
switch (page.minFilter)
|
||||
{
|
||||
case SpineRuntime40.TextureFilter.Linear:
|
||||
texture.Smooth = true;
|
||||
break;
|
||||
case SpineRuntime40.TextureFilter.MipMap:
|
||||
case SpineRuntime40.TextureFilter.MipMapNearestNearest:
|
||||
texture.GenerateMipmap();
|
||||
break;
|
||||
case SpineRuntime40.TextureFilter.MipMapLinearNearest:
|
||||
case SpineRuntime40.TextureFilter.MipMapNearestLinear:
|
||||
case SpineRuntime40.TextureFilter.MipMapLinearLinear:
|
||||
texture.Smooth = true;
|
||||
texture.GenerateMipmap();
|
||||
break;
|
||||
}
|
||||
|
||||
if (ForceSmooth) texture.Smooth = true;
|
||||
if (ForceRepeated) texture.Repeated = true;
|
||||
if (ForceMipmap) texture.GenerateMipmap();
|
||||
|
||||
page.rendererObject = texture;
|
||||
}
|
||||
|
||||
public void Load(SpineRuntime41.AtlasPage page, string path)
|
||||
{
|
||||
var texture = new SFML.Graphics.Texture(path);
|
||||
if (page.magFilter == SpineRuntime41.TextureFilter.Linear)
|
||||
{
|
||||
texture.Smooth = true;
|
||||
}
|
||||
if (page.uWrap == SpineRuntime41.TextureWrap.Repeat && page.vWrap == SpineRuntime41.TextureWrap.Repeat)
|
||||
{
|
||||
texture.Repeated = true;
|
||||
}
|
||||
switch (page.minFilter)
|
||||
{
|
||||
case SpineRuntime41.TextureFilter.Linear:
|
||||
texture.Smooth = true;
|
||||
break;
|
||||
case SpineRuntime41.TextureFilter.MipMap:
|
||||
case SpineRuntime41.TextureFilter.MipMapNearestNearest:
|
||||
texture.GenerateMipmap();
|
||||
break;
|
||||
case SpineRuntime41.TextureFilter.MipMapLinearNearest:
|
||||
case SpineRuntime41.TextureFilter.MipMapNearestLinear:
|
||||
case SpineRuntime41.TextureFilter.MipMapLinearLinear:
|
||||
texture.Smooth = true;
|
||||
texture.GenerateMipmap();
|
||||
break;
|
||||
}
|
||||
|
||||
if (ForceSmooth) texture.Smooth = true;
|
||||
if (ForceRepeated) texture.Repeated = true;
|
||||
if (ForceMipmap) texture.GenerateMipmap();
|
||||
|
||||
page.rendererObject = texture;
|
||||
}
|
||||
|
||||
public void Load(SpineRuntime42.AtlasPage page, string path)
|
||||
{
|
||||
var texture = new SFML.Graphics.Texture(path);
|
||||
if (page.magFilter == SpineRuntime42.TextureFilter.Linear)
|
||||
{
|
||||
texture.Smooth = true;
|
||||
}
|
||||
if (page.uWrap == SpineRuntime42.TextureWrap.Repeat && page.vWrap == SpineRuntime42.TextureWrap.Repeat)
|
||||
{
|
||||
texture.Repeated = true;
|
||||
}
|
||||
switch (page.minFilter)
|
||||
{
|
||||
case SpineRuntime42.TextureFilter.Linear:
|
||||
texture.Smooth = true;
|
||||
break;
|
||||
case SpineRuntime42.TextureFilter.MipMap:
|
||||
case SpineRuntime42.TextureFilter.MipMapNearestNearest:
|
||||
texture.GenerateMipmap();
|
||||
break;
|
||||
case SpineRuntime42.TextureFilter.MipMapLinearNearest:
|
||||
case SpineRuntime42.TextureFilter.MipMapNearestLinear:
|
||||
case SpineRuntime42.TextureFilter.MipMapLinearLinear:
|
||||
texture.Smooth = true;
|
||||
texture.GenerateMipmap();
|
||||
break;
|
||||
}
|
||||
|
||||
if (ForceSmooth) texture.Smooth = true;
|
||||
if (ForceRepeated) texture.Repeated = true;
|
||||
if (ForceMipmap) texture.GenerateMipmap();
|
||||
|
||||
page.rendererObject = texture;
|
||||
|
||||
// 似乎是不需要设置的, 因为存在某些 png 和 atlas 大小不同的情况, 一般是有一些缩放, 如果设置了反而渲染异常
|
||||
// page.width = (int)texture.Size.X;
|
||||
// page.height = (int)texture.Size.Y;
|
||||
}
|
||||
|
||||
public void Unload(object texture) => ((SFML.Graphics.Texture)texture).Dispose();
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>0.12.9</Version>
|
||||
<Version>0.12.17</Version>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<ApplicationIcon>appicon.ico</ApplicationIcon>
|
||||
|
||||
Reference in New Issue
Block a user