Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e3a201af89 | ||
|
|
292ede8461 | ||
|
|
112a9a1bf2 | ||
|
|
63ed8d7ca4 | ||
|
|
d1e33c25bc | ||
|
|
ce7c6f3802 | ||
|
|
0a30af0ad2 | ||
|
|
0b478cab18 | ||
|
|
b14849a0b1 | ||
|
|
b7f5f24e6f | ||
|
|
150331d2e4 | ||
|
|
dcec8797b0 | ||
|
|
4d1aec9ed8 | ||
|
|
0cb325820b | ||
|
|
2a862b28be | ||
|
|
c2935f49e9 | ||
|
|
22043f8f38 | ||
|
|
3020a818f0 | ||
|
|
30177e8d7f | ||
|
|
3ad49838be | ||
|
|
3e480abd44 | ||
|
|
49f6b28aef | ||
|
|
b81d13b582 | ||
|
|
04eb3cb640 | ||
|
|
0ac75a088a | ||
|
|
cd652a72a1 | ||
|
|
828ff30dbf | ||
|
|
f452fe8a71 | ||
|
|
15e29a3b8a | ||
|
|
5c6e98f5e1 | ||
|
|
ef06073119 | ||
|
|
bca8b0ad85 |
54
.github/workflows/dotnet-desktop.yml
vendored
54
.github/workflows/dotnet-desktop.yml
vendored
@@ -1,45 +1,79 @@
|
|||||||
name: Build & Release
|
name: Build & Release
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
pull_request:
|
||||||
tags:
|
branches:
|
||||||
- 'v*.*.*'
|
- release/wf
|
||||||
|
types:
|
||||||
|
- closed
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-release:
|
build-release:
|
||||||
|
if: ${{ github.event.pull_request.merged == true }}
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
env:
|
env:
|
||||||
PROJECT_NAME: SpineViewer
|
PROJECT_NAME: SpineViewer
|
||||||
VERSION: ${{ github.ref_name }}
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-tags: true
|
||||||
|
|
||||||
- name: Setup .NET SDK
|
- name: Setup .NET SDK
|
||||||
uses: actions/setup-dotnet@v3
|
uses: actions/setup-dotnet@v3
|
||||||
with:
|
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
|
- name: Publish FrameworkDependent version
|
||||||
|
shell: pwsh
|
||||||
run: |
|
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
|
- name: Publish SelfContained version
|
||||||
|
shell: pwsh
|
||||||
run: |
|
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
|
- name: Create release directory
|
||||||
run: mkdir release
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
New-Item -ItemType Directory -Path release -Force | Out-Null
|
||||||
|
|
||||||
- name: Compress FrameworkDependent version
|
- name: Compress FrameworkDependent version
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
run: |
|
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
|
- name: Compress SelfContained version
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
run: |
|
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
|
- name: Create GitHub Release
|
||||||
id: create_release
|
id: create_release
|
||||||
|
|||||||
15
CHANGELOG.md
15
CHANGELOG.md
@@ -1,5 +1,20 @@
|
|||||||
# CHANGELOG
|
# CHANGELOG
|
||||||
|
|
||||||
|
## v0.12.15
|
||||||
|
|
||||||
|
- 修复附件类型枚举量字符串大小写问题
|
||||||
|
|
||||||
|
## v0.12.14
|
||||||
|
|
||||||
|
- 修复 v38 文件读取的小 bug
|
||||||
|
|
||||||
|
## v0.12.13
|
||||||
|
|
||||||
|
- 导出文件名增加额外的随机字符串
|
||||||
|
|
||||||
|
## v0.12.12
|
||||||
|
|
||||||
|
- 修复 2.1 版本遗漏的 SkinnedMeshAttachment 附件渲染
|
||||||
|
|
||||||
## v0.12.11
|
## v0.12.11
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,17 @@ namespace SpineViewer.Spine.Implementations.SkeletonConverter
|
|||||||
[RotateMode.ChainScale] = "chainScale",
|
[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 BinaryReader reader = null;
|
||||||
private JsonObject root = null;
|
private JsonObject root = null;
|
||||||
private bool nonessential = false;
|
private bool nonessential = false;
|
||||||
@@ -298,7 +309,7 @@ namespace SpineViewer.Spine.Implementations.SkeletonConverter
|
|||||||
var name = reader.ReadStringRef() ?? keyName;
|
var name = reader.ReadStringRef() ?? keyName;
|
||||||
var type = (AttachmentType)reader.ReadByte();
|
var type = (AttachmentType)reader.ReadByte();
|
||||||
attachment["name"] = name;
|
attachment["name"] = name;
|
||||||
attachment["type"] = type.ToString();
|
attachment["type"] = AttachmentTypeJsonValue[type];
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case AttachmentType.Region:
|
case AttachmentType.Region:
|
||||||
@@ -586,7 +597,7 @@ namespace SpineViewer.Spine.Implementations.SkeletonConverter
|
|||||||
["compress"] = reader.ReadBoolean(),
|
["compress"] = reader.ReadBoolean(),
|
||||||
["stretch"] = reader.ReadBoolean(),
|
["stretch"] = reader.ReadBoolean(),
|
||||||
};
|
};
|
||||||
if (frameCount > 1) ReadCurve(o);
|
if (frameIdx < frameCount - 1) ReadCurve(o);
|
||||||
frames.Add(o);
|
frames.Add(o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -613,7 +624,7 @@ namespace SpineViewer.Spine.Implementations.SkeletonConverter
|
|||||||
["scaleMix"] = reader.ReadFloat(),
|
["scaleMix"] = reader.ReadFloat(),
|
||||||
["shearMix"] = reader.ReadFloat(),
|
["shearMix"] = reader.ReadFloat(),
|
||||||
};
|
};
|
||||||
if (frameCount > 1) ReadCurve(o);
|
if (frameIdx < frameCount - 1) ReadCurve(o);
|
||||||
frames.Add(o);
|
frames.Add(o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,9 +52,9 @@ namespace SpineViewer.Spine.Implementations.SkeletonConverter
|
|||||||
private static readonly Dictionary<AttachmentType, string> AttachmentTypeJsonValue = new()
|
private static readonly Dictionary<AttachmentType, string> AttachmentTypeJsonValue = new()
|
||||||
{
|
{
|
||||||
[AttachmentType.Region] = "region",
|
[AttachmentType.Region] = "region",
|
||||||
[AttachmentType.Boundingbox] = "boundingBox",
|
[AttachmentType.Boundingbox] = "boundingbox",
|
||||||
[AttachmentType.Mesh] = "mesh",
|
[AttachmentType.Mesh] = "mesh",
|
||||||
[AttachmentType.Linkedmesh] = "linkedMesh",
|
[AttachmentType.Linkedmesh] = "linkedmesh",
|
||||||
[AttachmentType.Path] = "path",
|
[AttachmentType.Path] = "path",
|
||||||
[AttachmentType.Point] = "point",
|
[AttachmentType.Point] = "point",
|
||||||
[AttachmentType.Clipping] = "clipping",
|
[AttachmentType.Clipping] = "clipping",
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ namespace SpineViewer.Spine.Implementations.SkeletonConverter
|
|||||||
[AttachmentType.Region] = "region",
|
[AttachmentType.Region] = "region",
|
||||||
[AttachmentType.Boundingbox] = "bounding",
|
[AttachmentType.Boundingbox] = "bounding",
|
||||||
[AttachmentType.Mesh] = "mesh",
|
[AttachmentType.Mesh] = "mesh",
|
||||||
[AttachmentType.Linkedmesh] = "linkedMesh",
|
[AttachmentType.Linkedmesh] = "linkedmesh",
|
||||||
[AttachmentType.Path] = "path",
|
[AttachmentType.Path] = "path",
|
||||||
[AttachmentType.Point] = "point",
|
[AttachmentType.Point] = "point",
|
||||||
[AttachmentType.Clipping] = "clipping",
|
[AttachmentType.Clipping] = "clipping",
|
||||||
@@ -1069,14 +1069,14 @@ namespace SpineViewer.Spine.Implementations.SkeletonConverter
|
|||||||
{
|
{
|
||||||
["time"] = reader.ReadFloat(),
|
["time"] = reader.ReadFloat(),
|
||||||
};
|
};
|
||||||
|
ReadCurve(frame, 1);
|
||||||
|
frame = o;
|
||||||
end = reader.ReadVarInt();
|
end = reader.ReadVarInt();
|
||||||
if (end > 0)
|
if (end > 0)
|
||||||
{
|
{
|
||||||
frame["offset"] = reader.ReadVarInt();
|
frame["offset"] = reader.ReadVarInt();
|
||||||
frame["vertices"] = ReadFloatArray(end);
|
frame["vertices"] = ReadFloatArray(end);
|
||||||
}
|
}
|
||||||
ReadCurve(frame, 1);
|
|
||||||
frame = o;
|
|
||||||
frames.Add(frame);
|
frames.Add(frame);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -260,7 +260,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
|||||||
SFML.Graphics.Texture texture;
|
SFML.Graphics.Texture texture;
|
||||||
|
|
||||||
float[] worldVertices = worldVerticesBuffer; // 顶点世界坐标, 连续的 [x0, y0, x1, y1, ...] 坐标值
|
float[] worldVertices = worldVerticesBuffer; // 顶点世界坐标, 连续的 [x0, y0, x1, y1, ...] 坐标值
|
||||||
int worldVerticesCount; // 等于顶点数组的长度除以 2
|
//int worldVerticesCount; // 等于顶点数组的长度除以 2
|
||||||
int[] worldTriangleIndices; // 三角形索引, 从顶点坐标数组取的时候要乘以 2, 最大值是 worldVerticesCount - 1
|
int[] worldTriangleIndices; // 三角形索引, 从顶点坐标数组取的时候要乘以 2, 最大值是 worldVerticesCount - 1
|
||||||
int worldTriangleIndicesLength; // 三角形索引数组长度
|
int worldTriangleIndicesLength; // 三角形索引数组长度
|
||||||
float[] uvs; // 纹理坐标
|
float[] uvs; // 纹理坐标
|
||||||
@@ -274,7 +274,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
|||||||
texture = (SFML.Graphics.Texture)((AtlasRegion)regionAttachment.RendererObject).page.rendererObject;
|
texture = (SFML.Graphics.Texture)((AtlasRegion)regionAttachment.RendererObject).page.rendererObject;
|
||||||
|
|
||||||
regionAttachment.ComputeWorldVertices(slot.Bone, worldVertices);
|
regionAttachment.ComputeWorldVertices(slot.Bone, worldVertices);
|
||||||
worldVerticesCount = 4;
|
//worldVerticesCount = 4;
|
||||||
worldTriangleIndices = [0, 1, 2, 2, 3, 0];
|
worldTriangleIndices = [0, 1, 2, 2, 3, 0];
|
||||||
worldTriangleIndicesLength = 6;
|
worldTriangleIndicesLength = 6;
|
||||||
uvs = regionAttachment.UVs;
|
uvs = regionAttachment.UVs;
|
||||||
@@ -290,7 +290,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
|||||||
if (meshAttachment.Vertices.Length > worldVertices.Length)
|
if (meshAttachment.Vertices.Length > worldVertices.Length)
|
||||||
worldVertices = worldVerticesBuffer = new float[meshAttachment.Vertices.Length * 2];
|
worldVertices = worldVerticesBuffer = new float[meshAttachment.Vertices.Length * 2];
|
||||||
meshAttachment.ComputeWorldVertices(slot, worldVertices);
|
meshAttachment.ComputeWorldVertices(slot, worldVertices);
|
||||||
worldVerticesCount = meshAttachment.Vertices.Length / 2;
|
//worldVerticesCount = meshAttachment.Vertices.Length / 2;
|
||||||
worldTriangleIndices = meshAttachment.Triangles;
|
worldTriangleIndices = meshAttachment.Triangles;
|
||||||
worldTriangleIndicesLength = meshAttachment.Triangles.Length;
|
worldTriangleIndicesLength = meshAttachment.Triangles.Length;
|
||||||
uvs = meshAttachment.UVs;
|
uvs = meshAttachment.UVs;
|
||||||
@@ -299,6 +299,22 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
|||||||
tintB *= meshAttachment.B;
|
tintB *= meshAttachment.B;
|
||||||
tintA *= meshAttachment.A;
|
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 不支持剪裁
|
// 2.1.x 不支持剪裁
|
||||||
//else if (attachment is ClippingAttachment clippingAttachment)
|
//else if (attachment is ClippingAttachment clippingAttachment)
|
||||||
//{
|
//{
|
||||||
@@ -432,6 +448,37 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
|||||||
vt.Position.Y = worldVerticesBuffer[idx2 + 1];
|
vt.Position.Y = worldVerticesBuffer[idx2 + 1];
|
||||||
lineVertices.Append(vt); lineVertices.Append(vt);
|
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.X = worldVerticesBuffer[idx0];
|
||||||
vt.Position.Y = worldVerticesBuffer[idx0 + 1];
|
vt.Position.Y = worldVerticesBuffer[idx0 + 1];
|
||||||
lineVertices.Append(vt);
|
lineVertices.Append(vt);
|
||||||
@@ -454,6 +501,34 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
|||||||
|
|
||||||
var hullLength = (meshAttachment.HullLength >> 1) << 1;
|
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)
|
if (debugMeshHulls && hullLength > 2)
|
||||||
{
|
{
|
||||||
vt.Position.X = worldVerticesBuffer[0];
|
vt.Position.X = worldVerticesBuffer[0];
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ namespace SpineViewer.Spine.SpineExporter
|
|||||||
var noteSuffix = FileNameNoteSuffix;
|
var noteSuffix = FileNameNoteSuffix;
|
||||||
if (!string.IsNullOrWhiteSpace(noteSuffix)) noteSuffix = $"_{noteSuffix}";
|
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);
|
var savePath = Path.Combine(OutputDir, filename);
|
||||||
@@ -86,7 +86,7 @@ namespace SpineViewer.Spine.SpineExporter
|
|||||||
{
|
{
|
||||||
if (worker?.CancellationPending == true) break; // 取消的日志在 GetFrames 里输出
|
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);
|
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)
|
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);
|
var savePath = Path.Combine(OutputDir, filename);
|
||||||
|
|
||||||
worker?.ReportProgress(0, $"{Properties.Resources.process} 0/1");
|
worker?.ReportProgress(0, $"{Properties.Resources.process} 0/1");
|
||||||
@@ -78,7 +78,7 @@ namespace SpineViewer.Spine.SpineExporter
|
|||||||
var spine = spinesToRender[i];
|
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);
|
var savePath = Path.Combine(OutputDir ?? spine.AssetsDir, filename);
|
||||||
|
|
||||||
try
|
try
|
||||||
|
|||||||
@@ -22,14 +22,16 @@ namespace SpineViewer.Spine.SpineExporter
|
|||||||
|
|
||||||
protected override void ExportSingle(SpineObject[] spinesToRender, BackgroundWorker? worker = null)
|
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);
|
Directory.CreateDirectory(saveDir);
|
||||||
|
|
||||||
int frameIdx = 0;
|
int frameIdx = 0;
|
||||||
foreach (var frame in GetFrames(spinesToRender, worker))
|
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);
|
var savePath = Path.Combine(saveDir, filename);
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -56,14 +58,14 @@ namespace SpineViewer.Spine.SpineExporter
|
|||||||
if (worker?.CancellationPending == true) break; // 取消的日志在 GetFrames 里输出
|
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);
|
var saveDir = Path.Combine(OutputDir ?? spine.AssetsDir, subDir);
|
||||||
Directory.CreateDirectory(saveDir);
|
Directory.CreateDirectory(saveDir);
|
||||||
|
|
||||||
int frameIdx = 0;
|
int frameIdx = 0;
|
||||||
foreach (var frame in GetFrames(spine, worker))
|
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);
|
var savePath = Path.Combine(saveDir, filename);
|
||||||
|
|
||||||
try
|
try
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<TargetFramework>net8.0-windows</TargetFramework>
|
<TargetFramework>net8.0-windows</TargetFramework>
|
||||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||||
<Version>0.12.11</Version>
|
<Version>0.12.15</Version>
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<UseWindowsForms>true</UseWindowsForms>
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
<ApplicationIcon>appicon.ico</ApplicationIcon>
|
<ApplicationIcon>appicon.ico</ApplicationIcon>
|
||||||
|
|||||||
Reference in New Issue
Block a user